Skip to content

Commit 25b03d1

Browse files
author
Christopher Brandt
authored
Merge pull request #30 from cloudgraphdev/feature/CG-1058
feat(cognitoIdentityPool): add iamRole/iamOpenIdConnectProvider/iamSa…
2 parents e21d1af + c37dba4 commit 25b03d1

12 files changed

Lines changed: 256 additions & 18 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
8585
| cloudwatch | cloudtrail, cloudwatchLog, sns |
8686
| cloudwatchLog | cloudtrail, cloudwatch, ecsCluster, kms, managedAirflow, rdsDbInstance |
8787
| codebuild | iamRole, kms, vpc, securityGroup, subnet |
88-
| cognitoIdentityPool | |
88+
| cognitoIdentityPool | iamRole, iamOpenIdConnectProvider, iamSamlProvider |
8989
| cognitoUserPool | appSync, lambda |
9090
| configurationRecorder | iamRole |
9191
| customerGateway | vpnConnection |
@@ -119,12 +119,12 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
119119
| guardDutyDetector | iamRole |
120120
| iamInstanceProfile | ec2, iamRole |
121121
| iamPasswordPolicy | |
122-
| iamSamlProvider | |
123-
| iamOpenIdConnectProvider | |
122+
| iamSamlProvider | cognitoIdentityPool |
123+
| iamOpenIdConnectProvider | cognitoIdentityPool |
124124
| iamServerCertificate | |
125125
| iamUser | iamGroup |
126126
| iamPolicy | iamRole, iamGroup |
127-
| iamRole | appSync, asg, cloudformationStackSet, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, s3, sageMakerNotebookInstance, systemsManagerInstance, guardDutyDetector, lambda, kinesisFirehose, rdsCluster, rdsDbInstance, elasticBeanstalkApp, elasticBeanstalkEnv |
127+
| iamRole | appSync, asg, cloudformationStackSet, codebuild, cognitoIdentityPool, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, s3, sageMakerNotebookInstance, systemsManagerInstance, guardDutyDetector, lambda, kinesisFirehose, rdsCluster, rdsDbInstance, elasticBeanstalkApp, elasticBeanstalkEnv |
128128
| iamGroup | iamUser, iamPolicy |
129129
| igw | vpc |
130130
| iot | |
Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,104 @@
1-
// TODO Add Optional IAM saml provider
1+
import { ServiceConnection } from '@cloudgraph/sdk'
2+
import { isEmpty } from 'lodash'
3+
import services from '../../enums/services'
4+
import { RawAwsCognitoIdentityPool } from './data'
5+
import { RawAwsIamRole } from '../iamRole/data'
6+
import { globalRegionName } from '../../enums/regions'
7+
8+
/**
9+
* Cognito Identity Pool
10+
*/
11+
12+
export default ({
13+
service: identityPool,
14+
data,
15+
region,
16+
}: {
17+
data: { name: string; data: { [property: string]: any[] } }[]
18+
service: RawAwsCognitoIdentityPool
19+
region: string
20+
}): { [key: string]: ServiceConnection[] } => {
21+
const connections: ServiceConnection[] = []
22+
23+
const {
24+
IdentityPoolId: id,
25+
identityPoolRoles,
26+
SamlProviderARNs = [],
27+
OpenIdConnectProviderARNs = [],
28+
} = identityPool
29+
30+
/**
31+
* Find related IAM Roles
32+
*/
33+
const roles: { name: string; data: { [property: string]: any[] } } =
34+
data.find(({ name }) => name === services.iamRole)
35+
36+
const iamRoleArns = Object.values(identityPoolRoles?.Roles || {})
37+
38+
if (roles?.data?.[globalRegionName]) {
39+
const dataAtRegion: RawAwsIamRole[] = roles.data[globalRegionName].filter(role =>
40+
iamRoleArns.includes(role.Arn)
41+
)
42+
if (!isEmpty(dataAtRegion)) {
43+
for (const instance of dataAtRegion) {
44+
const { Arn: arn }: RawAwsIamRole = instance
45+
46+
connections.push({
47+
id: arn,
48+
resourceType: services.iamRole,
49+
relation: 'child',
50+
field: 'iamRoles',
51+
})
52+
}
53+
}
54+
}
55+
56+
/**
57+
* Find iamSamlProvider
58+
* related to this cognito identity pool
59+
*/
60+
const iamSamlProviders = data.find(({ name }) => name === services.iamSamlProvider)
61+
if (iamSamlProviders?.data?.[region]) {
62+
const dataInRegion = iamSamlProviders.data[region].filter(provider =>
63+
SamlProviderARNs.includes(provider.arn)
64+
)
65+
66+
if (!isEmpty(dataInRegion)) {
67+
for (const provider of dataInRegion) {
68+
connections.push({
69+
id: provider.KeyId,
70+
resourceType: services.iamSamlProvider,
71+
relation: 'child',
72+
field: 'iamSamlProviders',
73+
})
74+
}
75+
}
76+
}
77+
78+
/**
79+
* Find iamOpenIdConnectProvider
80+
* related to this cognito identity pool
81+
*/
82+
const iamOpenIdConnectProviders = data.find(({ name }) => name === services.iamOpenIdConnectProvider)
83+
if (iamOpenIdConnectProviders?.data?.[region]) {
84+
const dataInRegion = iamOpenIdConnectProviders.data[region].filter(provider =>
85+
OpenIdConnectProviderARNs.includes(provider.arn)
86+
)
87+
88+
if (!isEmpty(dataInRegion)) {
89+
for (const provider of dataInRegion) {
90+
connections.push({
91+
id: provider.KeyId,
92+
resourceType: services.iamOpenIdConnectProvider,
93+
relation: 'child',
94+
field: 'iamOpenIdConnectProviders',
95+
})
96+
}
97+
}
98+
}
99+
100+
const identityPoolResult = {
101+
[id]: connections,
102+
}
103+
return identityPoolResult
104+
}

src/services/cognitoIdentityPool/data.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import COGID, {
22
IdentityPool,
33
IdentityPoolShortDescription,
4+
GetIdentityPoolRolesResponse,
45
} from 'aws-sdk/clients/cognitoidentity'
56
import { Config } from 'aws-sdk/lib/config'
67

@@ -25,6 +26,7 @@ const MAX_RESULTS = 60
2526

2627
export interface RawAwsCognitoIdentityPool
2728
extends Omit<IdentityPool, 'IdentityPoolTags'> {
29+
identityPoolRoles: GetIdentityPoolRolesResponse
2830
region: string
2931
Tags: TagMap
3032
}
@@ -91,6 +93,27 @@ const describeIdentityPool = async ({
9193
return null
9294
}
9395

96+
const getIdentityPoolRoles = async ({
97+
cogId,
98+
IdentityPoolId,
99+
}: {
100+
cogId: COGID
101+
IdentityPoolId: string
102+
}): Promise<GetIdentityPoolRolesResponse> => {
103+
try {
104+
return await cogId
105+
.getIdentityPoolRoles({ IdentityPoolId })
106+
.promise()
107+
108+
} catch (err) {
109+
errorLog.generateAwsErrorLog({
110+
functionName: 'cognitoIdentityPool:getIdentityPoolRoles',
111+
err,
112+
})
113+
}
114+
return null
115+
}
116+
94117
const listIdentityPoolData = async ({
95118
cogId,
96119
region,
@@ -106,8 +129,13 @@ const listIdentityPoolData = async ({
106129
cogId,
107130
IdentityPoolId: identityPoolId.IdentityPoolId,
108131
})
132+
const identityPoolRoles = await getIdentityPoolRoles({
133+
cogId,
134+
IdentityPoolId: identityPoolId.IdentityPoolId,
135+
})
109136
identityPoolData.push({
110137
...identityPool,
138+
identityPoolRoles,
111139
region,
112140
})
113141
}

src/services/cognitoIdentityPool/format.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { IdentityProviders } from 'aws-sdk/clients/cognitoidentity';
2-
import cuid from 'cuid';
1+
import { IdentityProviders } from 'aws-sdk/clients/cognitoidentity'
2+
import cuid from 'cuid'
33
import t from '../../properties/translations'
4-
5-
import { AwsCognitoIdentityPool, AwsSupportedLoginProvider } from '../../types/generated';
6-
import { formatTagsFromMap } from '../../utils/format';
7-
import { RawAwsCognitoIdentityPool } from './data';
4+
import { AwsCognitoIdentityPool, AwsSupportedLoginProvider } from '../../types/generated'
5+
import { formatTagsFromMap } from '../../utils/format'
6+
import { RawAwsCognitoIdentityPool } from './data'
7+
import {
8+
cognitoIdentityPoolArn,
9+
} from '../../utils/generateArns'
810

911
/**
1012
* Cognito Identity Pool
@@ -53,9 +55,12 @@ export default ({
5355
serverSideTokenCheck: serverSideTokenCheck? t.yes : t.no,
5456
})) || []
5557

58+
const arn = cognitoIdentityPoolArn({ region, account, identityPoolId })
59+
5660
const identityPool = {
5761
id: identityPoolId,
5862
accountId: account,
63+
arn,
5964
identityPoolName,
6065
allowUnauthenticatedIdentities: allowUnauthenticatedIdentities? t.yes : t.no,
6166
allowClassicFlow: allowClassicFlow? t.yes : t.no,

src/services/cognitoIdentityPool/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import { Service } from '@cloudgraph/sdk';
22
import BaseService from '../base';
33
import format from './format';
44
import getData from './data';
5-
// import getConnections from './connections'
5+
import getConnections from './connections'
66
import mutation from './mutation';
77

88
export default class AwsCognitoIdentityPool extends BaseService implements Service {
99
format = format.bind(this);
1010

1111
getData = getData.bind(this);
1212

13-
// getConnections = getConnections.bind(this)
13+
getConnections = getConnections.bind(this)
1414

1515
mutation = mutation;
1616
}

src/services/cognitoIdentityPool/schema.graphql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type awsCognitoIdentityProviders
2222

2323
type awsCognitoIdentityPool @key(fields: "id") {
2424
id: String! @id @search(by: [hash])
25+
arn: String! @search(by: [hash])
2526
accountId: String! @search(by: [hash])
2627
region: String @search(by: [hash, regexp])
2728
identityPoolName: String @search(by: [hash, regexp])
@@ -33,8 +34,7 @@ type awsCognitoIdentityPool @key(fields: "id") {
3334
cognitoIdentityProviders: [awsCognitoIdentityProviders]
3435
samlProviderARNs: [String] @search
3536
tags: [awsRawTag]
37+
iamRoles: [awsIamRole] @hasInverse(field: awsCognitoIdentityPool)
38+
iamOpenIdConnectProviders: [awsIamOpenIdConnectProvider] @hasInverse(field: awsCognitoIdentityPool)
39+
iamSamlProviders: [awsIamSamlProvider] @hasInverse(field: awsCognitoIdentityPool)
3640
}
37-
38-
# TODO: add an arn for identity pool see here: https://docs.aws.amazon.com/cognito/latest/developerguide/security_iam_service-with-iam.html
39-
#TODO: add connections to iamSamlProvider and iamOpenIdConnectProvider
40-
#TODO: try to add connection to iam role using getIdentityPoolRoles

src/services/iamOpenIdConnectProvider/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ type awsIamOpenIdConnectProvider @key(fields: "id") {
44
accountId: String! @search(by: [hash, regexp])
55
region: String @search(by: [hash, regexp])
66
cgId: String @search(by: [hash, regexp])
7+
awsCognitoIdentityPool: [awsCognitoIdentityPool] @hasInverse(field: iamOpenIdConnectProviders)
78
}

src/services/iamRole/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ type awsIamRole implements awsBaseService @key(fields: "id") {
3535
cloudFormationStackSet: [awsCloudFormationStackSet]
3636
@hasInverse(field: iamRoles)
3737
asg: [awsAsg] @hasInverse(field: iamRole)
38+
awsCognitoIdentityPool: [awsCognitoIdentityPool] @hasInverse(field: iamRoles)
3839
rdsDbInstance: [awsRdsDbInstance] @hasInverse(field: iamRoles)
3940
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
type awsIamSamlProvider implements awsOptionalService @key(fields: "id") {
22
validUntil: String @search(by: [hash, regexp])
33
createdDate: String @search(by: [hash, regexp])
4+
awsCognitoIdentityPool: [awsCognitoIdentityPool] @hasInverse(field: iamSamlProviders)
45
}

src/types/generated.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,12 @@ export type AwsCognitoIdentityPool = {
11191119
accountId: Scalars['String'];
11201120
allowClassicFlow?: Maybe<Scalars['String']>;
11211121
allowUnauthenticatedIdentities?: Maybe<Scalars['String']>;
1122+
arn: Scalars['String'];
11221123
cognitoIdentityProviders?: Maybe<Array<Maybe<AwsCognitoIdentityProviders>>>;
11231124
developerProviderName?: Maybe<Scalars['String']>;
1125+
iamOpenIdConnectProviders?: Maybe<Array<Maybe<AwsIamOpenIdConnectProvider>>>;
1126+
iamRoles?: Maybe<Array<Maybe<AwsIamRole>>>;
1127+
iamSamlProviders?: Maybe<Array<Maybe<AwsIamSamlProvider>>>;
11241128
id: Scalars['String'];
11251129
identityPoolName?: Maybe<Scalars['String']>;
11261130
openIdConnectProviderARNs?: Maybe<Array<Maybe<Scalars['String']>>>;
@@ -3028,6 +3032,7 @@ export type AwsIamMfaDevice = {
30283032
export type AwsIamOpenIdConnectProvider = {
30293033
accountId: Scalars['String'];
30303034
arn: Scalars['String'];
3035+
awsCognitoIdentityPool?: Maybe<Array<Maybe<AwsCognitoIdentityPool>>>;
30313036
cgId?: Maybe<Scalars['String']>;
30323037
id: Scalars['String'];
30333038
region?: Maybe<Scalars['String']>;
@@ -3063,6 +3068,7 @@ export type AwsIamRole = AwsBaseService & {
30633068
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
30643069
asg?: Maybe<Array<Maybe<AwsAsg>>>;
30653070
assumeRolePolicy?: Maybe<AwsIamJsonPolicy>;
3071+
awsCognitoIdentityPool?: Maybe<Array<Maybe<AwsCognitoIdentityPool>>>;
30663072
cloudFormationStack?: Maybe<Array<Maybe<AwsCloudFormationStack>>>;
30673073
cloudFormationStackSet?: Maybe<Array<Maybe<AwsCloudFormationStackSet>>>;
30683074
codebuilds?: Maybe<Array<Maybe<AwsCodebuild>>>;
@@ -3097,6 +3103,7 @@ export type AwsIamRole = AwsBaseService & {
30973103
};
30983104

30993105
export type AwsIamSamlProvider = AwsOptionalService & {
3106+
awsCognitoIdentityPool?: Maybe<Array<Maybe<AwsCognitoIdentityPool>>>;
31003107
createdDate?: Maybe<Scalars['String']>;
31013108
validUntil?: Maybe<Scalars['String']>;
31023109
};

0 commit comments

Comments
 (0)