import { Injectable } from "@nestjs/common"; import { PrismaService } from "../_prisma/prisma.service"; import { Prisma } from "@prisma/client"; import { IamPolicy } from "./iam-policy.entity"; import { IamRole } from "./iam-role.entity"; import { EntityAlreadyExists, NoSuchEntity, NotFoundException } from "../aws-shared-entities/aws-exceptions"; import { ArnUtil } from "../util/arn-util.static"; @Injectable() export class IamService { constructor( private readonly prismaService: PrismaService, ) {} async createRole(data: Prisma.IamRoleCreateInput): Promise { try { const record = await this.prismaService.iamRole.create({ data }); return new IamRole(record); } catch (err) { throw new EntityAlreadyExists(`RoleName ${data.name} already exists`); } } async findOneRoleByName(accountId: string, name: string): Promise { try { const record = await this.prismaService.iamRole.findFirstOrThrow({ where: { name, accountId, } }); return new IamRole(record); } catch (error) { throw new NotFoundException(); } } async deleteRoleByName(accountId: string, name: string) { await this.prismaService.iamRole.deleteMany({ where: { name, accountId, } }); } async listRolePolicies(): Promise { // return await this.prismaService; return []; } async getPolicyByArn(arn: string): Promise { try { const name = arn.split('/')[1]; const record = await this.prismaService.iamPolicy.findFirstOrThrow({ where: { name, }, orderBy: { version: 'desc', }, }); return new IamPolicy(record); } catch (err) { throw new NoSuchEntity(); } } async getPolicyByArnAndVersion(arn: string, version: number): Promise { try { const name = arn.split('/')[1]; const record = await this.prismaService.iamPolicy.findFirstOrThrow({ where: { name, version, } }); return new IamPolicy(record); } catch (err) { throw new NoSuchEntity(); } } async createPolicy(data: Prisma.IamPolicyCreateInput): Promise { try { const record = await this.prismaService.iamPolicy.create({ data }); return new IamPolicy(record); } catch (err) { throw new EntityAlreadyExists(`PolicyName ${data.name} already exists`); } } async attachPolicyToRoleName(accountId: string, arn: string, roleName: string) { const policy = await this.getPolicyByArn(arn); const role = await this.findOneRoleByName(accountId, roleName); await this.prismaService.iamRoleIamPolicyAttachment.create({ data: { iamPolicyId: policy.id, iamRoleId: role.id, } }); } async findAttachedRolePoliciesByRoleName(accountId: string, roleName: string): Promise { try { const record = await this.prismaService.iamRole.findFirstOrThrow({ where: { name: roleName, accountId, }, include: { policies: true, } }); const policyIds = record.policies.map(p => p.iamPolicyId); const policies = await this.prismaService.iamPolicy.findMany({ where: { id: { in: policyIds, }, isDefault: true, }}); return policies.map(p => new IamPolicy(p)); } catch (error) { throw new NotFoundException(); } } }