UNPKG

@solid/community-server

Version:

Community Solid Server: an open and modular implementation of the Solid specifications

66 lines 3.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MethodModesExtractor = void 0; const policy_engine_1 = require("@solidlab/policy-engine"); const NotImplementedHttpError_1 = require("../../util/errors/NotImplementedHttpError"); const IdentifierMap_1 = require("../../util/map/IdentifierMap"); const PathUtil_1 = require("../../util/PathUtil"); const ModesExtractor_1 = require("./ModesExtractor"); const READ_METHODS = new Set(['OPTIONS', 'GET', 'HEAD']); const SUPPORTED_METHODS = new Set([...READ_METHODS, 'PUT', 'POST', 'DELETE']); /** * Generates permissions for the base set of methods that always require the same permissions. * Specifically: GET, HEAD, POST, PUT and DELETE. */ class MethodModesExtractor extends ModesExtractor_1.ModesExtractor { resourceSet; /** * Certain permissions depend on the existence of the target resource. * The provided {@link ResourceSet} will be used for that. * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. */ constructor(resourceSet) { super(); this.resourceSet = resourceSet; } async canHandle({ method }) { if (!SUPPORTED_METHODS.has(method)) { throw new NotImplementedHttpError_1.NotImplementedHttpError(`Cannot determine permissions of ${method}`); } } async handle({ method, target }) { const requiredModes = new IdentifierMap_1.IdentifierSetMultiMap(); // Reading requires Read permissions on the resource if (READ_METHODS.has(method)) { requiredModes.add(target, policy_engine_1.PERMISSIONS.Read); } if (method === 'PUT') { if (await this.resourceSet.hasResource(target)) { // Replacing a resource's representation with PUT requires Write permissions requiredModes.add(target, policy_engine_1.PERMISSIONS.Modify); } else { // ... while creating a new resource with PUT requires Append and Create permissions. requiredModes.add(target, policy_engine_1.PERMISSIONS.Append); requiredModes.add(target, policy_engine_1.PERMISSIONS.Create); } } // Creating a new resource in a container requires Append access to that container if (method === 'POST') { requiredModes.add(target, policy_engine_1.PERMISSIONS.Append); } // Deleting a resource requires Delete access if (method === 'DELETE') { requiredModes.add(target, policy_engine_1.PERMISSIONS.Delete); // …and, if the target is a container, Read permissions are required as well // as this exposes if a container is empty or not if ((0, PathUtil_1.isContainerIdentifier)(target)) { requiredModes.add(target, policy_engine_1.PERMISSIONS.Read); } } return requiredModes; } } exports.MethodModesExtractor = MethodModesExtractor; //# sourceMappingURL=MethodModesExtractor.js.map