[MM-61756] Attribute Based Access Control - Phase 1 (#30785)

Attribute Based Access Control - Base
* MM-63662

* MM-63919

* MM-63954

* MM-63955 

* MM-63425

* MM-63426

* MM-63458

* MM-63459

* MM-63603

* MM-63845

* MM-64146

* MM-64199

* MM-64201

* MM-64233

* MM-64247

* MM-64268

---------

Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
Co-authored-by: Pablo Andrés Vélez Vidal <pablovv2012@gmail.com>
Co-authored-by: abhijit-singh <abhijitsingh0702@gmail.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Этот коммит содержится в:
Ibrahim Serdar Acikgoz
2025-05-15 11:33:08 +02:00
коммит произвёл GitHub
родитель 4b445cbf16
Коммит a344b3225b
156 изменённых файлов: 14382 добавлений и 621 удалений

Просмотреть файл

@@ -3,6 +3,7 @@
/* eslint-disable max-lines */
import type {AccessControlPolicy, CELExpressionError, AccessControlTestResult, AccessControlPoliciesResult, AccessControlPolicyChannelsResult, AccessControlVisualAST} from '@mattermost/types/access_control';
import type {ClusterInfo, AnalyticsRow, SchemaMigration, LogFilterQuery} from '@mattermost/types/admin';
import type {AppBinding, AppCallRequest, AppCallResponse} from '@mattermost/types/apps';
import type {Audit} from '@mattermost/types/audits';
@@ -108,7 +109,7 @@ import type {
import type {Post, PostList, PostSearchResults, PostsUsageResponse, TeamsUsageResponse, PaginatedPostList, FilesUsageResponse, PostAcknowledgement, PostAnalytics, PostInfo} from '@mattermost/types/posts';
import type {PreferenceType} from '@mattermost/types/preferences';
import type {ProductNotices} from '@mattermost/types/product_notices';
import type {UserPropertyField, UserPropertyFieldPatch} from '@mattermost/types/properties';
import type {PropertyField, UserPropertyField, UserPropertyFieldPatch} from '@mattermost/types/properties';
import type {Reaction} from '@mattermost/types/reactions';
import type {RemoteCluster, RemoteClusterAcceptInvite, RemoteClusterPatch, RemoteClusterWithPassword} from '@mattermost/types/remote_clusters';
import type {UserReport, UserReportFilter, UserReportOptions} from '@mattermost/types/reports';
@@ -1547,7 +1548,9 @@ export default class Client4 {
excludeDefaultChannels: boolean | undefined,
includeTotalCount: false | undefined,
includeDeleted: boolean | undefined,
excludePolicyConstrained: boolean | undefined
excludePolicyConstrained: boolean | undefined,
accessControlPolicyEnforced: boolean | undefined,
excludeAccessControlPolicyEnforced: boolean | undefined
): Promise<ChannelWithTeamData[]>;
getAllChannels(
page: number | undefined,
@@ -1556,7 +1559,9 @@ export default class Client4 {
excludeDefaultChannels: boolean | undefined,
includeTotalCount: true,
includeDeleted: boolean | undefined,
excludePolicyConstrained: boolean | undefined
excludePolicyConstrained: boolean | undefined,
accessControlPolicyEnforced: boolean | undefined,
excludeAccessControlPolicyEnforced: boolean | undefined
): Promise<ChannelsWithTotalCount>;
getAllChannels(
page = 0,
@@ -1566,16 +1571,36 @@ export default class Client4 {
includeTotalCount = false,
includeDeleted = false,
excludePolicyConstrained = false,
accessControlPolicyEnforced = false,
excludeAccessControlPolicyEnforced = false,
) {
const queryData = {
const queryData: Record<string, any> = {
page,
per_page: perPage,
not_associated_to_group: notAssociatedToGroup,
exclude_default_channels: excludeDefaultChannels,
include_total_count: includeTotalCount,
include_deleted: includeDeleted,
exclude_policy_constrained: excludePolicyConstrained,
};
if (notAssociatedToGroup) {
queryData.not_associated_to_group = notAssociatedToGroup;
}
if (excludeDefaultChannels) {
queryData.exclude_default_channels = excludeDefaultChannels;
}
if (excludePolicyConstrained) {
queryData.exclude_policy_constrained = excludePolicyConstrained;
}
if (accessControlPolicyEnforced) {
queryData.access_control_policy_enforced = accessControlPolicyEnforced;
}
if (excludeAccessControlPolicyEnforced) {
queryData.exclude_access_control_policy_enforced = excludeAccessControlPolicyEnforced;
}
return this.doFetch<ChannelWithTeamData[] | ChannelsWithTotalCount>(
`${this.getChannelsRoute()}${buildQueryString(queryData)}`,
{method: 'get'},
@@ -4382,6 +4407,111 @@ export default class Client4 {
{method: 'post', headers: {'Connection-Id': connectionId}},
);
};
getAccessControlPolicy = (id: string) => {
return this.doFetch<AccessControlPolicy>(
`${this.getBaseRoute()}/access_control_policies/${id}`,
{method: 'get'},
);
};
updateOrCreateAccessControlPolicy = (policy: AccessControlPolicy) => {
return this.doFetch<AccessControlPolicy>(
`${this.getBaseRoute()}/access_control_policies`,
{method: 'put', body: JSON.stringify(policy)},
);
};
deleteAccessControlPolicy = (id: string) => {
return this.doFetch<AccessControlPolicy>(
`${this.getBaseRoute()}/access_control_policies/${id}`,
{method: 'delete'},
);
};
getAccessControlPolicies = (after: string, limit: number) => {
return this.doFetch<AccessControlPoliciesResult>(
`${this.getBaseRoute()}/access_control_policies/search`,
{method: 'post', body: JSON.stringify({type: 'parent', cursor: {id: after}, limit})},
);
};
getChildPolicies = (parentId: string, after: string, limit: number) => {
return this.doFetch<AccessControlPoliciesResult>(
`${this.getBaseRoute()}/access_control_policies/search`,
{method: 'post', body: JSON.stringify({parent_id: parentId, cursor: {id: after}, limit})},
);
};
getChannelsForAccessControlPolicy = (policyId: string, after: string, limit: number) => {
return this.doFetch<AccessControlPolicyChannelsResult>(
`${this.getBaseRoute()}/access_control_policies/${policyId}/resources/channels?after=${after}&limit=${limit}`,
{method: 'get'},
);
};
searchAccessControlPolicies = (term: string, type: string, after: string, limit: number) => {
return this.doFetch<AccessControlPoliciesResult>(
`${this.getBaseRoute()}/access_control_policies/search`,
{method: 'post', body: JSON.stringify({term, type, cursor: {id: after}, limit, include_children: true})},
);
};
searchChildAccessControlPolicyChannels = (policyId: string, term: string, opts: ChannelSearchOpts) => {
return this.doFetch<ChannelsWithTotalCount>(
`${this.getBaseRoute()}/access_control_policies/${policyId}/resources/channels/search?term=${term}`,
{method: 'post', body: JSON.stringify({term, ...opts})},
);
};
updateAccessControlPolicyActive = (policyId: string, active: boolean) => {
return this.doFetch<StatusOK>(
`${this.getBaseRoute()}/access_control_policies/${policyId}/activate?active=${active}`,
{method: 'get'},
);
};
assignChannelsToAccessControlPolicy = (policyId: string, channelIds: string[]) => {
return this.doFetch<StatusOK>(
`${this.getBaseRoute()}/access_control_policies/${policyId}/assign`,
{method: 'post', body: JSON.stringify({channel_ids: channelIds})},
);
};
unassignChannelsFromAccessControlPolicy = (policyId: string, channelIds: string[]) => {
return this.doFetch<StatusOK>(
`${this.getBaseRoute()}/access_control_policies/${policyId}/unassign`,
{method: 'delete', body: JSON.stringify({channel_ids: channelIds})},
);
};
getAccessControlFields = (after: string, limit: number) => {
return this.doFetch<PropertyField[]>(
`${this.getBaseRoute()}/access_control_policies/cel/autocomplete/fields?after=${after}&limit=${limit}`,
{method: 'get'},
);
};
checkAccessControlExpression = (expression: string) => {
return this.doFetch<CELExpressionError[]>(
`${this.getBaseRoute()}/access_control_policies/cel/check`,
{method: 'post', body: JSON.stringify({expression})},
);
};
testAccessControlExpression = (expression: string, term: string, after: string, limit: number) => {
return this.doFetch<AccessControlTestResult>(
`${this.getBaseRoute()}/access_control_policies/cel/test`,
{method: 'post', body: JSON.stringify({expression, term, after, limit})},
);
};
expressionToVisualFormat = (expression: string) => {
return this.doFetch<AccessControlVisualAST>(
`${this.getBaseRoute()}/access_control_policies/cel/visual_ast`,
{method: 'post', body: JSON.stringify({expression})},
);
};
}
export function parseAndMergeNestedHeaders(originalHeaders: any) {