Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/services/cloudFormationStack/connections.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { ServiceConnection } from '@cloudgraph/sdk'
import { Stack } from 'aws-sdk/clients/cloudformation'
import isEmpty from 'lodash/isEmpty'
import resources from '../../enums/resources'
import services from '../../enums/services'
import { RawAwsCloudFormationStack } from './data'
import { RawAwsIamRole } from '../iamRole/data'
import { TagMap } from '../../types'
import { getIamId } from '../../utils/ids'
import { globalRegionName } from '../../enums/regions'

/**
Expand Down Expand Up @@ -84,14 +82,10 @@ export default ({
)
if (!isEmpty(dataAtRegion)) {
for (const instance of dataAtRegion) {
const { RoleId: roleId, RoleName: roleName } = instance
const { Arn: arn }: RawAwsIamRole = instance

connections.push({
id: getIamId({
resourceId: roleId,
resourceName: roleName,
resourceType: resources.iamRole,
}),
id: arn,
resourceType: services.iamRole,
relation: 'child',
field: 'iamRole',
Expand Down
2 changes: 1 addition & 1 deletion src/services/cloudFormationStack/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export default ({
timeoutInMinutes,
capabilities,
outputs: outputsList,
roleArn: roleArn || '', // TODO: create connection to IAM role if possible
roleArn: roleArn || '',
tags: formatTagsFromMap(tags),
enableTerminationProtection: enableTerminationProtection ? t.yes : t.no,
parentId: parentId || '',
Expand Down
144 changes: 126 additions & 18 deletions src/services/cognitoUserPool/connections.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
import { UserPoolType } from 'aws-sdk/clients/cognitoidentityserviceprovider';
import { UserPoolType, LambdaConfigType } from 'aws-sdk/clients/cognitoidentityserviceprovider'

import { ServiceConnection } from '@cloudgraph/sdk';
import services from '../../enums/services';
import { ServiceConnection } from '@cloudgraph/sdk'
import { isEmpty } from 'lodash'
import services from '../../enums/services'
import { sesArn } from '../../utils/generateArns'
import { RawAwsLambdaFunction } from '../lambda/data'
import { RawAwsSes } from '../ses/data'
import { RawAwsIamRole } from '../iamRole/data'
import { AwsKms } from '../kms/data'

const getLambdasArn = (
lambdaConfig?: LambdaConfigType
): string[] => {
if (isEmpty(lambdaConfig)) {
return []
}

const {
PreSignUp,
CustomMessage,
PostConfirmation,
PreAuthentication,
PostAuthentication,
DefineAuthChallenge,
CreateAuthChallenge,
VerifyAuthChallengeResponse,
PreTokenGeneration,
UserMigration,
} = lambdaConfig

return [
PreSignUp,
CustomMessage,
PostConfirmation,
PreAuthentication,
PostAuthentication,
DefineAuthChallenge,
CreateAuthChallenge,
VerifyAuthChallengeResponse,
PreTokenGeneration,
UserMigration,
]?.filter(l => l)
}

/**
* Cognito User Pool
Expand All @@ -11,7 +51,9 @@ export default ({
service: userPool,
data,
region,
account,
}: {
account: string
data: { name: string; data: { [property: string]: any[] } }[]
service: UserPoolType & {
region: string
Expand All @@ -23,38 +65,104 @@ export default ({
const {
Id: id,
LambdaConfig: lambdaConfig,
EmailConfiguration: emailConfiguration,
SmsConfiguration: smsConfiguration,
} = userPool

const defineAuthChallengeArn = lambdaConfig?.DefineAuthChallenge

/**
* Find Lambda Functions
* related to this Auto Scaling Group
* related to this cognito user pool
*/
const lambdasArn: string[] = getLambdasArn(lambdaConfig)
const lambdas = data.find(({ name }) => name === services.lambda)

if (defineAuthChallengeArn && lambdas?.data?.[region]) {
const lambdaInRegion = lambdas.data[region].find(lambda =>
defineAuthChallengeArn === lambda.FunctionArn)

if (lambdaInRegion) {
const lambdaFunctionArn = lambdaInRegion.FunctionArn
if (lambdasArn?.length > 0 && lambdas?.data?.[region]) {
const lambdasInRegion: RawAwsLambdaFunction[] = lambdas.data[region].filter(
({ FunctionArn }: RawAwsLambdaFunction) =>
lambdasArn.includes(FunctionArn)
)

if (!isEmpty(lambdasInRegion)) {
for (const lambda of lambdasInRegion) {
connections.push({
id: lambda.FunctionArn,
resourceType: services.lambda,
relation: 'child',
field: 'lambdas',
})
}
}
}

/**
* Find MKS
* related to this cognito user pool
*/
const kmsKeyID = lambdaConfig?.KMSKeyID
const kms = data.find(({ name }) => name === services.kms)

if (kmsKeyID && kms?.data?.[region]) {
const kmsInRegion: AwsKms = kms.data[region].find(
({ KeyId }: AwsKms) => kmsKeyID === KeyId
)

if (kmsInRegion) {
connections.push({
id: lambdaFunctionArn,
resourceType: services.lambda,
id: kmsInRegion.KeyId,
resourceType: services.kms,
relation: 'child',
field: 'lambda',
field: 'kms',
})
}
}

// TODO Email Sender
/**
* Find SES sender
* related to this cognito user pool
*/
const emailConfigSourceArn = emailConfiguration?.SourceArn
const emails = data.find(({ name }) => name === services.ses)

// TODO SMS Sender
if (emailConfigSourceArn && emails?.data?.[region]) {
const emailInRegion: RawAwsSes = emails.data[region].find(
({ Identity }: RawAwsSes) =>
emailConfigSourceArn === sesArn({ region, account, email: Identity })
)

if (emailInRegion) {
connections.push({
id: sesArn({ region, account, email: emailInRegion.Identity }),
resourceType: services.ses,
relation: 'child',
field: 'ses',
})
}
}

/**
* Find SNS caller
* related to this cognito user pool
*/
const smsConfigSnsCallerArn = smsConfiguration?.SnsCallerArn
const iamRoles = data.find(({ name }) => name === services.iamRole)

if (smsConfigSnsCallerArn && iamRoles?.data?.[region]) {
const iamRoleInRegion: RawAwsIamRole = iamRoles.data[region].find(
({ Arn }: RawAwsIamRole) => smsConfigSnsCallerArn === Arn
)

if (iamRoleInRegion) {
connections.push({
id: iamRoleInRegion.Arn,
resourceType: services.iamRole,
relation: 'child',
field: 'iamRole',
})
}
}

const userPoolResult = {
[id]: connections,
}
return userPoolResult
}
}
10 changes: 5 additions & 5 deletions src/services/cognitoUserPool/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ type awsCognitoUserPool implements awsBaseService @key(fields: "id") {
usernameConfigurationCaseSensitive: String @search(by: [hash, regexp])
accountRecoverySettings: [awsAccountRecoverySetting]
tags: [awsRawTag]
lambda: [awsLambda] @hasInverse(field: cognitoUserPool) #change to plural
lambdas: [awsLambda] @hasInverse(field: cognitoUserPools)
appSync: [awsAppSync] @hasInverse(field: cognitoUserPool)
}

# TODO: add connetion to kms
# TODO: add connection to iamRole using SmsConfiguration.SnsCallerArn
kms: [awsKms] @hasInverse(field: cognitoUserPools)
ses: [awsSes] @hasInverse(field: cognitoUserPools)
iamRole: [awsIamRole] @hasInverse(field: cognitoUserPools)
}
1 change: 1 addition & 0 deletions src/services/iamRole/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ type awsIamRole implements awsBaseService @key(fields: "id") {
systemsManagerInstances: [awsSystemsManagerInstance]
@hasInverse(field: iamRole)
iamInstanceProfiles: [awsIamInstanceProfile] @hasInverse(field: iamRole)
cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: iamRole)
}
1 change: 1 addition & 0 deletions src/services/kms/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ type awsKms implements awsBaseService @key(fields: "id") {
sageMakerNotebookInstances: [awsSageMakerNotebookInstance]
@hasInverse(field: kms)
rdsClusterSnapshots: [awsRdsClusterSnapshot] @hasInverse(field: kms)
cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: kms)
}
2 changes: 1 addition & 1 deletion src/services/lambda/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type awsLambda implements awsBaseService @key(fields: "arn") {
securityGroups: [awsSecurityGroup] @hasInverse(field: lambda)
subnet: [awsSubnet] @hasInverse(field: lambda) #change to plural
vpc: [awsVpc] @hasInverse(field: lambda)
cognitoUserPool: [awsCognitoUserPool] @hasInverse(field: lambda) #change to plural
cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: lambdas)
appSync: [awsAppSync] @hasInverse(field: lambda)
}

Expand Down
1 change: 1 addition & 0 deletions src/services/ses/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
type awsSes implements awsBaseService @key(fields: "arn") {
email: String @search(by: [hash, regexp])
verificationStatus: String @search(by: [hash, regexp])
cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: ses)
}
10 changes: 8 additions & 2 deletions src/types/generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1152,13 +1152,16 @@ export type AwsCognitoUserPool = AwsBaseService & {
emailVerificationMessage?: Maybe<Scalars['String']>;
emailVerificationSubject?: Maybe<Scalars['String']>;
estimatedNumberOfUsers?: Maybe<Scalars['Int']>;
lambda?: Maybe<Array<Maybe<AwsLambda>>>;
iamRole?: Maybe<Array<Maybe<AwsIamRole>>>;
kms?: Maybe<Array<Maybe<AwsKms>>>;
lambdaConfig?: Maybe<AwsCognitoUserPoolLambdaConfig>;
lambdas?: Maybe<Array<Maybe<AwsLambda>>>;
lastModifiedDate?: Maybe<Scalars['String']>;
mfaConfiguration?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
policies?: Maybe<AwsCognitoUserPoolPasswordPolicy>;
schemaAttributes?: Maybe<Array<Maybe<AwsCognitoUserPoolSchemaAttribute>>>;
ses?: Maybe<Array<Maybe<AwsSes>>>;
smsAuthenticationMessage?: Maybe<Scalars['String']>;
smsConfigurationExternalId?: Maybe<Scalars['String']>;
smsConfigurationFailure?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -3011,6 +3014,7 @@ export type AwsIamRole = AwsBaseService & {
assumeRolePolicy?: Maybe<AwsIamJsonPolicy>;
cloudFormationStack?: Maybe<Array<Maybe<AwsCloudFormationStack>>>;
codebuilds?: Maybe<Array<Maybe<AwsCodebuild>>>;
cognitoUserPools?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
configurationRecorder?: Maybe<Array<Maybe<AwsConfigurationRecorder>>>;
createdAt?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -3134,6 +3138,7 @@ export type AwsKms = AwsBaseService & {
cloudtrail?: Maybe<Array<Maybe<AwsCloudtrail>>>;
cloudwatchLog?: Maybe<Array<Maybe<AwsCloudwatchLog>>>;
codebuilds?: Maybe<Array<Maybe<AwsCodebuild>>>;
cognitoUserPools?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
creationDate?: Maybe<Scalars['String']>;
customerMasterKeySpec?: Maybe<Scalars['String']>;
deletionDate?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -3162,7 +3167,7 @@ export type AwsKms = AwsBaseService & {

export type AwsLambda = AwsBaseService & {
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
cognitoUserPool?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
cognitoUserPools?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
description?: Maybe<Scalars['String']>;
environmentVariables?: Maybe<Array<Maybe<AwsLambdaEnvironmentVariable>>>;
handler?: Maybe<Scalars['String']>;
Expand Down Expand Up @@ -3761,6 +3766,7 @@ export type AwsServiceBillingInfo = {
};

export type AwsSes = AwsBaseService & {
cognitoUserPools?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
email?: Maybe<Scalars['String']>;
verificationStatus?: Maybe<Scalars['String']>;
};
Expand Down