"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.makeRouterWithFleetAuthz = makeRouterWithFleetAuthz;
var _constants = require("../../../common/constants");
var _request_store = require("../request_store");
var _security = require("./security");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

function withDefaultPublicAccess(options) {
  if (options !== null && options !== void 0 && options.access) {
    return options;
  } else {
    return {
      ...options,
      access: _constants.PUBLIC_API_ACCESS
    };
  }
}
function makeRouterWithFleetAuthz(router, logger) {
  const routerAuthzWrapper = async ({
    context,
    request,
    response,
    handler,
    hasRequiredAuthz
  }) => {
    if (!(0, _security.checkSecurityEnabled)()) {
      const securityEnabledInfo = 'Kibana security must be enabled to use Fleet';
      logger.info(securityEnabledInfo);
      return response.forbidden({
        body: {
          message: securityEnabledInfo
        }
      });
    }
    const requestedAuthz = await (0, _security.getAuthzFromRequest)(request);
    if ((0, _security.doesNotHaveRequiredFleetAuthz)(requestedAuthz, hasRequiredAuthz)) {
      logger.info(`User does not have required fleet authz to access path: ${request.route.path}`);
      return response.forbidden();
    }
    return handler(context, request, response);
  };
  const requestContextWrapper = async ({
    context,
    request,
    response,
    handler
  }) => {
    return (0, _request_store.getRequestStore)().run(request, () => handler(context, request, response));
  };
  const fleetHandlerWrapper = async ({
    context,
    request,
    response,
    handler,
    hasRequiredAuthz
  }) => {
    return requestContextWrapper({
      context,
      request,
      response,
      handler: (handlerContext, handlerRequest, handlerResponse) => routerAuthzWrapper({
        context: handlerContext,
        request: handlerRequest,
        response: handlerResponse,
        handler,
        hasRequiredAuthz
      })
    });
  };
  const fleetAuthzRouter = {
    versioned: {
      get: ({
        fleetAuthz,
        ...options
      }) => {
        const res = router.versioned.get(withDefaultPublicAccess(options));
        const originalAddVersion = res.addVersion.bind(res);
        function addVersion({
          fleetAuthz: versionAuthz,
          ...opts
        }, handler) {
          originalAddVersion({
            ...opts
          }, (context, request, response) => fleetHandlerWrapper({
            context,
            request,
            response,
            handler,
            hasRequiredAuthz: versionAuthz || fleetAuthz
          }));
          return {
            addVersion
          };
        }
        return {
          addVersion
        };
      },
      delete: ({
        fleetAuthz,
        ...options
      }) => {
        const res = router.versioned.delete(withDefaultPublicAccess(options));
        const originalAddVersion = res.addVersion.bind(res);
        function addVersion({
          fleetAuthz: versionAuthz,
          ...opts
        }, handler) {
          originalAddVersion({
            ...opts
          }, (context, request, response) => fleetHandlerWrapper({
            context,
            request,
            response,
            handler,
            hasRequiredAuthz: versionAuthz || fleetAuthz
          }));
          return {
            addVersion
          };
        }
        return {
          addVersion
        };
      },
      put: ({
        fleetAuthz,
        ...options
      }) => {
        const res = router.versioned.put(withDefaultPublicAccess(options));
        const originalAddVersion = res.addVersion.bind(res);
        function addVersion({
          fleetAuthz: versionAuthz,
          ...opts
        }, handler) {
          originalAddVersion({
            ...opts
          }, (context, request, response) => fleetHandlerWrapper({
            context,
            request,
            response,
            handler,
            hasRequiredAuthz: versionAuthz || fleetAuthz
          }));
          return {
            addVersion
          };
        }
        return {
          addVersion
        };
      },
      post: ({
        fleetAuthz,
        ...options
      }) => {
        const res = router.versioned.post(withDefaultPublicAccess(options));
        const originalAddVersion = res.addVersion.bind(res);
        function addVersion({
          fleetAuthz: versionAuthz,
          ...opts
        }, handler) {
          originalAddVersion({
            ...opts
          }, (context, request, response) => fleetHandlerWrapper({
            context,
            request,
            response,
            handler,
            hasRequiredAuthz: versionAuthz || fleetAuthz
          }));
          return {
            addVersion
          };
        }
        return {
          addVersion
        };
      },
      patch: ({
        fleetAuthz,
        ...options
      }) => {
        const res = router.versioned.patch(withDefaultPublicAccess(options));
        const originalAddVersion = res.addVersion.bind(res);
        function addVersion({
          fleetAuthz: versionAuthz,
          ...opts
        }, handler) {
          originalAddVersion({
            ...opts
          }, (context, request, response) => fleetHandlerWrapper({
            context,
            request,
            response,
            handler,
            hasRequiredAuthz: versionAuthz || fleetAuthz
          }));
          return {
            addVersion
          };
        }
        return {
          addVersion
        };
      }
    }
  };
  return fleetAuthzRouter;
}