"use strict";
/*
 *  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *  SPDX-License-Identifier: Apache-2.0
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SWBProjectService = void 0;
const workbench_core_authorization_1 = require("@aws/workbench-core-authorization");
const roleUtils_1 = require("../utils/roleUtils");
class SWBProjectService {
    constructor(dynamicAuthorizationService, projectService) {
        this._dynamicAuthorizationService = dynamicAuthorizationService;
        this._projectService = projectService;
    }
    /**
     * Creates a new project
     *
     * @param params - the required fields to create a new project
     * @param user - authenticated user creating the project
     * @returns Project object of new project
     */
    async createProject(params, user) {
        const createProjectResponse = await this._projectService.createProject(params);
        const projectId = createProjectResponse.id;
        const paRole = (0, roleUtils_1.getProjectAdminRole)(projectId);
        const researcherRole = (0, roleUtils_1.getResearcherRole)(projectId);
        await this._dynamicAuthorizationService.createGroup({
            authenticatedUser: user,
            groupId: paRole,
            description: `Project Admin group for ${projectId}`
        });
        await this._dynamicAuthorizationService.createGroup({
            authenticatedUser: user,
            groupId: researcherRole,
            description: `Researcher group for ${projectId}`
        });
        // Create PA Permissions
        const paIdentityPermissions = this._generatePAIdentityPermissions(projectId, paRole);
        // Create Researcher Permissions
        const researcherIdentityPermissions = this._generateResearcherIdentityPermissions(projectId, researcherRole);
        const createIdentityPermissionsRequest = workbench_core_authorization_1.CreateIdentityPermissionsRequestParser.parse({
            authenticatedUser: user,
            identityPermissions: [...paIdentityPermissions, ...researcherIdentityPermissions]
        });
        await this._dynamicAuthorizationService.createIdentityPermissions(createIdentityPermissionsRequest);
        return createProjectResponse;
    }
    /**
     * Get project
     * @param request - the request object for getting a project
     *
     * @returns Project entry in DDB
     */
    async getProject(request) {
        return this._projectService.getProject(request);
    }
    /**
     * Get projects
     * @param request - the request object for getting a project
     *
     * @returns Project entry in DDB
     */
    async getProjects(request) {
        return this._projectService.getProjects(request);
    }
    /**
     * List projects
     *
     * @param request - the request object for listing projects
     * @returns Project entries in DDB, with optional pagination token
     */
    async listProjects(request) {
        const getUserGroupsResponse = await this._dynamicAuthorizationService.getUserGroups({
            authenticatedUser: request.user,
            userId: request.user.id
        });
        return this._projectService.listProjects(request, getUserGroupsResponse.data.groupIds);
    }
    /**
     * Soft deletes a project from the database.
     *
     * @param request - a {@link DeleteProjectRequest} object that contains the id of the project to delete
     * @param checkDependencies - an async function that checks if there are dependencies associated with the project
     */
    async softDeleteProject(request, checkDependencies) {
        await this._projectService.softDeleteProject(request, checkDependencies);
        const authenticatedUser = request.authenticatedUser;
        const projectId = request.projectId;
        const paRole = (0, roleUtils_1.getProjectAdminRole)(projectId);
        const researcherRole = (0, roleUtils_1.getResearcherRole)(projectId);
        // Get PA Permissions to delete
        const paIdentityPermissions = this._generatePAIdentityPermissions(projectId, paRole);
        // Get Researcher Permissions to delete
        const researcherIdentityPermissions = this._generateResearcherIdentityPermissions(projectId, researcherRole);
        const deleteIdentityPermissionsRequest = workbench_core_authorization_1.DeleteIdentityPermissionsRequestParser.parse({
            authenticatedUser,
            identityPermissions: [...paIdentityPermissions, ...researcherIdentityPermissions]
        });
        await this._dynamicAuthorizationService.deleteIdentityPermissions(deleteIdentityPermissionsRequest);
        await this._idempotentGroupDeletion({
            authenticatedUser,
            groupId: paRole
        });
        await this._idempotentGroupDeletion({
            authenticatedUser,
            groupId: researcherRole
        });
    }
    /**
     * Performs an idempotent group deletion so that an error does not get thrown if group already doesn't exist.
     * @param request - DeleteGroupRequest
     */
    async _idempotentGroupDeletion(request) {
        try {
            await this._dynamicAuthorizationService.deleteGroup(request);
        }
        catch (e) {
            if (!(e instanceof workbench_core_authorization_1.GroupNotFoundError)) {
                throw e;
            }
            console.warn(`Group ${request.groupId} was not found.`);
        }
    }
    /**
     * Update the name or description of an existing project.
     *
     * @param request - a {@link UpdateProjectRequest} object that contains the id of the project to update
     *                  as well as the new field values
     * @returns a {@link Project} object that reflects the changes requested
     */
    async updateProject(request) {
        return this._projectService.updateProject(request);
    }
    _generatePAIdentityPermissions(projectId, paRole) {
        return [
            ...this._generateIdentityPermissions('*', "SWB_DATASET" /* SwbAuthZSubject.SWB_DATASET */, ['CREATE'], paRole, {
                projectId: { $eq: projectId }
            }),
            ...this._generateIdentityPermissions('*', "SWB_DATASET_LIST" /* SwbAuthZSubject.SWB_DATASET_LIST */, ['READ'], paRole, {
                projectId: { $eq: projectId }
            }),
            ...this._generateIdentityPermissions('*', "SWB_ENVIRONMENT" /* SwbAuthZSubject.SWB_ENVIRONMENT */, ['CREATE', 'READ'], paRole, {
                projectId: { $eq: projectId }
            }),
            ...this._generateIdentityPermissions('*', "SWB_ENVIRONMENT_TYPE" /* SwbAuthZSubject.SWB_ENVIRONMENT_TYPE */, ['READ'], paRole),
            ...this._generateIdentityPermissions('*', "SWB_ETC" /* SwbAuthZSubject.SWB_ETC */, ['READ'], paRole, {
                projectId: { $eq: projectId }
            }),
            // Adding a permission for ListProjects so that as soon as a Project Admin gets added to their first project
            // they can begin to call ListProjects
            ...this._generateIdentityPermissions('*', "SWB_PROJECT_LIST" /* SwbAuthZSubject.SWB_PROJECT_LIST */, ['READ'], paRole),
            // Access for GetProject and GetProjects
            ...this._generateIdentityPermissions(projectId, "SWB_PROJECT" /* SwbAuthZSubject.SWB_PROJECT */, ['READ', 'UPDATE', 'DELETE'], paRole),
            ...this._generateIdentityPermissions('*', "SWB_PROJECT_USER_ASSOCIATION" /* SwbAuthZSubject.SWB_PROJECT_USER_ASSOCIATION */, ['CREATE', 'READ', 'DELETE'], paRole, { projectId: { $eq: projectId } }),
            // Adding a permission for SSH Key
            ...this._generateIdentityPermissions('*', "SWB_SSH_KEY" /* SwbAuthZSubject.SWB_SSH_KEY */, ['CREATE', 'READ', 'DELETE'], paRole, {
                projectId: { $eq: projectId }
            }),
            // Adding a permission for ListUsers so that as soon as a Project Admin gets added to their first project
            // they can begin to call ListUsers and GetUser
            ...this._generateIdentityPermissions('*', "SWB_USER" /* SwbAuthZSubject.SWB_USER */, ['READ'], paRole)
        ];
    }
    _generateResearcherIdentityPermissions(projectId, researcherRole) {
        return [
            ...this._generateIdentityPermissions('*', "SWB_DATASET_LIST" /* SwbAuthZSubject.SWB_DATASET_LIST */, ['READ'], researcherRole, {
                projectId: { $eq: projectId }
            }),
            ...this._generateIdentityPermissions('*', "SWB_ENVIRONMENT" /* SwbAuthZSubject.SWB_ENVIRONMENT */, ['CREATE', 'READ'], researcherRole, { projectId: { $eq: projectId } }),
            ...this._generateIdentityPermissions('*', "SWB_ENVIRONMENT_TYPE" /* SwbAuthZSubject.SWB_ENVIRONMENT_TYPE */, ['READ'], researcherRole),
            ...this._generateIdentityPermissions('*', "SWB_ETC" /* SwbAuthZSubject.SWB_ETC */, ['READ'], researcherRole, {
                projectId: { $eq: projectId }
            }),
            // Adding a permission for ListProjects so that as soon as a Researcher gets added to their first project
            // they can begin to call ListProjects
            ...this._generateIdentityPermissions('*', "SWB_PROJECT_LIST" /* SwbAuthZSubject.SWB_PROJECT_LIST */, ['READ'], researcherRole),
            // Access for GetProject and GetProjects
            ...this._generateIdentityPermissions(projectId, "SWB_PROJECT" /* SwbAuthZSubject.SWB_PROJECT */, ['READ'], researcherRole),
            ...this._generateIdentityPermissions('*', "SWB_SSH_KEY" /* SwbAuthZSubject.SWB_SSH_KEY */, ['CREATE', 'READ', 'DELETE'], researcherRole, { projectId: { $eq: projectId } })
        ];
    }
    /***
     * Generates the default identity permissions for the project
     * @param projectId - the project the permissions are being generated for
     * @returns an array of Identity Permissions
     */
    _generateIdentityPermissions(subjectId, subjectType, actions, role, conditions) {
        let partialIdentityPermission = {
            effect: 'ALLOW',
            identityType: 'GROUP',
            subjectId: subjectId,
            subjectType: subjectType
        };
        if (conditions) {
            partialIdentityPermission = Object.assign(Object.assign({}, partialIdentityPermission), { conditions: conditions });
        }
        const identityPermissions = [];
        for (const action of actions) {
            const identityPermission = workbench_core_authorization_1.IdentityPermissionParser.parse(Object.assign(Object.assign({}, partialIdentityPermission), { identityId: role, action }));
            identityPermissions.push(identityPermission);
        }
        return identityPermissions;
    }
}
exports.SWBProjectService = SWBProjectService;
//# sourceMappingURL=swbProjectService.js.map