"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReadDeleteAuthorizer = void 0;
const policy_engine_1 = require("@solidlab/policy-engine");
const global_logger_factory_1 = require("global-logger-factory");
const NotFoundHttpError_1 = require("../util/errors/NotFoundHttpError");
const Authorizer_1 = require("./Authorizer");
/**
 * An {@link Authorizer} that does the necessary checks to return a 404 instead of a 401/403
 * when trying to delete a non-existent resource when the client has the correct read permissions.
 *
 * In other cases, the request gets handled by the source authorizer.
 */
class ReadDeleteAuthorizer extends Authorizer_1.Authorizer {
    logger = (0, global_logger_factory_1.getLoggerFor)(this);
    source;
    resourceSet;
    identifierStrategy;
    constructor(source, resourceSet, identifierStrategy) {
        super();
        this.source = source;
        this.resourceSet = resourceSet;
        this.identifierStrategy = identifierStrategy;
    }
    async canHandle(input) {
        return this.source.canHandle(input);
    }
    async handle(input) {
        for (const identifier of input.requestedModes.distinctKeys()) {
            if (input.requestedModes.hasEntry(identifier, policy_engine_1.PERMISSIONS.Delete) &&
                !await this.resourceSet.hasResource(identifier)) {
                this.logger.debug(`Trying to delete non-existent resource ${identifier.path}`);
                if (input.availablePermissions.get(identifier)?.[policy_engine_1.PERMISSIONS.Read]) {
                    this.logger.debug(`Returning 404 as the client has read permissions on the resource`);
                    throw new NotFoundHttpError_1.NotFoundHttpError();
                }
                else if (!this.identifierStrategy.isRootContainer(identifier) &&
                    input.availablePermissions.get(this.identifierStrategy.getParentContainer(identifier))?.[policy_engine_1.PERMISSIONS.Read]) {
                    this.logger.debug(`Returning 404 as the client has read permissions on the parent container`);
                    throw new NotFoundHttpError_1.NotFoundHttpError();
                }
                else if (input.availablePermissions.has(identifier)) {
                    // Remove the available delete permission so the source authorizer will throw the correct error
                    input.availablePermissions.get(identifier)[policy_engine_1.PERMISSIONS.Delete] = false;
                }
            }
        }
        return this.source.handle(input);
    }
}
exports.ReadDeleteAuthorizer = ReadDeleteAuthorizer;
//# sourceMappingURL=ReadDeleteAuthorizer.js.map