From 7ae7c4e571b091a6bc1879cbed8c3cf828f97e6a Mon Sep 17 00:00:00 2001 From: Neil Smyth Date: Mon, 1 Jul 2024 09:49:55 +0200 Subject: [PATCH 1/3] virtual receives auth extended for child entities --- .../account/account.resolver.mutations.ts | 8 +- .../account/account.service.authorization.ts | 160 +++++++++++------- 2 files changed, 102 insertions(+), 66 deletions(-) diff --git a/src/domain/space/account/account.resolver.mutations.ts b/src/domain/space/account/account.resolver.mutations.ts index 5dde8b9321..d3a69965f2 100644 --- a/src/domain/space/account/account.resolver.mutations.ts +++ b/src/domain/space/account/account.resolver.mutations.ts @@ -279,10 +279,16 @@ export class AccountResolverMutations { virtualContributorData ); + const clonedAccountAuth = + await this.accountAuthorizationService.getClonedAccountAuthExtendedForChildEntities( + virtual.account + ); + + // Need virtual = await this.virtualContributorAuthorizationService.applyAuthorizationPolicy( virtual, - account.authorization + clonedAccountAuth ); virtual = await this.virtualContributorService.save(virtual); diff --git a/src/domain/space/account/account.service.authorization.ts b/src/domain/space/account/account.service.authorization.ts index e976f8b389..04acb93738 100644 --- a/src/domain/space/account/account.service.authorization.ts +++ b/src/domain/space/account/account.service.authorization.ts @@ -52,43 +52,27 @@ export class AccountAuthorizationService { ) {} async applyAuthorizationPolicy(accountInput: IAccount): Promise { - const account = await this.accountService.getAccountOrFail( - accountInput.id, - { - relations: { - agent: true, - space: { - community: { - policy: true, - }, + let account = await this.accountService.getAccountOrFail(accountInput.id, { + relations: { + agent: true, + space: { + community: { + policy: true, }, - license: true, - library: true, - defaults: true, - virtualContributors: true, - storageAggregator: true, }, - } - ); - if ( - !account.agent || - !account.space || - !account.space.community || - !account.space.community.policy || - !account.library || - !account.license || - !account.defaults || - !account.virtualContributors || - !account.storageAggregator - ) { + license: true, + library: true, + defaults: true, + virtualContributors: true, + storageAggregator: true, + }, + }); + if (!account.space) { throw new RelationshipNotFoundException( `Unable to load Account with entities at start of auth reset: ${account.id} `, LogContext.ACCOUNT ); } - const hostCredentials = await this.accountHostService.getHostCredentials( - account - ); // Ensure always applying from a clean state account.authorization = this.authorizationPolicyService.reset( @@ -100,16 +84,84 @@ export class AccountAuthorizationService { account.authorization ); - // For now also use the root space admins to have some access + account.authorization = await this.extendAuthorizationPolicy( + account, + account.authorization + ); + account.authorization = this.appendPrivilegeRules(account.authorization); + + account = await this.applyAuthorizationPolicyForChildEntities(account); + + // Need to save as there is still a circular dependency from space auth to account auth reset + const savedAccount = await this.accountService.save(account); + + // And cascade into the space if there is one + if (!account.space) { + throw new RelationshipNotFoundException( + `No space on account for resetting: ${account.id} `, + LogContext.ACCOUNT + ); + } + savedAccount.space = + await this.spaceAuthorizationService.applyAuthorizationPolicy( + account.space + ); + + return savedAccount; + } + public async getClonedAccountAuthExtendedForChildEntities( + account: IAccount + ): Promise { + if (!account.space) { + throw new RelationshipNotFoundException( + `Unable to load Account with entities at start of auth reset: ${account.id} `, + LogContext.ACCOUNT + ); + } + let clonedAccountAuth = + this.authorizationPolicyService.cloneAuthorizationPolicy( + account.authorization + ); + const communityPolicyWithSettings = this.spaceAuthorizationService.getCommunityPolicyWithSettings( account.space ); - account.authorization = this.extendAuthorizationPolicy( - account.authorization, + + const hostCredentials = await this.accountHostService.getHostCredentials( + account + ); + + clonedAccountAuth = this.extendAuthorizationPolicyForChildEntities( + clonedAccountAuth, + communityPolicyWithSettings, hostCredentials ); - account.authorization = this.appendPrivilegeRules(account.authorization); + return clonedAccountAuth; + } + + public async applyAuthorizationPolicyForChildEntities( + account: IAccount + ): Promise { + if ( + !account.agent || + !account.space || + !account.space.community || + !account.space.community.policy || + !account.library || + !account.license || + !account.defaults || + !account.virtualContributors || + !account.storageAggregator + ) { + throw new RelationshipNotFoundException( + `Unable to load Account with entities at start of auth reset: ${account.id} `, + LogContext.ACCOUNT + ); + } + + const clonedAccountAuth = + await this.getClonedAccountAuthExtendedForChildEntities(account); account.agent = this.agentAuthorizationService.applyAuthorizationPolicy( account.agent, @@ -121,16 +173,6 @@ export class AccountAuthorizationService { account.authorization ); - let clonedAccountAuth = - this.authorizationPolicyService.cloneAuthorizationPolicy( - account.authorization - ); - clonedAccountAuth = this.extendAuthorizationPolicyForChildEntities( - clonedAccountAuth, - communityPolicyWithSettings, - hostCredentials - ); - // For certain child entities allow the space admin also pretty much full control account.library = await this.templatesSetAuthorizationService.applyAuthorizationPolicy( @@ -160,29 +202,13 @@ export class AccountAuthorizationService { updatedVCs.push(udpatedVC); } account.virtualContributors = updatedVCs; - - // Need to save as there is still a circular dependency from space auth to account auth reset - const savedAccount = await this.accountService.save(account); - - // And cascade into the space if there is one - if (!account.space) { - throw new RelationshipNotFoundException( - `No space on account for resetting: ${account.id} `, - LogContext.ACCOUNT - ); - } - savedAccount.space = - await this.spaceAuthorizationService.applyAuthorizationPolicy( - account.space - ); - - return savedAccount; + return account; } - private extendAuthorizationPolicy( - authorization: IAuthorizationPolicy | undefined, - hostCredentials: ICredentialDefinition[] - ): IAuthorizationPolicy { + private async extendAuthorizationPolicy( + account: IAccount, + authorization: IAuthorizationPolicy | undefined + ): Promise { if (!authorization) { throw new EntityNotInitializedException( 'Authorization definition not found for account', @@ -190,6 +216,10 @@ export class AccountAuthorizationService { ); } + const hostCredentials = await this.accountHostService.getHostCredentials( + account + ); + const newRules: IAuthorizationPolicyRuleCredential[] = []; // By default it is world visible. TODO: work through the logic on this authorization.anonymousReadAccess = true; From 806fc79ae990d04218bda687059ae3c8d67919a6 Mon Sep 17 00:00:00 2001 From: Valentin Yanakiev Date: Mon, 1 Jul 2024 11:43:33 +0300 Subject: [PATCH 2/3] Fixed account loading --- src/domain/space/account/account.resolver.mutations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domain/space/account/account.resolver.mutations.ts b/src/domain/space/account/account.resolver.mutations.ts index d3a69965f2..8eefd21cbc 100644 --- a/src/domain/space/account/account.resolver.mutations.ts +++ b/src/domain/space/account/account.resolver.mutations.ts @@ -281,7 +281,7 @@ export class AccountResolverMutations { const clonedAccountAuth = await this.accountAuthorizationService.getClonedAccountAuthExtendedForChildEntities( - virtual.account + account ); // Need From 4515450dd94f23a89894f9c640bbab640b35ef9c Mon Sep 17 00:00:00 2001 From: Valentin Yanakiev Date: Mon, 1 Jul 2024 11:50:18 +0300 Subject: [PATCH 3/3] Minor version bump --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8fa61253fa..6f6cd491b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "alkemio-server", - "version": "0.82.6", + "version": "0.82.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "alkemio-server", - "version": "0.82.6", + "version": "0.82.7", "license": "EUPL-1.2", "dependencies": { "@alkemio/matrix-adapter-lib": "^0.3.6", diff --git a/package.json b/package.json index 5136ee8625..f514fd6cca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alkemio-server", - "version": "0.82.6", + "version": "0.82.7", "description": "Alkemio server, responsible for managing the shared Alkemio platform", "author": "Alkemio Foundation", "private": false,