{"size": 6408, "ext": "js", "max_stars_repo_path": "dac-api/tenants/add.js", "max_stars_repo_name": "tommycwu/okta-dac", "max_stars_repo_stars_event_min_datetime": "2021-05-12T06:59:47.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-31T19:33:31.000Z", "max_issues_repo_path": "dac-api/tenants/add.js", "max_issues_repo_name": "tommycwu/okta-dac", "max_issues_repo_issues_event_min_datetime": "2020-08-06T17:58:01.000Z", "max_issues_repo_issues_event_max_datetime": "2021-04-29T22:09:16.000Z", "max_forks_repo_path": "dac-api/tenants/add.js", "max_forks_repo_name": "tommycwu/okta-dac", "max_forks_repo_forks_event_min_datetime": "2020-07-14T15:18:40.000Z", "max_forks_repo_forks_event_max_datetime": "2021-04-01T11:21:53.000Z"}
{"max_stars_count": 14, "max_issues_count": 8, "max_forks_count": 9, "avg_line_length": 34.2673796791, "max_line_length": 102, "alphanum_fraction": 0.4002808989}
'use strict';
const lib = require('../lib/index.js');
const appClientId = process.env.CLIENT_ID;


module.exports.handler = async (event, context) => {
    async function addGroup(name, tenantId) {
        try {
            const res = await lib.axios.post(
                lib.orgUrl + '/api/v1/groups', {
                    profile: {
                        name: name,
                        description: JSON.stringify({
                            tenantId: tenantId
                        })
                    }
                },
                lib.headers
            );
            return res;
        } catch (e) {
            throw e;
        }
    }
    
    async function addUserAdminRole(groupId) {
        try {
            const res = await lib.axios.post(lib.orgUrl + '/api/v1/groups/' + groupId + '/roles', {
                type: 'USER_ADMIN'
            }, lib.headers);
            return res;
        } catch (e) {
            throw e;
        }
    }
    
    async function assignGroupToApp(groupId, tenantId, tenantName, usersGroupId) {
        try {
            const res = await lib.axios.put(
                lib.orgUrl + '/api/v1/apps/' + appClientId + '/groups/' + groupId, {
                    profile: {
                        tenants: [
                            tenantId + ":" + tenantName + ':' + usersGroupId
                        ]
                    }
                },
                lib.headers
            );
            return res;
        } catch (e) {
            throw e;
        }
    }
    
    async function updateTenantJitGroupAndInactivate(id, groupId) {
        try {
            const res = await lib.axios.get(lib.orgUrl + '/api/v1/idps/' + id, lib.headers);
            let payload = res.data;
            delete payload._links;
            delete payload.id;
            delete payload.created;
            delete payload.lastUpdated;
            payload.policy.provisioning.groups.action = 'ASSIGN';
            payload.policy.provisioning.groups.assignments = [groupId];
            payload.status = 'INACTIVE';
            const res2 = await lib.axios.put(lib.orgUrl + '/api/v1/idps/' + id, payload, lib.headers);
            return res2;
        } catch (e) {
            console.log(e);
            throw e;
        }
    }
    
    async function addTenant(name) {
        if (!name || name.length <= 0) {
            throw lib.standardResponses.malformedRequest;
        }
    
        try {
            const res = await lib.getAdminsGroup(name, null);
            if (res.status == 200) {
                return {
                    status: 400,
                    data: {
                        message: 'tenant ' + name + ' already exists'
                    }
                };
            }
        } catch (e) {
            if (e.response.status != 404) {
                throw e;
            }
        }
    
        try {
            const kid = await lib.addKey([process.env.TEMPLATE_CERT]);
    
            const res = await lib.axios.post(
                lib.orgUrl + '/api/v1/idps', {
                    type: "SAML2",
                    name: lib.DAC_PREFIX + name,
                    status: "INACTIVE",
                    protocol: {
                        type: "SAML2",
                        endpoints: {
                            sso: {
                                url: "https://placeholder",
                                binding: "HTTP-POST",
                                destination: "https://template"
                            },
                            acs: {
                                binding: "HTTP-POST",
                                type: "INSTANCE"
                            }
                        },
                        algorithms: {},
                        credentials: {
                            trust: {
                                issuer: "placeholder",
                                kid: kid
                            }
                        }
                    },
                    policy: {
                        provisioning: {
                            action: "AUTO",
                            groups: {
                                action: "NONE"
                            }
                        },
                        subject: {
                            userNameTemplate: {
                                template: "idpuser.subjectNameId"
                            },
                            matchType: "USERNAME"
                        },
                        maxClockSkew: 120000
                    }
                },
                lib.headers
            );
            if (res.status == 200) {
                const allUsers = await addGroup('USERS_' + name, res.data.id);
                const admins = await addGroup('ADMINS_' + name, res.data.id);
                const role = await addUserAdminRole(admins.data.id);
                await lib.addGroupAdminTarget(admins.data.id, role.data.id, allUsers.data.id);
                await lib.addGroupAdminTarget(admins.data.id, role.data.id, admins.data.id);
                await assignGroupToApp(admins.data.id, res.data.id, name, allUsers.data.id);
                await updateTenantJitGroupAndInactivate(res.data.id, allUsers.data.id);
    
                return {
                    status: 201,
                    data: {
                        id: res.data.id,
                        ADMINS_groupId: admins.data.id,
                        USERS_groupId: allUsers.data.id,
                        ADMINS_roleId: role.data.id,
                        name: name,
                        created: res.data.created,
                        lastUpdated: res.data.lastUpdated
                    }
                };
            }
        } catch (e) {
            throw e;
        }
    }    


    const response = {
        isBase64Encoded: false,
        headers: {
            "Access-Control-Allow-Origin": "*"
        }
    };
    try {
        const requestBody = JSON.parse(event.body);
        const res = await addTenant(requestBody.name);
        response.statusCode = res.status;
        response.body = JSON.stringify(res.data);
    } catch (e) {
        console.log(e);
        response.statusCode = e.response.status;
        response.body = JSON.stringify(e.response.data);
    }
    return response;
};