Browse Source

Restrict restricted view and manage permission to MCP

pull/7783/head
Thomas Kaul 1 month ago
parent
commit
657e32bdeb
  1. 30
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
  2. 2
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
  3. 16
      libs/common/src/lib/scopes.ts

30
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts

@ -6,6 +6,7 @@ import { Filter, PortfolioPosition } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import {
Scope,
canGrantRestrictedWriteAccess,
getAccessLevel,
getScopesOfAccess,
getScopesOfAccessLevel,
@ -125,6 +126,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
return this.hasExperimentalFeatures && this.hasPermissionToEnableMcp;
}
public get canGrantRestrictedWriteAccess() {
return canGrantRestrictedWriteAccess({ type: this.accessType });
}
public get canGrantWriteAccess() {
return this.hasExperimentalFeatures;
}
@ -195,25 +200,16 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
// Narrow the permission to the scopes which the type permits, because
// an access which is not granted to a user never exposes the monetary
// values and a public access never changes data. The type PRIVATE has
// no restricted write level, hence the permission to change the data
// exposes the monetary values
const accessLevelOfType = getAccessLevel(
getScopesOfAccess({
scopes: getScopesOfAccessLevel(this.accessLevel),
type: accessType
})
// values and a public access never changes data
this.accessForm.get('accessLevel')?.setValue(
getAccessLevel(
getScopesOfAccess({
scopes: getScopesOfAccessLevel(this.accessLevel),
type: accessType
})
)
);
this.accessForm
.get('accessLevel')
?.setValue(
accessType === 'PRIVATE' &&
this.accessLevel === 'CREATE_READ_RESTRICTED_UPDATE_DELETE'
? 'CREATE_READ_UPDATE_DELETE'
: accessLevelOfType
);
if (!canApplyFiltersToAccess({ type: accessType })) {
this.accessForm.get('filters')?.setValue(null);
}

2
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html

@ -82,7 +82,7 @@
<mat-option value="READ_RESTRICTED">
<gf-access-level-icon accessLevel="READ_RESTRICTED" />
</mat-option>
@if (accessForm.get('type')?.value === 'MCP') {
@if (canGrantRestrictedWriteAccess) {
<mat-option
value="CREATE_READ_RESTRICTED_UPDATE_DELETE"
[disabled]="!canGrantWriteAccess"

16
libs/common/src/lib/scopes.ts

@ -64,7 +64,9 @@ export const SCOPES_OF_READ_RESTRICTED_ACCESS: readonly Scope[] =
/**
* Maximum scopes per access type. The scopes stored on an access are
* intersected with it, hence a scope which the type does not permit stays
* ineffective even if it is stored.
* ineffective even if it is stored. A type which cannot grant the restricted
* write access drops the write scopes in addition, unless the access reads the
* monetary values.
*/
const SCOPES_OF_TYPE: Record<AccessType, readonly Scope[]> = {
MCP: [...SCOPES_OF_READ_RESTRICTED_ACCESS, scopes.activityCreate],
@ -72,6 +74,14 @@ const SCOPES_OF_TYPE: Record<AccessType, readonly Scope[]> = {
PUBLIC: SCOPES_OF_PUBLIC_ACCESS
};
/**
* Access types which combine a write scope with the restricted read access,
* because their tools change data without exposing the monetary values
*/
export function canGrantRestrictedWriteAccess({ type }: { type: AccessType }) {
return type === 'MCP';
}
/**
* Access level which the scopes of an access grant
*/
@ -96,10 +106,8 @@ export function getScopesOfAccess({
}): string[] {
const scopesToEvaluate = scopesOfAccess ?? [];
// The type PRIVATE has no restricted write level, hence a write scope stays
// ineffective without the scope to read the monetary values
const permitsWriteAccess =
type !== 'PRIVATE' ||
canGrantRestrictedWriteAccess({ type }) ||
hasScope(scopesToEvaluate, scopes.portfolioReadValues);
// An unknown scope is dropped

Loading…
Cancel
Save