Added IAM support
This commit is contained in:
parent
2c78be1b3f
commit
29d36a57d6
|
|
@ -1,56 +1,216 @@
|
||||||
export enum Action {
|
export enum Action {
|
||||||
|
|
||||||
|
// IAM
|
||||||
|
IamAddClientIDToOpenIDConnectProvider = 'AddClientIDToOpenIDConnectProvider',
|
||||||
|
IamAddRoleToInstanceProfile = 'AddRoleToInstanceProfile',
|
||||||
|
IamAddUserToGroup = 'AddUserToGroup',
|
||||||
|
IamAttachGroupPolicy = 'AttachGroupPolicy',
|
||||||
|
IamAttachRolePolicy = 'AttachRolePolicy',
|
||||||
|
IamAttachUserPolicy = 'AttachUserPolicy',
|
||||||
|
IamChangePassword = 'ChangePassword',
|
||||||
|
IamCreateAccessKey = 'CreateAccessKey',
|
||||||
|
IamCreateAccountAlias = 'CreateAccountAlias',
|
||||||
|
IamCreateGroup = 'CreateGroup',
|
||||||
|
IamCreateInstanceProfile = 'CreateInstanceProfile',
|
||||||
|
IamCreateLoginProfile = 'CreateLoginProfile',
|
||||||
|
IamCreateOpenIDConnectProvider = 'CreateOpenIDConnectProvider',
|
||||||
|
IamCreatePolicy = 'CreatePolicy',
|
||||||
|
IamCreatePolicyVersion = 'CreatePolicyVersion',
|
||||||
|
IamCreateRole = 'CreateRole',
|
||||||
|
IamCreateSAMLProvider = 'CreateSAMLProvider',
|
||||||
|
IamCreateServiceLinkedRole = 'CreateServiceLinkedRole',
|
||||||
|
IamCreateServiceSpecificCredential = 'CreateServiceSpecificCredential',
|
||||||
|
IamCreateUser = 'CreateUser',
|
||||||
|
IamCreateVirtualMFADevice = 'CreateVirtualMFADevice',
|
||||||
|
IamDeactivateMFADevice = 'DeactivateMFADevice',
|
||||||
|
IamDeleteAccessKey = 'DeleteAccessKey',
|
||||||
|
IamDeleteAccountAlias = 'DeleteAccountAlias',
|
||||||
|
IamDeleteAccountPasswordPolicy = 'DeleteAccountPasswordPolicy',
|
||||||
|
IamDeleteGroup = 'DeleteGroup',
|
||||||
|
IamDeleteGroupPolicy = 'DeleteGroupPolicy',
|
||||||
|
IamDeleteInstanceProfile = 'DeleteInstanceProfile',
|
||||||
|
IamDeleteLoginProfile = 'DeleteLoginProfile',
|
||||||
|
IamDeleteOpenIDConnectProvider = 'DeleteOpenIDConnectProvider',
|
||||||
|
IamDeletePolicy = 'DeletePolicy',
|
||||||
|
IamDeletePolicyVersion = 'DeletePolicyVersion',
|
||||||
|
IamDeleteRole = 'DeleteRole',
|
||||||
|
IamDeleteRolePermissionsBoundary = 'DeleteRolePermissionsBoundary',
|
||||||
|
IamDeleteRolePolicy = 'DeleteRolePolicy',
|
||||||
|
IamDeleteSAMLProvider = 'DeleteSAMLProvider',
|
||||||
|
IamDeleteServerCertificate = 'DeleteServerCertificate',
|
||||||
|
IamDeleteServiceLinkedRole = 'DeleteServiceLinkedRole',
|
||||||
|
IamDeleteServiceSpecificCredential = 'DeleteServiceSpecificCredential',
|
||||||
|
IamDeleteSigningCertificate = 'DeleteSigningCertificate',
|
||||||
|
IamDeleteSSHPublicKey = 'DeleteSSHPublicKey',
|
||||||
|
IamDeleteUser = 'DeleteUser',
|
||||||
|
IamDeleteUserPermissionsBoundary = 'DeleteUserPermissionsBoundary',
|
||||||
|
IamDeleteUserPolicy = 'DeleteUserPolicy',
|
||||||
|
IamDeleteVirtualMFADevice = 'DeleteVirtualMFADevice',
|
||||||
|
IamDetachGroupPolicy = 'DetachGroupPolicy',
|
||||||
|
IamDetachRolePolicy = 'DetachRolePolicy',
|
||||||
|
IamDetachUserPolicy = 'DetachUserPolicy',
|
||||||
|
IamEnableMFADevice = 'EnableMFADevice',
|
||||||
|
IamGenerateCredentialReport = 'GenerateCredentialReport',
|
||||||
|
IamGenerateOrganizationsAccessReport = 'GenerateOrganizationsAccessReport',
|
||||||
|
IamGenerateServiceLastAccessedDetails = 'GenerateServiceLastAccessedDetails',
|
||||||
|
IamGetAccessKeyLastUsed = 'GetAccessKeyLastUsed',
|
||||||
|
IamGetAccountAuthorizationDetails = 'GetAccountAuthorizationDetails',
|
||||||
|
IamGetAccountPasswordPolicy = 'GetAccountPasswordPolicy',
|
||||||
|
IamGetAccountSummary = 'GetAccountSummary',
|
||||||
|
IamGetContextKeysForCustomPolicy = 'GetContextKeysForCustomPolicy',
|
||||||
|
IamGetContextKeysForPrincipalPolicy = 'GetContextKeysForPrincipalPolicy',
|
||||||
|
IamGetCredentialReport = 'GetCredentialReport',
|
||||||
|
IamGetGroup = 'GetGroup',
|
||||||
|
IamGetGroupPolicy = 'GetGroupPolicy',
|
||||||
|
IamGetInstanceProfile = 'GetInstanceProfile',
|
||||||
|
IamGetLoginProfile = 'GetLoginProfile',
|
||||||
|
IamGetOpenIDConnectProvider = 'GetOpenIDConnectProvider',
|
||||||
|
IamGetOrganizationsAccessReport = 'GetOrganizationsAccessReport',
|
||||||
|
IamGetPolicy = 'GetPolicy',
|
||||||
|
IamGetPolicyVersion = 'GetPolicyVersion',
|
||||||
|
IamGetRole = 'GetRole',
|
||||||
|
IamGetRolePolicy = 'GetRolePolicy',
|
||||||
|
IamGetSAMLProvider = 'GetSAMLProvider',
|
||||||
|
IamGetServerCertificate = 'GetServerCertificate',
|
||||||
|
IamGetServiceLastAccessedDetails = 'GetServiceLastAccessedDetails',
|
||||||
|
IamGetServiceLastAccessedDetailsWithEntities = 'GetServiceLastAccessedDetailsWithEntities',
|
||||||
|
IamGetServiceLinkedRoleDeletionStatus = 'GetServiceLinkedRoleDeletionStatus',
|
||||||
|
IamGetSSHPublicKey = 'GetSSHPublicKey',
|
||||||
|
IamGetUser = 'GetUser',
|
||||||
|
IamGetUserPolicy = 'GetUserPolicy',
|
||||||
|
IamListAccessKeys = 'ListAccessKeys',
|
||||||
|
IamListAccountAliases = 'ListAccountAliases',
|
||||||
|
IamListAttachedGroupPolicies = 'ListAttachedGroupPolicies',
|
||||||
|
IamListAttachedRolePolicies = 'ListAttachedRolePolicies',
|
||||||
|
IamListAttachedUserPolicies = 'ListAttachedUserPolicies',
|
||||||
|
IamListEntitiesForPolicy = 'ListEntitiesForPolicy',
|
||||||
|
IamListGroupPolicies = 'ListGroupPolicies',
|
||||||
|
IamListGroups = 'ListGroups',
|
||||||
|
IamListGroupsForUser = 'ListGroupsForUser',
|
||||||
|
IamListInstanceProfiles = 'ListInstanceProfiles',
|
||||||
|
IamListInstanceProfilesForRole = 'ListInstanceProfilesForRole',
|
||||||
|
IamListInstanceProfileTags = 'ListInstanceProfileTags',
|
||||||
|
IamListMFADevices = 'ListMFADevices',
|
||||||
|
IamListMFADeviceTags = 'ListMFADeviceTags',
|
||||||
|
IamListOpenIDConnectProviders = 'ListOpenIDConnectProviders',
|
||||||
|
IamListOpenIDConnectProviderTags = 'ListOpenIDConnectProviderTags',
|
||||||
|
IamListPolicies = 'ListPolicies',
|
||||||
|
IamListPoliciesGrantingServiceAccess = 'ListPoliciesGrantingServiceAccess',
|
||||||
|
IamListPolicyTags = 'ListPolicyTags',
|
||||||
|
IamListPolicyVersions = 'ListPolicyVersions',
|
||||||
|
IamListRolePolicies = 'ListRolePolicies',
|
||||||
|
IamListRoles = 'ListRoles',
|
||||||
|
IamListRoleTags = 'ListRoleTags',
|
||||||
|
IamListSAMLProviders = 'ListSAMLProviders',
|
||||||
|
IamListSAMLProviderTags = 'ListSAMLProviderTags',
|
||||||
|
IamListServerCertificates = 'ListServerCertificates',
|
||||||
|
IamListServerCertificateTags = 'ListServerCertificateTags',
|
||||||
|
IamListServiceSpecificCredentials = 'ListServiceSpecificCredentials',
|
||||||
|
IamListSigningCertificates = 'ListSigningCertificates',
|
||||||
|
IamListSSHPublicKeys = 'ListSSHPublicKeys',
|
||||||
|
IamListUserPolicies = 'ListUserPolicies',
|
||||||
|
IamListUsers = 'ListUsers',
|
||||||
|
IamListUserTags = 'ListUserTags',
|
||||||
|
IamListVirtualMFADevices = 'ListVirtualMFADevices',
|
||||||
|
IamPutGroupPolicy = 'PutGroupPolicy',
|
||||||
|
IamPutRolePermissionsBoundary = 'PutRolePermissionsBoundary',
|
||||||
|
IamPutRolePolicy = 'PutRolePolicy',
|
||||||
|
IamPutUserPermissionsBoundary = 'PutUserPermissionsBoundary',
|
||||||
|
IamPutUserPolicy = 'PutUserPolicy',
|
||||||
|
IamRemoveClientIDFromOpenIDConnectProvider = 'RemoveClientIDFromOpenIDConnectProvider',
|
||||||
|
IamRemoveRoleFromInstanceProfile = 'RemoveRoleFromInstanceProfile',
|
||||||
|
IamRemoveUserFromGroup = 'RemoveUserFromGroup',
|
||||||
|
IamResetServiceSpecificCredential = 'ResetServiceSpecificCredential',
|
||||||
|
IamResyncMFADevice = 'ResyncMFADevice',
|
||||||
|
IamSetDefaultPolicyVersion = 'SetDefaultPolicyVersion',
|
||||||
|
IamSetSecurityTokenServicePreferences = 'SetSecurityTokenServicePreferences',
|
||||||
|
IamSimulateCustomPolicy = 'SimulateCustomPolicy',
|
||||||
|
IamSimulatePrincipalPolicy = 'SimulatePrincipalPolicy',
|
||||||
|
IamTagInstanceProfile = 'TagInstanceProfile',
|
||||||
|
IamTagMFADevice = 'TagMFADevice',
|
||||||
|
IamTagOpenIDConnectProvider = 'TagOpenIDConnectProvider',
|
||||||
|
IamTagPolicy = 'TagPolicy',
|
||||||
|
IamTagRole = 'TagRole',
|
||||||
|
IamTagSAMLProvider = 'TagSAMLProvider',
|
||||||
|
IamTagServerCertificate = 'TagServerCertificate',
|
||||||
|
IamTagUser = 'TagUser',
|
||||||
|
IamUntagInstanceProfile = 'UntagInstanceProfile',
|
||||||
|
IamUntagMFADevice = 'UntagMFADevice',
|
||||||
|
IamUntagOpenIDConnectProvider = 'UntagOpenIDConnectProvider',
|
||||||
|
IamUntagPolicy = 'UntagPolicy',
|
||||||
|
IamUntagRole = 'UntagRole',
|
||||||
|
IamUntagSAMLProvider = 'UntagSAMLProvider',
|
||||||
|
IamUntagServerCertificate = 'UntagServerCertificate',
|
||||||
|
IamUntagUser = 'UntagUser',
|
||||||
|
IamUpdateAccessKey = 'UpdateAccessKey',
|
||||||
|
IamUpdateAccountPasswordPolicy = 'UpdateAccountPasswordPolicy',
|
||||||
|
IamUpdateAssumeRolePolicy = 'UpdateAssumeRolePolicy',
|
||||||
|
IamUpdateGroup = 'UpdateGroup',
|
||||||
|
IamUpdateLoginProfile = 'UpdateLoginProfile',
|
||||||
|
IamUpdateOpenIDConnectProviderThumbprint = 'UpdateOpenIDConnectProviderThumbprint',
|
||||||
|
IamUpdateRole = 'UpdateRole',
|
||||||
|
IamUpdateRoleDescription = 'UpdateRoleDescription',
|
||||||
|
IamUpdateSAMLProvider = 'UpdateSAMLProvider',
|
||||||
|
IamUpdateServerCertificate = 'UpdateServerCertificate',
|
||||||
|
IamUpdateServiceSpecificCredential = 'UpdateServiceSpecificCredential',
|
||||||
|
IamUpdateSigningCertificate = 'UpdateSigningCertificate',
|
||||||
|
IamUpdateSSHPublicKey = 'UpdateSSHPublicKey',
|
||||||
|
IamUpdateUser = 'UpdateUser',
|
||||||
|
IamUploadServerCertificate = 'UploadServerCertificate',
|
||||||
|
IamUploadSigningCertificate = 'UploadSigningCertificate',
|
||||||
|
IamUploadSSHPublicKey = 'UploadSSHPublicKey',
|
||||||
|
|
||||||
// KMS
|
// KMS
|
||||||
KmsCancelKeyDeletion = 'CancelKeyDeletion',
|
KmsCancelKeyDeletion = 'TrentService.CancelKeyDeletion',
|
||||||
KmsConnectCustomKeyStore = 'ConnectCustomKeyStore',
|
KmsConnectCustomKeyStore = 'TrentService.ConnectCustomKeyStore',
|
||||||
KmsCreateAlias = 'CreateAlias',
|
KmsCreateAlias = 'TrentService.CreateAlias',
|
||||||
KmsCreateCustomKeyStore = 'CreateCustomKeyStore',
|
KmsCreateCustomKeyStore = 'TrentService.CreateCustomKeyStore',
|
||||||
KmsCreateGrant = 'CreateGrant',
|
KmsCreateGrant = 'TrentService.CreateGrant',
|
||||||
KmsCreateKey = 'CreateKey',
|
KmsCreateKey = 'TrentService.CreateKey',
|
||||||
KmsDecrypt = 'Decrypt',
|
KmsDecrypt = 'TrentService.Decrypt',
|
||||||
KmsDeleteAlias = 'DeleteAlias',
|
KmsDeleteAlias = 'TrentService.DeleteAlias',
|
||||||
KmsDeleteCustomKeyStore = 'DeleteCustomKeyStore',
|
KmsDeleteCustomKeyStore = 'TrentService.DeleteCustomKeyStore',
|
||||||
KmsDeleteImportedKeyMaterial = 'DeleteImportedKeyMaterial',
|
KmsDeleteImportedKeyMaterial = 'TrentService.DeleteImportedKeyMaterial',
|
||||||
KmsDescribeCustomKeyStores = 'DescribeCustomKeyStores',
|
KmsDescribeCustomKeyStores = 'TrentService.DescribeCustomKeyStores',
|
||||||
KmsDescribeKey = 'DescribeKey',
|
KmsDescribeKey = 'TrentService.DescribeKey',
|
||||||
KmsDisableKey = 'DisableKey',
|
KmsDisableKey = 'TrentService.DisableKey',
|
||||||
KmsDisableKeyRotation = 'DisableKeyRotation',
|
KmsDisableKeyRotation = 'TrentService.DisableKeyRotation',
|
||||||
KmsDisconnectCustomKeyStore = 'DisconnectCustomKeyStore',
|
KmsDisconnectCustomKeyStore = 'TrentService.DisconnectCustomKeyStore',
|
||||||
KmsEnableKey = 'EnableKey',
|
KmsEnableKey = 'TrentService.EnableKey',
|
||||||
KmsEnableKeyRotation = 'EnableKeyRotation',
|
KmsEnableKeyRotation = 'TrentService.EnableKeyRotation',
|
||||||
KmsEncrypt = 'Encrypt',
|
KmsEncrypt = 'TrentService.Encrypt',
|
||||||
KmsGenerateDataKey = 'GenerateDataKey',
|
KmsGenerateDataKey = 'TrentService.GenerateDataKey',
|
||||||
KmsGenerateDataKeyPair = 'GenerateDataKeyPair',
|
KmsGenerateDataKeyPair = 'TrentService.GenerateDataKeyPair',
|
||||||
KmsGenerateDataKeyPairWithoutPlaintext = 'GenerateDataKeyPairWithoutPlaintext',
|
KmsGenerateDataKeyPairWithoutPlaintext = 'TrentService.GenerateDataKeyPairWithoutPlaintext',
|
||||||
KmsGenerateDataKeyWithoutPlaintext = 'GenerateDataKeyWithoutPlaintext',
|
KmsGenerateDataKeyWithoutPlaintext = 'TrentService.GenerateDataKeyWithoutPlaintext',
|
||||||
KmsGenerateMac = 'GenerateMac',
|
KmsGenerateMac = 'TrentService.GenerateMac',
|
||||||
KmsGenerateRandom = 'GenerateRandom',
|
KmsGenerateRandom = 'TrentService.GenerateRandom',
|
||||||
KmsGetKeyPolicy = 'GetKeyPolicy',
|
KmsGetKeyPolicy = 'TrentService.GetKeyPolicy',
|
||||||
KmsGetKeyRotationStatus = 'GetKeyRotationStatus',
|
KmsGetKeyRotationStatus = 'TrentService.GetKeyRotationStatus',
|
||||||
KmsGetParametersForImport = 'GetParametersForImport',
|
KmsGetParametersForImport = 'TrentService.GetParametersForImport',
|
||||||
KmsGetPublicKey = 'GetPublicKey',
|
KmsGetPublicKey = 'TrentService.GetPublicKey',
|
||||||
KmsImportKeyMaterial = 'ImportKeyMaterial',
|
KmsImportKeyMaterial = 'TrentService.ImportKeyMaterial',
|
||||||
KmsListAliases = 'ListAliases',
|
KmsListAliases = 'TrentService.ListAliases',
|
||||||
KmsListGrants = 'ListGrants',
|
KmsListGrants = 'TrentService.ListGrants',
|
||||||
KmsListKeyPolicies = 'ListKeyPolicies',
|
KmsListKeyPolicies = 'TrentService.ListKeyPolicies',
|
||||||
KmsListKeys = 'ListKeys',
|
KmsListKeys = 'TrentService.ListKeys',
|
||||||
KmsListResourceTags = 'ListResourceTags',
|
KmsListResourceTags = 'TrentService.ListResourceTags',
|
||||||
KmsListRetirableGrants = 'ListRetirableGrants',
|
KmsListRetirableGrants = 'TrentService.ListRetirableGrants',
|
||||||
KmsPutKeyPolicy = 'PutKeyPolicy',
|
KmsPutKeyPolicy = 'TrentService.PutKeyPolicy',
|
||||||
KmsReEncrypt = 'ReEncrypt',
|
KmsReEncrypt = 'TrentService.ReEncrypt',
|
||||||
KmsReplicateKey = 'ReplicateKey',
|
KmsReplicateKey = 'TrentService.ReplicateKey',
|
||||||
KmsRetireGrant = 'RetireGrant',
|
KmsRetireGrant = 'TrentService.RetireGrant',
|
||||||
KmsRevokeGrant = 'RevokeGrant',
|
KmsRevokeGrant = 'TrentService.RevokeGrant',
|
||||||
KmsScheduleKeyDeletion = 'ScheduleKeyDeletion',
|
KmsScheduleKeyDeletion = 'TrentService.ScheduleKeyDeletion',
|
||||||
KmsSign = 'Sign',
|
KmsSign = 'TrentService.Sign',
|
||||||
KmsTagResource = 'TagResource',
|
KmsTagResource = 'TrentService.TagResource',
|
||||||
KmsUntagResource = 'UntagResource',
|
KmsUntagResource = 'TrentService.UntagResource',
|
||||||
KmsUpdateAlias = 'UpdateAlias',
|
KmsUpdateAlias = 'TrentService.UpdateAlias',
|
||||||
KmsUpdateCustomKeyStore = 'UpdateCustomKeyStore',
|
KmsUpdateCustomKeyStore = 'TrentService.UpdateCustomKeyStore',
|
||||||
KmsUpdateKeyDescription = 'UpdateKeyDescription',
|
KmsUpdateKeyDescription = 'TrentService.UpdateKeyDescription',
|
||||||
KmsUpdatePrimaryRegion = 'UpdatePrimaryRegion',
|
KmsUpdatePrimaryRegion = 'TrentService.UpdatePrimaryRegion',
|
||||||
KmsVerify = 'Verify',
|
KmsVerify = 'TrentService.Verify',
|
||||||
KmsVerifyMac = 'VerifyMac',
|
KmsVerifyMac = 'TrentService.VerifyMac',
|
||||||
|
|
||||||
// SecretsManager
|
// SecretsManager
|
||||||
SecretsManagerCancelRotateSecret = 'secretsmanager.CancelRotateSecret',
|
SecretsManagerCancelRotateSecret = 'secretsmanager.CancelRotateSecret',
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export class AppController {
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
const queryParams = { __path: request.path, ...body, ...lowerCasedHeaders };
|
const queryParams = { __path: request.path, ...body, ...lowerCasedHeaders };
|
||||||
|
console.log({ queryParams })
|
||||||
const actionKey = queryParams['x-amz-target'] ? 'x-amz-target' : 'Action';
|
const actionKey = queryParams['x-amz-target'] ? 'x-amz-target' : 'Action';
|
||||||
const { error: actionError } = Joi.object({
|
const { error: actionError } = Joi.object({
|
||||||
[actionKey]: Joi.string().valid(...Object.values(Action)).required(),
|
[actionKey]: Joi.string().valid(...Object.values(Action)).required(),
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ import { AuditInterceptor } from './audit/audit.interceptor';
|
||||||
import { KmsModule } from './kms/kms.module';
|
import { KmsModule } from './kms/kms.module';
|
||||||
import { KMSHandlers } from './kms/kms.constants';
|
import { KMSHandlers } from './kms/kms.constants';
|
||||||
import { configValidator } from './config/config.validator';
|
import { configValidator } from './config/config.validator';
|
||||||
|
import { IamModule } from './iam/iam.module';
|
||||||
|
import { IAMHandlers } from './iam/iam.constants';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -35,6 +37,7 @@ import { configValidator } from './config/config.validator';
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
TypeOrmModule.forFeature([Audit]),
|
TypeOrmModule.forFeature([Audit]),
|
||||||
|
IamModule,
|
||||||
KmsModule,
|
KmsModule,
|
||||||
SecretsManagerModule,
|
SecretsManagerModule,
|
||||||
SnsModule,
|
SnsModule,
|
||||||
|
|
@ -54,6 +57,7 @@ import { configValidator } from './config/config.validator';
|
||||||
SqsHandlers,
|
SqsHandlers,
|
||||||
SecretsManagerHandlers,
|
SecretsManagerHandlers,
|
||||||
KMSHandlers,
|
KMSHandlers,
|
||||||
|
IAMHandlers,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AttachRolePolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamRole)
|
||||||
|
private readonly roleRepo: Repository<IamRole>,
|
||||||
|
@InjectRepository(IamRolePolicyAttachment)
|
||||||
|
private readonly attachRepo: Repository<IamRolePolicyAttachment>,
|
||||||
|
) {
|
||||||
|
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) {
|
||||||
|
|
||||||
|
const role = await this.roleRepo.findOne({ where: { roleName: RoleName, accountId: awsProperties.accountId} });
|
||||||
|
|
||||||
|
await this.attachRepo.create({
|
||||||
|
id: uuid.v4(),
|
||||||
|
policyArn: PolicyArn,
|
||||||
|
roleId: role.id,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
}).save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
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(
|
||||||
|
@InjectRepository(IamPolicy)
|
||||||
|
private readonly policyRepo: Repository<IamPolicy>,
|
||||||
|
) {
|
||||||
|
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) {
|
||||||
|
|
||||||
|
const { identifier, accountId } = breakdownArn(PolicyArn);
|
||||||
|
const [_policy, name] = identifier.split('/');
|
||||||
|
const currentPolicy = await this.policyRepo.findOne({ where: { accountId, name, isDefault: true } });
|
||||||
|
|
||||||
|
if (SetAsDefault) {
|
||||||
|
await this.policyRepo.update({ accountId, name }, { isDefault: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
const policy = await this.policyRepo.create({
|
||||||
|
id: uuid.v4(),
|
||||||
|
name: name,
|
||||||
|
isDefault: SetAsDefault,
|
||||||
|
version: currentPolicy.version + 1,
|
||||||
|
document: PolicyDocument,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
return {
|
||||||
|
PolicyVersion: {
|
||||||
|
IsDefaultVersion: policy.isDefault,
|
||||||
|
VersionId: `v${policy.version}`,
|
||||||
|
CreateDate: new Date(policy.createdAt).toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyName: string;
|
||||||
|
PolicyDocument: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreatePolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamPolicy)
|
||||||
|
private readonly policyRepo: Repository<IamPolicy>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamCreatePolicy;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyName: Joi.string().required(),
|
||||||
|
PolicyDocument: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyName, PolicyDocument }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const policy = await this.policyRepo.create({
|
||||||
|
id: uuid.v4(),
|
||||||
|
name: PolicyName,
|
||||||
|
document: PolicyDocument,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
return {
|
||||||
|
Policy: {
|
||||||
|
PolicyName: policy.name,
|
||||||
|
DefaultVersionId: 'v1',
|
||||||
|
PolicyId: policy.id,
|
||||||
|
Path: '/',
|
||||||
|
Arn: policy.arn,
|
||||||
|
AttachmentCount: 0,
|
||||||
|
CreateDate: new Date(policy.createdAt).toISOString(),
|
||||||
|
UpdateDate: new Date(policy.updatedAt).toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
Path: string;
|
||||||
|
AssumeRolePolicyDocument: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreateRoleHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamRole)
|
||||||
|
private readonly roleRepo: Repository<IamRole>,
|
||||||
|
@InjectRepository(IamPolicy)
|
||||||
|
private readonly policyRepo: Repository<IamPolicy>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamCreateRole;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
Path: Joi.string().required(),
|
||||||
|
AssumeRolePolicyDocument: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName, Path, AssumeRolePolicyDocument }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const policy = await this.policyRepo.create({
|
||||||
|
id: uuid.v4(),
|
||||||
|
name: `${RoleName}-AssumeRolePolicyDocument`,
|
||||||
|
document: AssumeRolePolicyDocument,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
const id = uuid.v4();
|
||||||
|
|
||||||
|
await this.roleRepo.create({
|
||||||
|
id,
|
||||||
|
roleName: RoleName,
|
||||||
|
path: Path,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
assumeRolePolicyDocumentId: policy.id,
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
const role = await this.roleRepo.findOne({ where: { id }});
|
||||||
|
|
||||||
|
return {
|
||||||
|
Role: role.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { breakdownArn } from '../util/breakdown-arn';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
PolicyArn: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetPolicyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamPolicy)
|
||||||
|
private readonly policyRepo: Repository<IamPolicy>,
|
||||||
|
@InjectRepository(IamRolePolicyAttachment)
|
||||||
|
private readonly attachmentRepo: Repository<IamRolePolicyAttachment>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamGetPolicy;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
PolicyArn: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ PolicyArn }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const { identifier, accountId } = breakdownArn(PolicyArn);
|
||||||
|
const [_policy, name] = identifier.split('/');
|
||||||
|
const policy = await this.policyRepo.findOne({ where: { name, accountId, isDefault: true }});
|
||||||
|
|
||||||
|
if (!policy) {
|
||||||
|
throw new NotFoundException('NoSuchEntity', 'The request was rejected because it referenced a resource entity that does not exist. The error message describes the resource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachmentCount = await this.attachmentRepo.count({ where: { policyArn: policy.arn } });
|
||||||
|
|
||||||
|
return {
|
||||||
|
Policy: {
|
||||||
|
PolicyName: policy.name,
|
||||||
|
DefaultVersionId: `v${policy.version}`,
|
||||||
|
PolicyId: policy.id,
|
||||||
|
Path: '/',
|
||||||
|
Arn: policy.arn,
|
||||||
|
AttachmentCount: attachmentCount,
|
||||||
|
CreateDate: new Date(policy.createdAt).toISOString(),
|
||||||
|
UpdateDate: new Date(policy.updatedAt).toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetRoleHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamRole)
|
||||||
|
private readonly roleRepo: Repository<IamRole>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamGetRole;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const role = await this.roleRepo.findOne({ where: { roleName: RoleName, accountId: awsProperties.accountId } });
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new NotFoundException('NoSuchEntity', 'The request was rejected because it referenced a resource entity that does not exist. The error message describes the resource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
Role: role.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, OneToMany, OneToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
|
||||||
|
@Entity({ name: 'iam_policy' })
|
||||||
|
export class IamPolicy extends BaseEntity {
|
||||||
|
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({ default: 1 })
|
||||||
|
version: number;
|
||||||
|
|
||||||
|
@Column({ name: 'is_default', default: true })
|
||||||
|
isDefault: boolean;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
document: string;
|
||||||
|
|
||||||
|
@Column({ name: 'account_id', nullable: false })
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@CreateDateColumn()
|
||||||
|
createdAt: string;
|
||||||
|
|
||||||
|
@UpdateDateColumn()
|
||||||
|
updatedAt: string;
|
||||||
|
|
||||||
|
@OneToOne(() => IamRole, role => role.assumeRolePolicyDocument)
|
||||||
|
iamRole: IamRole;
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
return `arn:aws:iam::${this.accountId}:policy/${this.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
|
||||||
|
@Entity({ name: 'iam_role_policy_attachment' })
|
||||||
|
export class IamRolePolicyAttachment extends BaseEntity {
|
||||||
|
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({ name: 'policy_arn' })
|
||||||
|
policyArn: string;
|
||||||
|
|
||||||
|
@Column({ name: 'role_name' })
|
||||||
|
roleId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'account_id'})
|
||||||
|
accountId: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, OneToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
|
||||||
|
@Entity({ name: 'iam_role' })
|
||||||
|
export class IamRole extends BaseEntity {
|
||||||
|
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@Column({ name: 'role_name' })
|
||||||
|
roleName: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
path: string;
|
||||||
|
|
||||||
|
@Column({ name: 'assume_role_policy_document_id', nullable: false })
|
||||||
|
assumeRolePolicyDocumentId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'account_id', nullable: false })
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@CreateDateColumn()
|
||||||
|
createdAt: string;
|
||||||
|
|
||||||
|
@UpdateDateColumn()
|
||||||
|
updatedAt: string;
|
||||||
|
|
||||||
|
@OneToOne(() => IamPolicy, (policy) => policy.id, { eager: true })
|
||||||
|
@JoinColumn({ name: 'assume_role_policy_document_id' })
|
||||||
|
assumeRolePolicyDocument: IamPolicy;
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
const identifier = this.path.split('/');
|
||||||
|
identifier.push(this.roleName);
|
||||||
|
return `arn:aws:iam::${this.accountId}:role/${identifier.join('/')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get metadata() {
|
||||||
|
return {
|
||||||
|
Path: this.path,
|
||||||
|
Arn: this.arn,
|
||||||
|
RoleName: this.roleName,
|
||||||
|
AssumeRolePolicyDocument: this.assumeRolePolicyDocument.document,
|
||||||
|
CreateDate: new Date(this.createdAt).toISOString(),
|
||||||
|
RoleId: this.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,205 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
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 { AttachRolePolicyHandler } from './attach-role-policy.handler';
|
||||||
|
import { CreatePolicyVersionHandler } from './create-policy-version.handler';
|
||||||
|
import { CreatePolicyHandler } from './create-policy.handler';
|
||||||
|
import { CreateRoleHandler } from './create-role.handler';
|
||||||
|
import { GetPolicyHandler } from './get-policy.handler';
|
||||||
|
import { GetRoleHandler } from './get-role.handler';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
import { IAMHandlers } from './iam.constants';
|
||||||
|
import { ListAttachedRolePoliciesHandler } from './list-attached-role-policies';
|
||||||
|
import { ListRolePoliciesHandler } from './list-role-policies.handler';
|
||||||
|
|
||||||
|
const handlers = [
|
||||||
|
AttachRolePolicyHandler,
|
||||||
|
CreatePolicyHandler,
|
||||||
|
CreatePolicyVersionHandler,
|
||||||
|
CreateRoleHandler,
|
||||||
|
GetPolicyHandler,
|
||||||
|
GetRoleHandler,
|
||||||
|
ListAttachedRolePoliciesHandler,
|
||||||
|
ListRolePoliciesHandler,
|
||||||
|
]
|
||||||
|
|
||||||
|
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: [
|
||||||
|
TypeOrmModule.forFeature([IamPolicy, IamRole, IamRolePolicyAttachment]),
|
||||||
|
AwsSharedEntitiesModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
...handlers,
|
||||||
|
ExistingActionHandlersProvider(handlers),
|
||||||
|
DefaultActionHandlerProvider(IAMHandlers, Format.Xml, actions),
|
||||||
|
],
|
||||||
|
exports: [IAMHandlers],
|
||||||
|
})
|
||||||
|
export class IamModule {}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { In, Repository } from 'typeorm';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
import { IamPolicy } from './iam-policy.entity';
|
||||||
|
import { breakdownArn } from '../util/breakdown-arn';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ListAttachedRolePoliciesHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamRole)
|
||||||
|
private readonly roleRepo: Repository<IamRole>,
|
||||||
|
@InjectRepository(IamPolicy)
|
||||||
|
private readonly policyRepo: Repository<IamPolicy>,
|
||||||
|
@InjectRepository(IamRolePolicyAttachment)
|
||||||
|
private readonly attachmentRepo: Repository<IamRolePolicyAttachment>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamListAttachedRolePolicies;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const role = await this.roleRepo.findOne({ where: { roleName: RoleName, accountId: awsProperties.accountId } });
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new NotFoundException('NoSuchEntity', 'The request was rejected because it referenced a resource entity that does not exist. The error message describes the resource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachments = await this.attachmentRepo.find({ where: { roleId: role.id } })
|
||||||
|
const policyIds = attachments.map(({ policyArn }) => breakdownArn(policyArn)).map(({ identifier }) => identifier.split('/')[1]);
|
||||||
|
const policies = await this.policyRepo.find({ where: { name: In(policyIds), isDefault: true } });
|
||||||
|
|
||||||
|
return {
|
||||||
|
AttachedPolicies: {
|
||||||
|
member: [role.assumeRolePolicyDocument, ...policies].map(p => ({
|
||||||
|
PolicyName: p.name,
|
||||||
|
PolicyArn: p.arn,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { IamRole } from './iam-role.entity';
|
||||||
|
import { IamRolePolicyAttachment } from './iam-role-policy-attachment.entity';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
RoleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ListRolePoliciesHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(IamRole)
|
||||||
|
private readonly roleRepo: Repository<IamRole>,
|
||||||
|
@InjectRepository(IamRolePolicyAttachment)
|
||||||
|
private readonly attachmentRepo: Repository<IamRolePolicyAttachment>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Xml;
|
||||||
|
action = Action.IamListRolePolicies;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
RoleName: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ RoleName }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const role = await this.roleRepo.findOne({ where: { roleName: RoleName, accountId: awsProperties.accountId } });
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new NotFoundException('NoSuchEntity', 'The request was rejected because it referenced a resource entity that does not exist. The error message describes the resource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
PolicyNames: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { KmsKeyAlias } from './kms-key-alias.entity';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
AliasName: string;
|
||||||
|
TargetKeyId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreateAliasHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(KmsKeyAlias)
|
||||||
|
private readonly aliasRepo: Repository<KmsKeyAlias>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Json;
|
||||||
|
action = Action.KmsCreateAlias;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
AliasName: Joi.string().required(),
|
||||||
|
TargetKeyId: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ AliasName, TargetKeyId }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
await this.aliasRepo.save({
|
||||||
|
name: AliasName.split('/')[1],
|
||||||
|
targetKeyId: TargetKeyId,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
region: awsProperties.region,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { AbstractActionHandler, AwsProperties, Format } from '../abstract-action.handler';
|
||||||
|
import { Action } from '../action.enum';
|
||||||
|
import * as Joi from 'joi';
|
||||||
|
import { KmsKeyAlias } from './kms-key-alias.entity';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { KmsKey } from './kms-key.entity';
|
||||||
|
import { ArnParts, breakdownArn } from '../util/breakdown-arn';
|
||||||
|
|
||||||
|
type QueryParams = {
|
||||||
|
KeyId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DescribeKeyHandler extends AbstractActionHandler<QueryParams> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(KmsKeyAlias)
|
||||||
|
private readonly aliasRepo: Repository<KmsKeyAlias>,
|
||||||
|
@InjectRepository(KmsKey)
|
||||||
|
private readonly keyRepo: Repository<KmsKey>,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
format = Format.Json;
|
||||||
|
action = Action.KmsDescribeKey;
|
||||||
|
validator = Joi.object<QueryParams, true>({
|
||||||
|
KeyId: Joi.string().required(),
|
||||||
|
});
|
||||||
|
|
||||||
|
protected async handle({ KeyId }: QueryParams, awsProperties: AwsProperties) {
|
||||||
|
|
||||||
|
const searchable = KeyId.startsWith('arn') ? breakdownArn(KeyId) : {
|
||||||
|
service: 'kms',
|
||||||
|
region: awsProperties.region,
|
||||||
|
accountId: awsProperties.accountId,
|
||||||
|
identifier: KeyId,
|
||||||
|
};
|
||||||
|
const [ type, pk ] = searchable.identifier.split('/');
|
||||||
|
const keyId: Promise<string> = type === 'key' ?
|
||||||
|
Promise.resolve(pk) :
|
||||||
|
this.findKeyIdFromAlias(pk, searchable);
|
||||||
|
|
||||||
|
|
||||||
|
const keyRecord = await this.keyRepo.findOne({ where: {
|
||||||
|
id: await keyId,
|
||||||
|
region: searchable.region,
|
||||||
|
accountId: searchable.accountId,
|
||||||
|
}});
|
||||||
|
|
||||||
|
return {
|
||||||
|
KeyMetadata: keyRecord.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async findKeyIdFromAlias(alias: string ,arn: ArnParts): Promise<string> {
|
||||||
|
const record = await this.aliasRepo.findOne({ where: {
|
||||||
|
name: alias,
|
||||||
|
accountId: arn.accountId,
|
||||||
|
region: arn.region,
|
||||||
|
}});
|
||||||
|
return record.targetKeyId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity({ name: 'kms_key_alias' })
|
||||||
|
export class KmsKeyAlias extends BaseEntity {
|
||||||
|
|
||||||
|
@PrimaryColumn()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'target_key_id' })
|
||||||
|
targetKeyId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'account_id', nullable: false })
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'region', nullable: false })
|
||||||
|
region: string;
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
return `arn:aws:kms:${this.region}:${this.accountId}:alias/${this.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity({ name: 'kms_key'})
|
||||||
|
export class KmsKey extends BaseEntity {
|
||||||
|
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({ name: 'usage' })
|
||||||
|
usage: string;
|
||||||
|
|
||||||
|
@Column({ name: 'description' })
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@Column({ name: 'key_spec' })
|
||||||
|
keySpec: string;
|
||||||
|
|
||||||
|
@Column({ name: 'key' })
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
@Column({ name: 'account_id', nullable: false })
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'region', nullable: false })
|
||||||
|
region: string;
|
||||||
|
|
||||||
|
@CreateDateColumn()
|
||||||
|
createdAt: string;
|
||||||
|
|
||||||
|
get arn() {
|
||||||
|
return `arn:aws:kms:${this.region}:${this.accountId}:key/${this.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get metadata() {
|
||||||
|
return {
|
||||||
|
AWSAccountId: this.accountId,
|
||||||
|
KeyId: this.id,
|
||||||
|
Arn: this.arn,
|
||||||
|
CreationDate: new Date(this.createdAt).toISOString(),
|
||||||
|
Enabled: true,
|
||||||
|
Description: this.description,
|
||||||
|
KeyUsage: this.usage,
|
||||||
|
KeyState: 'Enabled',
|
||||||
|
KeyManager: "CUSTOMER",
|
||||||
|
CustomerMasterKeySpec: this.keySpec,
|
||||||
|
KeySpec: this.keySpec,
|
||||||
|
DeletionDate: null,
|
||||||
|
SigningAlgorithms: [
|
||||||
|
"RSASSA_PSS_SHA_256",
|
||||||
|
"RSASSA_PSS_SHA_384",
|
||||||
|
"RSASSA_PSS_SHA_512",
|
||||||
|
"RSASSA_PKCS1_V1_5_SHA_256",
|
||||||
|
"RSASSA_PKCS1_V1_5_SHA_384",
|
||||||
|
"RSASSA_PKCS1_V1_5_SHA_512"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,10 +5,15 @@ import { Action } from '../action.enum';
|
||||||
import { AwsSharedEntitiesModule } from '../aws-shared-entities/aws-shared-entities.module';
|
import { AwsSharedEntitiesModule } from '../aws-shared-entities/aws-shared-entities.module';
|
||||||
import { DefaultActionHandlerProvider } from '../default-action-handler/default-action-handler.provider';
|
import { DefaultActionHandlerProvider } from '../default-action-handler/default-action-handler.provider';
|
||||||
import { ExistingActionHandlersProvider } from '../default-action-handler/existing-action-handlers.provider';
|
import { ExistingActionHandlersProvider } from '../default-action-handler/existing-action-handlers.provider';
|
||||||
|
import { CreateAliasHandler } from './create-alias.handler';
|
||||||
|
import { DescribeKeyHandler } from './describe-key.handler';
|
||||||
|
import { KmsKeyAlias } from './kms-key-alias.entity';
|
||||||
|
import { KmsKey } from './kms-key.entity';
|
||||||
import { KMSHandlers } from './kms.constants';
|
import { KMSHandlers } from './kms.constants';
|
||||||
|
|
||||||
const handlers = [
|
const handlers = [
|
||||||
|
CreateAliasHandler,
|
||||||
|
DescribeKeyHandler,
|
||||||
]
|
]
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
|
|
@ -66,7 +71,7 @@ const actions = [
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([]),
|
TypeOrmModule.forFeature([KmsKey, KmsKeyAlias]),
|
||||||
AwsSharedEntitiesModule,
|
AwsSharedEntitiesModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
export type ArnParts = {
|
||||||
|
service: string;
|
||||||
|
region: string;
|
||||||
|
accountId: string;
|
||||||
|
identifier: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const breakdownArn = (arn: string): ArnParts => {
|
||||||
|
if (!arn.startsWith('arn')) {
|
||||||
|
throw new Error('Invalid arn');
|
||||||
|
}
|
||||||
|
|
||||||
|
const [_arn, _aws, service, region, accountId, ...identifierData] = arn.split(':');
|
||||||
|
|
||||||
|
return {
|
||||||
|
service,
|
||||||
|
region,
|
||||||
|
accountId,
|
||||||
|
identifier: identifierData.join(':'),
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue