Skip to content

Commit

Permalink
Merge pull request #4191 from alkem-io/develop
Browse files Browse the repository at this point in the history
Release: Fixes
  • Loading branch information
valentinyanakiev authored Jul 1, 2024
2 parents 2ea98a7 + f61c640 commit 3c4965b
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 69 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
8 changes: 7 additions & 1 deletion src/domain/space/account/account.resolver.mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,16 @@ export class AccountResolverMutations {
virtualContributorData
);

const clonedAccountAuth =
await this.accountAuthorizationService.getClonedAccountAuthExtendedForChildEntities(
account
);

// Need
virtual =
await this.virtualContributorAuthorizationService.applyAuthorizationPolicy(
virtual,
account.authorization
clonedAccountAuth
);

virtual = await this.virtualContributorService.save(virtual);
Expand Down
160 changes: 95 additions & 65 deletions src/domain/space/account/account.service.authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,43 +52,27 @@ export class AccountAuthorizationService {
) {}

async applyAuthorizationPolicy(accountInput: IAccount): Promise<IAccount> {
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(
Expand All @@ -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<IAuthorizationPolicy> {
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<IAccount> {
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,
Expand All @@ -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(
Expand Down Expand Up @@ -160,36 +202,24 @@ 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<IAuthorizationPolicy> {
if (!authorization) {
throw new EntityNotInitializedException(
'Authorization definition not found for account',
LogContext.ACCOUNT
);
}

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;
Expand Down

0 comments on commit 3c4965b

Please sign in to comment.