baqend
Version:
Baqend JavaScript SDK
179 lines (154 loc) • 4.79 kB
text/typescript
import type * as model from '../model';
import type { JsonMap } from '../util';
export type TrustedEntity = model.User | model.Role | string;
export type BasePermission = ['load', 'update', 'delete', 'query', 'insert'];
/**
* An aggregation of access rules for given object metadata.
*/
export class Permission {
static readonly BASE_PERMISSIONS: BasePermission = ['load', 'update', 'delete', 'query', 'insert'];
public rules: { [ref: string]: string } = {};
/**
* Returns a list of user and role references of all rules
* @return a list of references
*/
allRules(): string[] {
return Object.keys(this.rules);
}
/**
* Removes all rules from this permission object
* @return
*/
clear(): void {
this.rules = {};
}
/**
* Copies permissions from another permission object
* @param permission The permission to copy from
* @return
*/
copy(permission: Permission): Permission {
this.rules = { ...permission.rules };
return this;
}
/**
* Gets whenever all users and roles have the permission to perform the operation
* @return <code>true</code> If public access is allowed
*/
isPublicAllowed(): boolean {
if ('*' in this.rules) {
return false;
}
return !this.allRules().some((ref) => this.rules[ref] === 'allow');
}
/**
* Sets whenever all users and roles should have the permission to perform the operation
*
* Note: All other allow rules will be removed.
*
* @return
*/
setPublicAllowed(): void {
this.allRules().forEach((ref) => {
if (this.rules[ref] === 'allow') {
delete this.rules[ref];
}
});
}
/**
* Returns the actual rule of the given user or role.
* @param userOrRole The user or role to check for
* @return The actual access rule or undefined if no rule was found
*/
getRule(userOrRole: TrustedEntity): string {
return this.rules[this.ref(userOrRole)];
}
/**
* Checks whenever the user or role is explicit allowed to perform the operation.
*
* @param userOrRole The user or role to check for
* @return <code>true</code> If the given user or role is allowed
*/
isAllowed(userOrRole: TrustedEntity): boolean {
return this.rules[this.ref(userOrRole)] === 'allow';
}
/**
* Checks whenever the user or role is explicit denied to perform the operation.
*
* @param userOrRole The user or role to check for
* @return <code>true</code> If the given user or role is denied
*/
isDenied(userOrRole: TrustedEntity): boolean {
return this.rules[this.ref(userOrRole)] === 'deny';
}
/**
* Allows the given users or rules to perform the operation
* @param userOrRole The users or roles to allow
* @return this permission object
*/
allowAccess(...userOrRole: TrustedEntity[]): Permission {
for (let i = 0; i < userOrRole.length; i += 1) {
this.rules[this.ref(userOrRole[i])] = 'allow';
}
return this;
}
/**
* Denies the given users or rules to perform the operation
* @param userOrRole The users or roles to deny
* @return this permission object
*/
denyAccess(...userOrRole: TrustedEntity[]): Permission {
for (let i = 0; i < userOrRole.length; i += 1) {
this.rules[this.ref(userOrRole[i])] = 'deny';
}
return this;
}
/**
* Deletes any allow/deny rules for the given users or roles
* @param userOrRole The users or roles to delete rules for
* @return this permission object
*/
deleteAccess(...userOrRole: TrustedEntity[]): Permission {
for (let i = 0; i < userOrRole.length; i += 1) {
delete this.rules[this.ref(userOrRole[i])];
}
return this;
}
/**
* A Json representation of the set of rules
* @return
*/
toJSON(): JsonMap {
return { ...this.rules };
}
/**
* Sets the permission rules from json
* @param json The permission json representation
* @return
*/
fromJSON(json: JsonMap) {
this.rules = { ...json } as { [ref: string]: string };
}
/**
* Creates a permission from the given rules.
* @param json The rules.
* @return The permission.
*/
static fromJSON(json: JsonMap): Permission {
const permission = new this();
permission.fromJSON(json);
return permission;
}
/**
* Resolves user and role references and validate given references
* @param userOrRole The user, role or reference
* @return The resolved and validated reference
*/
private ref(userOrRole: TrustedEntity): string {
const ref = typeof userOrRole === 'string' ? userOrRole : userOrRole.id!;
if (ref.indexOf('/db/User/') === 0 || ref.indexOf('/db/Role/') === 0) {
return ref;
}
throw new TypeError('The given object isn\'t a user, role or a valid reference.');
}
}