diff --git a/webapp/packages/core-authentication/src/UsersResource.ts b/webapp/packages/core-authentication/src/UsersResource.ts index b1c7900403..e8d95f7438 100644 --- a/webapp/packages/core-authentication/src/UsersResource.ts +++ b/webapp/packages/core-authentication/src/UsersResource.ts @@ -115,8 +115,20 @@ export class UsersResource extends CachedMapResource { - await this.graphQLService.sdk.setConnections({ userId, connections }); + async addConnectionsAccess(userId: string, connectionIds: string[]): Promise { + await this.graphQLService.sdk.addConnectionsAccess({ + projectId: 'g_GlobalConfiguration', + connectionIds, + subjects: [userId], + }); + } + + async deleteConnectionsAccess(userId: string, connectionIds: string[]): Promise { + await this.graphQLService.sdk.deleteConnectionsAccess({ + projectId: 'g_GlobalConfiguration', + connectionIds, + subjects: [userId], + }); } async setMetaParameters(userId: string, parameters: Record): Promise { diff --git a/webapp/packages/core-sdk/src/queries/connections/administration/setConnectionAccess.gql b/webapp/packages/core-sdk/src/queries/connections/administration/setConnectionAccess.gql deleted file mode 100644 index 6b536bd918..0000000000 --- a/webapp/packages/core-sdk/src/queries/connections/administration/setConnectionAccess.gql +++ /dev/null @@ -1,11 +0,0 @@ -query setConnectionAccess( - $projectId: ID! - $connectionId: ID! - $subjects: [ID!]! -) { - setConnectionSubjectAccess( - projectId: $projectId - connectionId: $connectionId - subjects: $subjects - ) -} \ No newline at end of file diff --git a/webapp/packages/core-sdk/src/queries/connections/administration/setSubjectConnectionAccess.gql b/webapp/packages/core-sdk/src/queries/connections/administration/setSubjectConnectionAccess.gql deleted file mode 100644 index 9a64d6b677..0000000000 --- a/webapp/packages/core-sdk/src/queries/connections/administration/setSubjectConnectionAccess.gql +++ /dev/null @@ -1,3 +0,0 @@ -query setSubjectConnectionAccess($subjectId: ID!, $connections: [ID!]!) { - setSubjectConnectionAccess(subjectId: $subjectId, connections: $connections) -} \ No newline at end of file diff --git a/webapp/packages/core-sdk/src/queries/resource-manager/addProjectsPermissions.graphql b/webapp/packages/core-sdk/src/queries/resource-manager/addProjectsPermissions.graphql new file mode 100644 index 0000000000..153c1d1cc9 --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/resource-manager/addProjectsPermissions.graphql @@ -0,0 +1,3 @@ +mutation addProjectsPermissions($projectIds: [ID!]!, $subjectIds: [ID!]!, $permissions: [String!]!) { + rmAddProjectsPermissions(projectIds: $projectIds, subjectIds: $subjectIds, permissions: $permissions) +} diff --git a/webapp/packages/core-sdk/src/queries/resource-manager/deleteProjectsPermissions.graphql b/webapp/packages/core-sdk/src/queries/resource-manager/deleteProjectsPermissions.graphql new file mode 100644 index 0000000000..a16a9eb9ef --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/resource-manager/deleteProjectsPermissions.graphql @@ -0,0 +1,3 @@ +mutation deleteProjectsPermissions($projectIds: [ID!]!, $subjectIds: [ID!]!, $permissions: [String!]!) { + rmDeleteProjectsPermissions(projectIds: $projectIds, subjectIds: $subjectIds, permissions: $permissions) +} diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedConnections/GrantedConnectionsTabService.ts b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedConnections/GrantedConnectionsTabService.ts index 2f8894c3d8..886c50dde9 100644 --- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedConnections/GrantedConnectionsTabService.ts +++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedConnections/GrantedConnectionsTabService.ts @@ -95,15 +95,38 @@ export class GrantedConnectionsTabService extends Bootstrap { return; } + const { connectionsToRevoke, connectionsToGrant } = this.getConnectionsDifferences(state); + try { - await this.graphQLService.sdk.setSubjectConnectionAccess({ - subjectId: config.teamId, - connections: state.grantedSubjects, - }); + if (connectionsToRevoke.length > 0) { + await this.graphQLService.sdk.deleteConnectionsAccess({ + projectId: 'g_GlobalConfiguration', + subjects: [config.teamId], + connectionIds: connectionsToRevoke, + }); + } + + if (connectionsToGrant.length > 0) { + await this.graphQLService.sdk.addConnectionsAccess({ + projectId: 'g_GlobalConfiguration', + subjects: [config.teamId], + connectionIds: connectionsToGrant, + }); + } state.loaded = false; } catch (exception: any) { this.notificationService.logException(exception); } } + + private getConnectionsDifferences(state: IGrantedConnectionsTabState): { connectionsToRevoke: string[]; connectionsToGrant: string[] } { + const current = state.initialGrantedSubjects; + const next = state.grantedSubjects; + + const connectionsToRevoke = current.filter(subjectId => !next.includes(subjectId)); + const connectionsToGrant = next.filter(subjectId => !current.includes(subjectId)); + + return { connectionsToRevoke, connectionsToGrant }; + } } diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/ConnectionAccess/UserFormConnectionAccessPart.ts b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/ConnectionAccess/UserFormConnectionAccessPart.ts index c1e59f6e08..ab0fea8243 100644 --- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/ConnectionAccess/UserFormConnectionAccessPart.ts +++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/ConnectionAccess/UserFormConnectionAccessPart.ts @@ -55,14 +55,33 @@ export class UserFormConnectionAccessPart extends FormPart 0) { + await this.usersResource.deleteConnectionsAccess(userFormInfoPart.state.userId, connectionsToRevoke); + } + + if (connectionsToGrant.length > 0) { + await this.usersResource.addConnectionsAccess(userFormInfoPart.state.userId, connectionsToGrant); + } } private getGrantedConnections(state: AdminConnectionGrantInfo[]): string[] { return state.filter(connection => connection.subjectType !== AdminSubjectType.Team).map(connection => connection.dataSourceId); } + private getConnectionsDifferences(current: string[], next: string[]): { connectionsToRevoke: string[]; connectionsToGrant: string[] } { + const connectionsToRevoke = current.filter(subjectId => !next.includes(subjectId)); + const connectionsToGrant = next.filter(subjectId => !current.includes(subjectId)); + + return { connectionsToRevoke, connectionsToGrant }; + } + protected override async loader() { const userFormInfoPart = this.formState.dataContext.get(DATA_CONTEXT_USER_FORM_INFO_PART); let grantedConnections: AdminConnectionGrantInfo[] = []; diff --git a/webapp/packages/plugin-connections-administration/src/ConnectionForm/ConnectionAccess/ConnectionAccessTabService.ts b/webapp/packages/plugin-connections-administration/src/ConnectionForm/ConnectionAccess/ConnectionAccessTabService.ts index 56810ba0a8..81de02c7c1 100644 --- a/webapp/packages/plugin-connections-administration/src/ConnectionForm/ConnectionAccess/ConnectionAccessTabService.ts +++ b/webapp/packages/plugin-connections-administration/src/ConnectionForm/ConnectionAccess/ConnectionAccessTabService.ts @@ -104,20 +104,24 @@ export class ConnectionAccessTabService extends Bootstrap { const key = createConnectionParam(data.state.projectId, config.connectionId); - const changed = await this.isChanged(key, state.grantedSubjects); + const currentGrantedSubjects = await this.connectionInfoResource.loadAccessSubjects(key); + const currentGrantedSubjectIds = currentGrantedSubjects.map(subject => subject.subjectId); - if (changed) { - if (state.initialGrantedSubjects.length > state.grantedSubjects.length) { + const { subjectsToRevoke, subjectsToGrant } = await this.getSubjectDifferences(currentGrantedSubjectIds, state.grantedSubjects); + + if (subjectsToRevoke.length === 0 && subjectsToGrant.length === 0) { + return; + } - const subjectsToRemove = state.initialGrantedSubjects.filter(subject => !state.grantedSubjects.includes(subject)); - await this.connectionInfoResource.deleteConnectionsAccess(key, subjectsToRemove); - } else if (state.initialGrantedSubjects.length < state.grantedSubjects.length) { + if (subjectsToRevoke.length > 0) { + await this.connectionInfoResource.deleteConnectionsAccess(key, subjectsToRevoke); + } - const subjectsToAdd = state.grantedSubjects.filter(subject => !state.initialGrantedSubjects.includes(subject)); - await this.connectionInfoResource.addConnectionsAccess(key, subjectsToAdd); - } - state.initialGrantedSubjects = state.grantedSubjects.slice(); + if (subjectsToGrant.length > 0) { + await this.connectionInfoResource.addConnectionsAccess(key, subjectsToGrant); } + + state.initialGrantedSubjects = state.grantedSubjects.slice(); } private async formState(data: IConnectionFormState, contexts: IExecutionContextProvider) { @@ -146,4 +150,11 @@ export class ConnectionAccessTabService extends Bootstrap { return current.some(value => !next.some(subjectId => subjectId === value.subjectId)); } + + private async getSubjectDifferences(current: string[], next: string[]): Promise<{ subjectsToRevoke: string[]; subjectsToGrant: string[] }> { + const subjectsToRevoke = current.filter(subjectId => !next.includes(subjectId)); + const subjectsToGrant = next.filter(subjectId => !current.includes(subjectId)); + + return { subjectsToRevoke, subjectsToGrant }; + } }