WIP
This commit is contained in:
parent
1dc45267ac
commit
da84b6b085
Binary file not shown.
|
|
@ -24,6 +24,39 @@ model Audit {
|
||||||
response String?
|
response String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model IamRole {
|
||||||
|
id String @id
|
||||||
|
path String?
|
||||||
|
name String
|
||||||
|
assumeRolePolicy String?
|
||||||
|
description String?
|
||||||
|
maxSessionDuration Int?
|
||||||
|
permissionBoundaryArn String?
|
||||||
|
lastUsedDate DateTime?
|
||||||
|
lastUsedRegion String?
|
||||||
|
accountId String
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
@@unique([accountId, name])
|
||||||
|
}
|
||||||
|
|
||||||
|
model IamPolicy {
|
||||||
|
id String
|
||||||
|
version Int @default(1)
|
||||||
|
isDefault Boolean
|
||||||
|
path String?
|
||||||
|
name String
|
||||||
|
description String?
|
||||||
|
policy String
|
||||||
|
isAttachable Boolean @default(false)
|
||||||
|
accountId String
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@id([id, version])
|
||||||
|
@@unique([accountId, path, name])
|
||||||
|
}
|
||||||
|
|
||||||
model KmsAlias {
|
model KmsAlias {
|
||||||
name String
|
name String
|
||||||
accountId String
|
accountId String
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ import { SqsModule } from './sqs/sqs.module';
|
||||||
import { PrismaModule } from './_prisma/prisma.module';
|
import { PrismaModule } from './_prisma/prisma.module';
|
||||||
import { StsModule } from './sts/sts.module';
|
import { StsModule } from './sts/sts.module';
|
||||||
import { StsHandlers } from './sts/sts.constants';
|
import { StsHandlers } from './sts/sts.constants';
|
||||||
|
import { IamModule } from './iam/iam.module';
|
||||||
|
import { IAMHandlers } from './iam/iam.constants';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -26,6 +28,7 @@ import { StsHandlers } from './sts/sts.constants';
|
||||||
}),
|
}),
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
AwsSharedEntitiesModule,
|
AwsSharedEntitiesModule,
|
||||||
|
IamModule,
|
||||||
KmsModule,
|
KmsModule,
|
||||||
SecretsManagerModule,
|
SecretsManagerModule,
|
||||||
SnsModule,
|
SnsModule,
|
||||||
|
|
@ -41,6 +44,7 @@ import { StsHandlers } from './sts/sts.constants';
|
||||||
provide: ActionHandlers,
|
provide: ActionHandlers,
|
||||||
useFactory: (...args) => args.reduce((m, hs) => ({ ...m, ...hs }), {}),
|
useFactory: (...args) => args.reduce((m, hs) => ({ ...m, ...hs }), {}),
|
||||||
inject: [
|
inject: [
|
||||||
|
IAMHandlers,
|
||||||
KMSHandlers,
|
KMSHandlers,
|
||||||
SecretsManagerHandlers,
|
SecretsManagerHandlers,
|
||||||
SnsHandlers,
|
SnsHandlers,
|
||||||
|
|
|
||||||
|
|
@ -162,4 +162,13 @@ export class UnsupportedOperationException extends AwsException {
|
||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.BAD_REQUEST,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class EntityAlreadyExists extends AwsException {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(
|
||||||
|
message,
|
||||||
|
EntityAlreadyExists.name,
|
||||||
|
HttpStatus.CONFLICT,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AttachRolePolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamAttachRolePolicy;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyArn: Joi.string().required(),
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyArn, RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { breakdownArn } from '../util/breakdown-arn';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
PolicyDocument: string;
|
||||||
|
SetAsDefault: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreatePolicyVersionHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamCreatePolicyVersion;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyArn: Joi.string().required(),
|
||||||
|
PolicyDocument: Joi.string().required(),
|
||||||
|
SetAsDefault: Joi.boolean().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyArn, PolicyDocument, SetAsDefault }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { IamService } from './iam.service';
|
||||||
|
import { TagsService } from '../aws-shared-entities/tags.service';
|
||||||
|
import { randomUUID } from 'crypto';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
Description: string;
|
||||||
|
Path: string;
|
||||||
|
PolicyDocument: string;
|
||||||
|
PolicyName: string;
|
||||||
|
} & Record<string, string>;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreatePolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly iamService: IamService,
|
||||||
|
private readonly tagsService: TagsService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamCreatePolicy;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
Description: Joi.string().max(1000).allow(null, '').default(null),
|
||||||
|
Path: Joi.string().min(1).max(512).default(null).regex(new RegExp(`((/[A-Za-z0-9\.,\+@=_-]+)*)/`)),
|
||||||
|
PolicyDocument: Joi.string().min(1).max(131072).required(),
|
||||||
|
PolicyName: Joi.string().min(1).max(128).required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle(params: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const { Description, Path, PolicyName, PolicyDocument } = params;
|
||||||
|
|
||||||
|
const policy = await this.iamService.createPolicy({
|
||||||
|
id: randomUUID(),
|
||||||
|
version: 1,
|
||||||
|
isDefault: true,
|
||||||
|
name: PolicyName,
|
||||||
|
path: Path,
|
||||||
|
description: Description,
|
||||||
|
policy: PolicyDocument,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
});
|
||||||
|
|
||||||
|
return policy.metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { IamService } from './iam.service';
|
||||||
|
import { randomUUID } from 'crypto';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
Path: string;
|
||||||
|
AssumeRolePolicyDocument: string;
|
||||||
|
MaxSessionDuration: number;
|
||||||
|
Description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreateRoleHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly iamService: IamService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamCreateRole;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
AssumeRolePolicyDocument: Joi.string().min(1).max(131072).required(),
|
||||||
|
Description: Joi.string().max(1000).allow(null, '').default(null),
|
||||||
|
MaxSessionDuration: Joi.number().min(3600).max(43200).default(3600),
|
||||||
|
Path: Joi.string().min(1).max(512).required(),
|
||||||
|
RoleName: Joi.string().min(1).max(64).required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName, Path, AssumeRolePolicyDocument, MaxSessionDuration, Description }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const role = await this.iamService.createRole({
|
||||||
|
id: randomUUID(),
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
name: RoleName,
|
||||||
|
path: Path,
|
||||||
|
assumeRolePolicy: AssumeRolePolicyDocument,
|
||||||
|
maxSessionDuration: MaxSessionDuration,
|
||||||
|
description: Description,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
Role: role.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { IamService } from './iam.service';
|
||||||
|
import { NotFoundException } from '../aws-shared-entities/aws-exceptions';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DeleteRoleHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly iamService: IamService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamDeleteRole;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().min(1).max(64).required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
await this.iamService.deleteRoleByName(awsProperties.accountId, RoleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
VersionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetPolicyVersionHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamGetPolicyVersion;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyArn: Joi.string().required(),
|
||||||
|
VersionId: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyArn, VersionId }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetPolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamGetPolicy;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyArn: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyArn }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { IamService } from './iam.service';
|
||||||
|
import { NotFoundException } from '../aws-shared-entities/aws-exceptions';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetRoleHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly iamService: IamService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamGetRole;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().min(1).max(64).required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const role = await this.iamService.findOneRoleByName(awsProperties.accountId, RoleName);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
Role: role.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { IamPolicy as PrismaIamPolicy } from "@prisma/client";
|
||||||
|
|
||||||
|
export class IamPolicy implements PrismaIamPolicy {
|
||||||
|
|
||||||
|
id: string;
|
||||||
|
accountId: string;
|
||||||
|
name: string;
|
||||||
|
version: number;
|
||||||
|
isDefault: boolean;
|
||||||
|
policy: string;
|
||||||
|
path: string | null;
|
||||||
|
description: string | null;
|
||||||
|
isAttachable: boolean;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
|
||||||
|
constructor(p: PrismaIamPolicy) {
|
||||||
|
this.id = p.id;
|
||||||
|
this.accountId = p.accountId;
|
||||||
|
this.name = p.name;
|
||||||
|
this.version = p.version;
|
||||||
|
this.isDefault = p.isDefault;
|
||||||
|
this.policy = p.policy;
|
||||||
|
this.path = p.path;
|
||||||
|
this.description = p.description;
|
||||||
|
this.isAttachable = p.isAttachable;
|
||||||
|
this.createdAt = p.createdAt;
|
||||||
|
this.updatedAt = p.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
const parts = ['policy'];
|
||||||
|
if (this.path && this.path !== '/') {
|
||||||
|
parts.push(this.path);
|
||||||
|
}
|
||||||
|
parts.push(this.name);
|
||||||
|
return `arn:aws:iam::${this.accountId}:${parts.join('/')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get metadata() {
|
||||||
|
return {
|
||||||
|
Arn: this.arn,
|
||||||
|
AttachmentCount: 0,
|
||||||
|
CreateDate: this.createdAt.toISOString(),
|
||||||
|
DefaultVersionId: `v${this.version}`,
|
||||||
|
Description: this.description,
|
||||||
|
IsAttachable: this.isAttachable,
|
||||||
|
Path: this.path,
|
||||||
|
PolicyId: this.id,
|
||||||
|
PolicyName: this.name,
|
||||||
|
UpdateDate: this.updatedAt.toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
import { IamRole as PrismaIamRole } from '@prisma/client';
|
||||||
|
|
||||||
|
export class IamRole implements PrismaIamRole {
|
||||||
|
|
||||||
|
accountId: string;
|
||||||
|
path: string | null;
|
||||||
|
name: string;
|
||||||
|
createdAt: Date;
|
||||||
|
id: string;
|
||||||
|
maxSessionDuration: number | null;
|
||||||
|
assumeRolePolicy: string | null;
|
||||||
|
description: string | null;
|
||||||
|
permissionBoundaryArn: string | null;
|
||||||
|
lastUsedDate: Date | null;
|
||||||
|
lastUsedRegion: string | null;
|
||||||
|
|
||||||
|
constructor(p: PrismaIamRole) {
|
||||||
|
this.accountId = p.accountId;
|
||||||
|
this.path = p.path;
|
||||||
|
this.name = p.name;
|
||||||
|
this.createdAt = p.createdAt;
|
||||||
|
this.id = p.id;
|
||||||
|
this.maxSessionDuration = p.maxSessionDuration;
|
||||||
|
this.assumeRolePolicy = p.assumeRolePolicy;
|
||||||
|
this.description = p.description;
|
||||||
|
this.permissionBoundaryArn = p.permissionBoundaryArn;
|
||||||
|
this.lastUsedDate = p.lastUsedDate;
|
||||||
|
this.lastUsedRegion = p.lastUsedRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
const parts = ['role'];
|
||||||
|
if (this.path && this.path !== '/') {
|
||||||
|
parts.push(this.path);
|
||||||
|
}
|
||||||
|
parts.push(this.name);
|
||||||
|
return `arn:aws:iam::${this.accountId}:${parts.join('/')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get metadata() {
|
||||||
|
return {
|
||||||
|
Path: this.path,
|
||||||
|
Arn: this.arn,
|
||||||
|
RoleName: this.name,
|
||||||
|
AssumeRolePolicyDocument: this.assumeRolePolicy,
|
||||||
|
CreateDate: this.createdAt.toISOString(),
|
||||||
|
RoleId: this.id,
|
||||||
|
MaxSessionDuration: this.maxSessionDuration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { AbstractActionHandler } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
|
||||||
|
export type IAMHandlers = Record<Action, AbstractActionHandler>;
|
||||||
|
export const IAMHandlers = Symbol.for('IAMHandlers');
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import { AwsSharedEntitiesModule } from '../aws-shared-entities/aws-shared-entities.module';
|
||||||
|
import { DefaultActionHandlerProvider } from '../default-action-handler/default-action-handler.provider';
|
||||||
|
import { ExistingActionHandlersProvider } from '../default-action-handler/existing-action-handlers.provider';
|
||||||
|
import { CreatePolicyHandler } from './create-policy.handler';
|
||||||
|
import { CreateRoleHandler } from './create-role.handler';
|
||||||
|
import { IAMHandlers } from './iam.constants';
|
||||||
|
import { PrismaModule } from '../_prisma/prisma.module';
|
||||||
|
import { IamService } from './iam.service';
|
||||||
|
import { GetRoleHandler } from './get-role.handler';
|
||||||
|
|
||||||
|
const handlers = [
|
||||||
|
CreatePolicyHandler,
|
||||||
|
CreateRoleHandler,
|
||||||
|
GetRoleHandler,
|
||||||
|
]
|
||||||
|
|
||||||
|
const actions = [
|
||||||
|
Action.IamAddClientIDToOpenIDConnectProvider,
|
||||||
|
Action.IamAddRoleToInstanceProfile,
|
||||||
|
Action.IamAddUserToGroup,
|
||||||
|
Action.IamAttachGroupPolicy,
|
||||||
|
Action.IamAttachRolePolicy,
|
||||||
|
Action.IamAttachUserPolicy,
|
||||||
|
Action.IamChangePassword,
|
||||||
|
Action.IamCreateAccessKey,
|
||||||
|
Action.IamCreateAccountAlias,
|
||||||
|
Action.IamCreateGroup,
|
||||||
|
Action.IamCreateInstanceProfile,
|
||||||
|
Action.IamCreateLoginProfile,
|
||||||
|
Action.IamCreateOpenIDConnectProvider,
|
||||||
|
Action.IamCreatePolicy,
|
||||||
|
Action.IamCreatePolicyVersion,
|
||||||
|
Action.IamCreateRole,
|
||||||
|
Action.IamCreateSAMLProvider,
|
||||||
|
Action.IamCreateServiceLinkedRole,
|
||||||
|
Action.IamCreateServiceSpecificCredential,
|
||||||
|
Action.IamCreateUser,
|
||||||
|
Action.IamCreateVirtualMFADevice,
|
||||||
|
Action.IamDeactivateMFADevice,
|
||||||
|
Action.IamDeleteAccessKey,
|
||||||
|
Action.IamDeleteAccountAlias,
|
||||||
|
Action.IamDeleteAccountPasswordPolicy,
|
||||||
|
Action.IamDeleteGroup,
|
||||||
|
Action.IamDeleteGroupPolicy,
|
||||||
|
Action.IamDeleteInstanceProfile,
|
||||||
|
Action.IamDeleteLoginProfile,
|
||||||
|
Action.IamDeleteOpenIDConnectProvider,
|
||||||
|
Action.IamDeletePolicy,
|
||||||
|
Action.IamDeletePolicyVersion,
|
||||||
|
Action.IamDeleteRole,
|
||||||
|
Action.IamDeleteRolePermissionsBoundary,
|
||||||
|
Action.IamDeleteRolePolicy,
|
||||||
|
Action.IamDeleteSAMLProvider,
|
||||||
|
Action.IamDeleteServerCertificate,
|
||||||
|
Action.IamDeleteServiceLinkedRole,
|
||||||
|
Action.IamDeleteServiceSpecificCredential,
|
||||||
|
Action.IamDeleteSigningCertificate,
|
||||||
|
Action.IamDeleteSSHPublicKey,
|
||||||
|
Action.IamDeleteUser,
|
||||||
|
Action.IamDeleteUserPermissionsBoundary,
|
||||||
|
Action.IamDeleteUserPolicy,
|
||||||
|
Action.IamDeleteVirtualMFADevice,
|
||||||
|
Action.IamDetachGroupPolicy,
|
||||||
|
Action.IamDetachRolePolicy,
|
||||||
|
Action.IamDetachUserPolicy,
|
||||||
|
Action.IamEnableMFADevice,
|
||||||
|
Action.IamGenerateCredentialReport,
|
||||||
|
Action.IamGenerateOrganizationsAccessReport,
|
||||||
|
Action.IamGenerateServiceLastAccessedDetails,
|
||||||
|
Action.IamGetAccessKeyLastUsed,
|
||||||
|
Action.IamGetAccountAuthorizationDetails,
|
||||||
|
Action.IamGetAccountPasswordPolicy,
|
||||||
|
Action.IamGetAccountSummary,
|
||||||
|
Action.IamGetContextKeysForCustomPolicy,
|
||||||
|
Action.IamGetContextKeysForPrincipalPolicy,
|
||||||
|
Action.IamGetCredentialReport,
|
||||||
|
Action.IamGetGroup,
|
||||||
|
Action.IamGetGroupPolicy,
|
||||||
|
Action.IamGetInstanceProfile,
|
||||||
|
Action.IamGetLoginProfile,
|
||||||
|
Action.IamGetOpenIDConnectProvider,
|
||||||
|
Action.IamGetOrganizationsAccessReport,
|
||||||
|
Action.IamGetPolicy,
|
||||||
|
Action.IamGetPolicyVersion,
|
||||||
|
Action.IamGetRole,
|
||||||
|
Action.IamGetRolePolicy,
|
||||||
|
Action.IamGetSAMLProvider,
|
||||||
|
Action.IamGetServerCertificate,
|
||||||
|
Action.IamGetServiceLastAccessedDetails,
|
||||||
|
Action.IamGetServiceLastAccessedDetailsWithEntities,
|
||||||
|
Action.IamGetServiceLinkedRoleDeletionStatus,
|
||||||
|
Action.IamGetSSHPublicKey,
|
||||||
|
Action.IamGetUser,
|
||||||
|
Action.IamGetUserPolicy,
|
||||||
|
Action.IamListAccessKeys,
|
||||||
|
Action.IamListAccountAliases,
|
||||||
|
Action.IamListAttachedGroupPolicies,
|
||||||
|
Action.IamListAttachedRolePolicies,
|
||||||
|
Action.IamListAttachedUserPolicies,
|
||||||
|
Action.IamListEntitiesForPolicy,
|
||||||
|
Action.IamListGroupPolicies,
|
||||||
|
Action.IamListGroups,
|
||||||
|
Action.IamListGroupsForUser,
|
||||||
|
Action.IamListInstanceProfiles,
|
||||||
|
Action.IamListInstanceProfilesForRole,
|
||||||
|
Action.IamListInstanceProfileTags,
|
||||||
|
Action.IamListMFADevices,
|
||||||
|
Action.IamListMFADeviceTags,
|
||||||
|
Action.IamListOpenIDConnectProviders,
|
||||||
|
Action.IamListOpenIDConnectProviderTags,
|
||||||
|
Action.IamListPolicies,
|
||||||
|
Action.IamListPoliciesGrantingServiceAccess,
|
||||||
|
Action.IamListPolicyTags,
|
||||||
|
Action.IamListPolicyVersions,
|
||||||
|
Action.IamListRolePolicies,
|
||||||
|
Action.IamListRoles,
|
||||||
|
Action.IamListRoleTags,
|
||||||
|
Action.IamListSAMLProviders,
|
||||||
|
Action.IamListSAMLProviderTags,
|
||||||
|
Action.IamListServerCertificates,
|
||||||
|
Action.IamListServerCertificateTags,
|
||||||
|
Action.IamListServiceSpecificCredentials,
|
||||||
|
Action.IamListSigningCertificates,
|
||||||
|
Action.IamListSSHPublicKeys,
|
||||||
|
Action.IamListUserPolicies,
|
||||||
|
Action.IamListUsers,
|
||||||
|
Action.IamListUserTags,
|
||||||
|
Action.IamListVirtualMFADevices,
|
||||||
|
Action.IamPutGroupPolicy,
|
||||||
|
Action.IamPutRolePermissionsBoundary,
|
||||||
|
Action.IamPutRolePolicy,
|
||||||
|
Action.IamPutUserPermissionsBoundary,
|
||||||
|
Action.IamPutUserPolicy,
|
||||||
|
Action.IamRemoveClientIDFromOpenIDConnectProvider,
|
||||||
|
Action.IamRemoveRoleFromInstanceProfile,
|
||||||
|
Action.IamRemoveUserFromGroup,
|
||||||
|
Action.IamResetServiceSpecificCredential,
|
||||||
|
Action.IamResyncMFADevice,
|
||||||
|
Action.IamSetDefaultPolicyVersion,
|
||||||
|
Action.IamSetSecurityTokenServicePreferences,
|
||||||
|
Action.IamSimulateCustomPolicy,
|
||||||
|
Action.IamSimulatePrincipalPolicy,
|
||||||
|
Action.IamTagInstanceProfile,
|
||||||
|
Action.IamTagMFADevice,
|
||||||
|
Action.IamTagOpenIDConnectProvider,
|
||||||
|
Action.IamTagPolicy,
|
||||||
|
Action.IamTagRole,
|
||||||
|
Action.IamTagSAMLProvider,
|
||||||
|
Action.IamTagServerCertificate,
|
||||||
|
Action.IamTagUser,
|
||||||
|
Action.IamUntagInstanceProfile,
|
||||||
|
Action.IamUntagMFADevice,
|
||||||
|
Action.IamUntagOpenIDConnectProvider,
|
||||||
|
Action.IamUntagPolicy,
|
||||||
|
Action.IamUntagRole,
|
||||||
|
Action.IamUntagSAMLProvider,
|
||||||
|
Action.IamUntagServerCertificate,
|
||||||
|
Action.IamUntagUser,
|
||||||
|
Action.IamUpdateAccessKey,
|
||||||
|
Action.IamUpdateAccountPasswordPolicy,
|
||||||
|
Action.IamUpdateAssumeRolePolicy,
|
||||||
|
Action.IamUpdateGroup,
|
||||||
|
Action.IamUpdateLoginProfile,
|
||||||
|
Action.IamUpdateOpenIDConnectProviderThumbprint,
|
||||||
|
Action.IamUpdateRole,
|
||||||
|
Action.IamUpdateRoleDescription,
|
||||||
|
Action.IamUpdateSAMLProvider,
|
||||||
|
Action.IamUpdateServerCertificate,
|
||||||
|
Action.IamUpdateServiceSpecificCredential,
|
||||||
|
Action.IamUpdateSigningCertificate,
|
||||||
|
Action.IamUpdateSSHPublicKey,
|
||||||
|
Action.IamUpdateUser,
|
||||||
|
Action.IamUploadServerCertificate,
|
||||||
|
Action.IamUploadSigningCertificate,
|
||||||
|
Action.IamUploadSSHPublicKey,
|
||||||
|
]
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
AwsSharedEntitiesModule,
|
||||||
|
PrismaModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
...handlers,
|
||||||
|
IamService,
|
||||||
|
ExistingActionHandlersProvider(handlers),
|
||||||
|
DefaultActionHandlerProvider(IAMHandlers, Format.Xml, actions),
|
||||||
|
],
|
||||||
|
exports: [IAMHandlers],
|
||||||
|
})
|
||||||
|
export class IamModule {}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
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 } from "../aws-shared-entities/aws-exceptions";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class IamService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly prismaService: PrismaService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createRole(data: Prisma.IamRoleCreateInput): Promise<IamRole> {
|
||||||
|
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<IamRole | null> {
|
||||||
|
const record = await this.prismaService.iamRole.findFirst({
|
||||||
|
where: {
|
||||||
|
name,
|
||||||
|
accountId,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return record ? new IamRole(record) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteRoleByName(accountId: string, name: string) {
|
||||||
|
await this.prismaService.iamRole.deleteMany({
|
||||||
|
where: {
|
||||||
|
name,
|
||||||
|
accountId,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createPolicy(data: Prisma.IamPolicyCreateInput): Promise<IamPolicy> {
|
||||||
|
const record = await this.prismaService.iamPolicy.create({ data });
|
||||||
|
return new IamPolicy(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ListAttachedRolePoliciesHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamListAttachedRolePolicies;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
Marker: string;
|
||||||
|
MaxItems: number;
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ListRolePoliciesHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamListRolePolicies;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
Marker: Joi.string().allow(null),
|
||||||
|
MaxItems: Joi.number().min(1).max(1000).default(100),
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue