import type { Field } from '../model/implementation/field.js'; import type { Permission, PermissionProfile } from '../model/implementation/permission-profile.js'; import type { RootEntityType } from '../model/implementation/root-entity-type.js'; import type { QueryNode } from '../query-tree/base.js'; import type { AuthContext } from './auth-basics.js'; import { AccessOperation } from './auth-basics.js'; import type { AccessConditionDescription } from './describe-access-condition.js'; export declare enum ConditionExplanationContext { BEFORE_WRITE = 0, SET = 1 } /** * Determines whether a user can access information, possibly dependent on the instance containing the information */ export declare abstract class PermissionDescriptor { /** * Gets the condition which determines if a user has access * @param authContext * @param operation * @param instanceNode a QueryNode which evaluates to the instance * @returns a QueryNode that evaluates to TRUE if the user has access or FALSE if they don't */ abstract getAccessCondition(authContext: AuthContext, operation: AccessOperation, instanceNode: QueryNode): QueryNode; /** * Determines if a user has access or if it depends on the instance */ canAccess(authContext: AuthContext, operation: AccessOperation): PermissionResult; /** * Gets a condition that checks that all items that are added to or removed from list fields used in * restrictions would be permitted on their own * * This prevents users from granting or revoking access to objects for values they don't have access to * themselves. The regular access condition only requires one list item to match. * * Each changed item is checked by evaluating the access condition on the new instance with the list replaced * by just that item. Thus, if a permission grants access to the new instance without restricting the list * field, all changes to the list are allowed. Otherwise, each changed item needs to match the restriction on * the list field of a permission whose other restrictions match the new instance. * * @param authContext * @param operation * @param oldInstanceNode a QueryNode that evaluates to the instance before the change, or undefined if the * instance is created * @param newInstanceNode a QueryNode that evaluates to the instance after the change * @param isFieldPathAffected can be used to skip list fields that are known not to be changed * @returns a QueryNode that evaluates to TRUE if the change is allowed or FALSE if it isn't */ getListChangeCondition(authContext: AuthContext, operation: AccessOperation, oldInstanceNode: QueryNode | undefined, newInstanceNode: QueryNode, isFieldPathAffected?: (fields: ReadonlyArray) => boolean): QueryNode; /** * Gets a human-readable explanation fragment that explains why some instance could not be accessed */ getExplanationForCondition(authContext: AuthContext, operation: AccessOperation, context: ConditionExplanationContext): string | undefined; /** * Determines if the user has permissions for the operation that restrict the accessible * objects. If canAccess() returns DENIED nevertheless, these permissions match no object. */ hasApplicablePermissions(authContext: AuthContext, operation: AccessOperation): boolean; /** * Describes the condition that determines if a user has access, e.g. for tools that explain * why a query reads or skips certain objects */ describeAccessCondition(authContext: AuthContext, operation: AccessOperation): AccessConditionDescription; } export declare enum PermissionResult { /** * Access is granted for all instances */ GRANTED = 0, /** * Access may be granted or denied, depending on the instance's accessGroup */ CONDITIONAL = 1, /** * Access is denied for all instances */ DENIED = 2 } export declare class AlwaysGrantPermissionDescriptor extends PermissionDescriptor { getAccessCondition(authContext: AuthContext, operation: AccessOperation): QueryNode; canAccess(authContext: AuthContext, operation: AccessOperation): PermissionResult; static readonly INSTANCE: AlwaysGrantPermissionDescriptor; } export declare class AlwaysDenyPermissionDescriptor extends PermissionDescriptor { getAccessCondition(authContext: AuthContext, operation: AccessOperation): QueryNode; canAccess(authContext: AuthContext, operation: AccessOperation): PermissionResult; static readonly INSTANCE: AlwaysDenyPermissionDescriptor; } export declare class ConjunctivePermissionDescriptor extends PermissionDescriptor { readonly lhs: PermissionDescriptor; readonly rhs: PermissionDescriptor; constructor(lhs: PermissionDescriptor, rhs: PermissionDescriptor); getAccessCondition(authContext: AuthContext, operation: AccessOperation): QueryNode; } export declare class StaticPermissionDescriptor extends PermissionDescriptor { readonly readRoles: ReadonlyArray; readonly readWriteRoles: ReadonlyArray; private readonly allReadRoles; constructor(readRoles: ReadonlyArray, readWriteRoles: ReadonlyArray); getAccessCondition(authContext: AuthContext, operation: AccessOperation): QueryNode; } export declare class ProfileBasedPermissionDescriptor extends PermissionDescriptor { private readonly profile; private readonly rootEntityType?; private readonly accessGroupField; constructor(profile: PermissionProfile, rootEntityType?: RootEntityType | undefined); getAccessCondition(authContext: AuthContext, operation: AccessOperation, instanceNode: QueryNode): QueryNode; private getAccessConditionForPermissions; getPermissionRestrictionCondition(permission: Permission, authContext: AuthContext, instanceNode: QueryNode): QueryNode; hasApplicablePermissions(authContext: AuthContext, operation: AccessOperation): boolean; describeAccessCondition(authContext: AuthContext, operation: AccessOperation): AccessConditionDescription; private describePermission; getListChangeCondition(authContext: AuthContext, operation: AccessOperation, oldInstanceNode: QueryNode | undefined, newInstanceNode: QueryNode, isFieldPathAffected?: (fields: ReadonlyArray) => boolean): QueryNode; private isListRestrictionField; private getRestrictionFieldPath; private getPureAccessGroupCondition; private getAccessGroupConditionNode; private getApplicablePermissions; private getAllowedAccessGroups; getExplanationForCondition(authContext: AuthContext, operation: AccessOperation, context: ConditionExplanationContext): string | undefined; getExplanationPrefixForAccessGroups(context: ConditionExplanationContext): string; getExplanationForSingleField(context: ConditionExplanationContext, fieldName: string): string; getGeneralExplanation(context: ConditionExplanationContext): string; getGenericDataDependentExplanation(context: ConditionExplanationContext): string; }