"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthorizingHttpHandler = void 0;
const LogUtil_1 = require("../logging/LogUtil");
const OperationHttpHandler_1 = require("./OperationHttpHandler");
/**
 * Handles all the necessary steps for an authorization.
 * Errors if authorization fails, otherwise passes the parameter to the operationHandler handler.
 * The following steps are executed:
 *  - Extracting credentials from the request.
 *  - Extracting the required permissions.
 *  - Reading the allowed permissions for the credentials.
 *  - Validating if this operation is allowed.
 */
class AuthorizingHttpHandler extends OperationHttpHandler_1.OperationHttpHandler {
    constructor(args) {
        super();
        this.logger = (0, LogUtil_1.getLoggerFor)(this);
        this.credentialsExtractor = args.credentialsExtractor;
        this.modesExtractor = args.modesExtractor;
        this.permissionReader = args.permissionReader;
        this.authorizer = args.authorizer;
        this.operationHandler = args.operationHandler;
    }
    async handle(input) {
        const { request, operation } = input;
        const credentials = await this.credentialsExtractor.handleSafe(request);
        this.logger.verbose(`Extracted credentials: ${JSON.stringify(credentials)}`);
        const requestedModes = await this.modesExtractor.handleSafe(operation);
        this.logger.verbose(`Retrieved required modes: ${[...requestedModes.entrySets()].map(([id, set]) => `{ ${id.path}: ${[...set]} }`)}`);
        const availablePermissions = await this.permissionReader.handleSafe({ credentials, requestedModes });
        this.logger.verbose(`Available permissions are ${[...availablePermissions.entries()].map(([id, map]) => `{ ${id.path}: ${JSON.stringify(map)} }`)}`);
        try {
            await this.authorizer.handleSafe({ credentials, requestedModes, availablePermissions });
        }
        catch (error) {
            this.logger.verbose(`Authorization failed: ${error.message}`);
            throw error;
        }
        this.logger.verbose(`Authorization succeeded, calling source handler`);
        return this.operationHandler.handleSafe(input);
    }
}
exports.AuthorizingHttpHandler = AuthorizingHttpHandler;
//# sourceMappingURL=AuthorizingHttpHandler.js.map