import Node from 'type/node'; import SystemId from 'system/enum/id'; import ActionType from 'enum/action-type'; import PermissionNode from 'type/node/permission'; import UnauthorizedError from 'http/error/unauthorized'; import getNodeParameters from 'utility/get-node-parameters'; import LoadNodeFromUrlOperation from 'operation/load-node-from-url'; import Operation, { OperationInput } from 'operation'; import FetchNodePermissionsOperation from 'operation/fetch-node-permissions'; import FetchListFieldValuesOperation from 'operation/fetch-list-field-values'; interface Input extends OperationInput { readonly node: Node; readonly action_type: ActionType; } class CheckNodePermissionOperation extends Operation { protected async performInternal(): Promise { if (this.accountIsCreator()) { return Promise.resolve(); } const permission = await this.fetchRequiredPermission(); if (permission === undefined) { throw new UnauthorizedError(); } await this.ensureAccountExistsInGroup(permission.group); } private async fetchRequiredPermission(): Promise { const permissions = await this.fetchNodePermissions(); const action_type = this.getActionType(); return permissions.find((permission) => { return permission.action_type === action_type; }); } private fetchNodePermissions(): Promise { const node = this.getNode(); const repository = this.getRepository(); const account = this.getAccount(); const input = { node, repository, account }; const operation = new FetchNodePermissionsOperation(input); return operation.perform(); } private async ensureAccountExistsInGroup(group_url: string): Promise { if (this.isEveryoneGroup(group_url)) { return; } const repository = this.getRepository(); const account = this.getAccount(); const load_node_operation = new LoadNodeFromUrlOperation({ url: group_url, repository, account }); const node = await load_node_operation.perform(); const field_key = 'accounts'; const list_values_operation = new FetchListFieldValuesOperation({ node, field_key, repository, account }); const values = await list_values_operation.perform(); const account_urls = values as string[]; if (account_urls.includes(account.url)) { return; } throw new UnauthorizedError(); } private accountIsCreator(): boolean { const account = this.getAccount(); const node = this.getNode(); return account.url === node.creator; } private isEveryoneGroup(group_url: string): boolean { const parameters = getNodeParameters(group_url); const id = parameters.id; return id === SystemId.EVERYONE_GROUP; } private getActionType(): ActionType { const input = this.getInput(); return input.action_type; } private getNode(): Node { const input = this.getInput(); return input.node; } } export default CheckNodePermissionOperation;