|
1 | 1 | const assert = require('assert'); |
2 | | -const async = require('async'); |
3 | 2 | const { errors } = require('arsenal'); |
| 3 | +const { |
| 4 | + CreateRoleCommand, |
| 5 | + DeleteRoleCommand, |
| 6 | + AttachRolePolicyCommand, |
| 7 | + DetachRolePolicyCommand, |
| 8 | + CreatePolicyCommand, |
| 9 | + DeletePolicyCommand, |
| 10 | + CreateUserCommand, |
| 11 | + CreateAccessKeyCommand, |
| 12 | + AttachUserPolicyCommand, |
| 13 | +} = require('@aws-sdk/client-iam'); |
| 14 | +const { AssumeRoleCommand } = require('@aws-sdk/client-sts'); |
| 15 | +const { |
| 16 | + CreateBucketCommand, |
| 17 | + PutObjectCommand, |
| 18 | + DeleteObjectCommand, |
| 19 | + DeleteBucketCommand, |
| 20 | +} = require('@aws-sdk/client-s3'); |
4 | 21 | const VaultClient = require('../../VaultClient'); |
5 | 22 | const { getS3Client } = require('../../s3SDK'); |
6 | 23 | const { getSTSClient } = require('../../stsSDK'); |
@@ -77,107 +94,99 @@ testAPIs.forEach(testAPI => { |
77 | 94 |
|
78 | 95 | describe(`iam policies - cloudserver - AssumeRole - ${testAPI.API}`, () => { |
79 | 96 |
|
80 | | - before(done => { |
81 | | - async.series([ |
82 | | - // create account1, generateAccountAccessKey for it and get account1 iam client |
83 | | - next => clientAdmin.createAccount(account1Name, account1Info, (err, res) => { |
84 | | - if (err) { |
85 | | - return next(err); |
86 | | - } |
87 | | - iamAccount1Id = res.account.id; |
88 | | - return next(); |
89 | | - }), |
90 | | - next => clientAdmin.generateAccountAccessKey( |
| 97 | + before(async () => { |
| 98 | + // create account1, generateAccountAccessKey for it and get account1 iam client |
| 99 | + const res = await new Promise((resolve, reject) => { |
| 100 | + clientAdmin.createAccount(account1Name, account1Info, (err, res) => { |
| 101 | + if (err) return reject(err); |
| 102 | + return resolve(res); |
| 103 | + }); |
| 104 | + }); |
| 105 | + iamAccount1Id = res.account.id; |
| 106 | + |
| 107 | + await new Promise((resolve, reject) => { |
| 108 | + clientAdmin.generateAccountAccessKey( |
91 | 109 | account1Name, |
92 | | - next, |
| 110 | + (err) => { |
| 111 | + if (err) return reject(err); |
| 112 | + return resolve(); |
| 113 | + }, |
93 | 114 | { externalAccessKey: externalAccessKey1, externalSecretKey: externalSecretKey1 }, |
94 | | - ), |
95 | | - next => { |
96 | | - iamAccount1Client = VaultClient.getIamClient(externalAccessKey1, externalSecretKey1); |
97 | | - next(); |
98 | | - }, |
99 | | - // create account2, generateAccountAccessKey for it, get account2 iam client |
100 | | - // create a user under account2, create access key for the user and get user sts client |
101 | | - next => clientAdmin.createAccount(account2Name, account2Info, next), |
102 | | - next => clientAdmin.generateAccountAccessKey( |
| 115 | + ); |
| 116 | + }); |
| 117 | + |
| 118 | + iamAccount1Client = VaultClient.getIamClient(externalAccessKey1, externalSecretKey1); |
| 119 | + |
| 120 | + // create account2, generateAccountAccessKey for it, get account2 iam client |
| 121 | + // create a user under account2, create access key for the user and get user sts client |
| 122 | + await new Promise((resolve, reject) => { |
| 123 | + clientAdmin.createAccount(account2Name, account2Info, (err) => { |
| 124 | + if (err) return reject(err); |
| 125 | + return resolve(); |
| 126 | + }); |
| 127 | + }); |
| 128 | + |
| 129 | + await new Promise((resolve, reject) => { |
| 130 | + clientAdmin.generateAccountAccessKey( |
103 | 131 | account2Name, |
104 | | - () => next(), |
105 | | - { externalAccessKey: externalAccessKey2, externalSecretKey: externalSecretKey2 }, |
106 | | - ), |
107 | | - next => { |
108 | | - iamAccount2Client = VaultClient.getIamClient(externalAccessKey2, externalSecretKey2); |
109 | | - next(); |
110 | | - }, |
111 | | - next => iamAccount2Client.createUser({ UserName: userName }, next), |
112 | | - next => iamAccount2Client.createAccessKey( |
113 | | - { UserName: userName }, |
114 | | - (err, result) => { |
115 | | - if (err) { |
116 | | - return next(err); |
117 | | - } |
118 | | - stsClient = getSTSClient(result.AccessKey.AccessKeyId, result.AccessKey.SecretAccessKey); |
119 | | - return next(); |
| 132 | + (err) => { |
| 133 | + if (err) return reject(err); |
| 134 | + return resolve(); |
120 | 135 | }, |
121 | | - ), |
122 | | - // create allowAssumeRole policy and attach it to the user created above |
123 | | - next => iamAccount2Client.createPolicy({ |
124 | | - PolicyName: 'allowAssumeRolePolicy', |
125 | | - PolicyDocument: allowAssumeRolePolicy, |
126 | | - }, (err, result) => { |
127 | | - if (err) { |
128 | | - return next(err); |
129 | | - } |
130 | | - allowAssumeRolePolicyArn = result.Policy.Arn; |
131 | | - return iamAccount2Client.attachUserPolicy({ |
132 | | - UserName: userName, |
133 | | - PolicyArn: allowAssumeRolePolicyArn, |
134 | | - }, next); |
135 | | - }), |
136 | | - // get account1 s3 client, create 2 buckets and put 2 objects respectively |
137 | | - next => { |
138 | | - s3Account1Client = getS3Client(externalAccessKey1, externalSecretKey1); |
139 | | - next(); |
140 | | - }, |
141 | | - next => s3Account1Client.createBucket({ Bucket: bucket1 }, next), |
142 | | - next => s3Account1Client.putObject({ Bucket: bucket1, Key: 'file1' }, next), |
143 | | - next => s3Account1Client.createBucket({ Bucket: bucket2 }, next), |
144 | | - next => s3Account1Client.putObject({ Bucket: bucket2, Key: 'file1' }, next), |
145 | | - ], done); |
| 136 | + { externalAccessKey: externalAccessKey2, externalSecretKey: externalSecretKey2 }, |
| 137 | + ); |
| 138 | + }); |
| 139 | + |
| 140 | + iamAccount2Client = VaultClient.getIamClient(externalAccessKey2, externalSecretKey2); |
| 141 | + await iamAccount2Client.send(new CreateUserCommand({ UserName: userName })); |
| 142 | + const result = await iamAccount2Client.send(new CreateAccessKeyCommand({ UserName: userName })); |
| 143 | + stsClient = getSTSClient(result.AccessKey.AccessKeyId, result.AccessKey.SecretAccessKey); |
| 144 | + // create allowAssumeRole policy and attach it to the user created above |
| 145 | + const policyResult = await iamAccount2Client.send(new CreatePolicyCommand({ |
| 146 | + PolicyName: 'allowAssumeRolePolicy', |
| 147 | + PolicyDocument: allowAssumeRolePolicy, |
| 148 | + })); |
| 149 | + allowAssumeRolePolicyArn = policyResult.Policy.Arn; |
| 150 | + await iamAccount2Client.send(new AttachUserPolicyCommand({ |
| 151 | + UserName: userName, |
| 152 | + PolicyArn: allowAssumeRolePolicyArn, |
| 153 | + })); |
| 154 | + |
| 155 | + // get account1 s3 client, create 2 buckets and put 2 objects respectively |
| 156 | + s3Account1Client = getS3Client(externalAccessKey1, externalSecretKey1); |
| 157 | + await s3Account1Client.send(new CreateBucketCommand({ Bucket: bucket1 })); |
| 158 | + await s3Account1Client.send(new PutObjectCommand({ Bucket: bucket1, Key: 'file1' })); |
| 159 | + await s3Account1Client.send(new CreateBucketCommand({ Bucket: bucket2 })); |
| 160 | + await s3Account1Client.send(new PutObjectCommand({ Bucket: bucket2, Key: 'file1' })); |
146 | 161 | }); |
147 | 162 |
|
148 | | - after(done => { |
149 | | - async.series([ |
150 | | - next => s3Account1Client.deleteObject({ |
151 | | - Bucket: bucket1, |
152 | | - Key: 'file1', |
153 | | - }, next), |
154 | | - next => s3Account1Client.deleteObject({ |
155 | | - Bucket: bucket2, |
156 | | - Key: 'file1', |
157 | | - }, next), |
158 | | - next => s3Account1Client.deleteBucket({ Bucket: bucket1 }, next), |
159 | | - next => s3Account1Client.deleteBucket({ Bucket: bucket2 }, next), |
160 | | - next => VaultClient.deleteVaultAccount(clientAdmin, iamAccount1Client, account1Name, next), |
161 | | - next => VaultClient.deleteVaultAccount(clientAdmin, iamAccount2Client, account2Name, next), |
162 | | - ], done); |
| 163 | + after(async () => { |
| 164 | + await s3Account1Client.send(new DeleteObjectCommand({ |
| 165 | + Bucket: bucket1, |
| 166 | + Key: 'file1', |
| 167 | + })); |
| 168 | + await s3Account1Client.send(new DeleteObjectCommand({ |
| 169 | + Bucket: bucket2, |
| 170 | + Key: 'file1', |
| 171 | + })); |
| 172 | + await s3Account1Client.send(new DeleteBucketCommand({ Bucket: bucket1 })); |
| 173 | + await s3Account1Client.send(new DeleteBucketCommand({ Bucket: bucket2 })); |
| 174 | + await VaultClient.deleteVaultAccount(clientAdmin, iamAccount1Client, account1Name); |
| 175 | + await VaultClient.deleteVaultAccount(clientAdmin, iamAccount2Client, account2Name); |
163 | 176 | }); |
164 | 177 |
|
165 | | - function cleanUp(roleName, policyArn, err, done) { |
166 | | - return async.series([ |
167 | | - next => iamAccount1Client.detachRolePolicy({ |
| 178 | + async function cleanUp(roleName, policyArn, err) { |
| 179 | + try { |
| 180 | + await iamAccount1Client.send(new DetachRolePolicyCommand({ |
168 | 181 | RoleName: roleName, PolicyArn: policyArn, |
169 | | - }, next), |
170 | | - next => iamAccount1Client.deletePolicy({ PolicyArn: policyArn }, next), |
171 | | - next => iamAccount1Client.deleteRole({ RoleName: roleName }, next), |
172 | | - ], _err => { |
173 | | - if (err) { |
174 | | - return done(err); |
175 | | - } |
176 | | - if (_err) { |
177 | | - return done(_err); |
178 | | - } |
179 | | - return done(); |
180 | | - }); |
| 182 | + })); |
| 183 | + await iamAccount1Client.send(new DeletePolicyCommand({ PolicyArn: policyArn })); |
| 184 | + await iamAccount1Client.send(new DeleteRoleCommand({ RoleName: roleName })); |
| 185 | + } catch (cleanupErr) { |
| 186 | + if (err) throw err; |
| 187 | + throw cleanupErr; |
| 188 | + } |
| 189 | + if (err) throw err; |
181 | 190 | } |
182 | 191 |
|
183 | 192 | const tests = [ |
@@ -314,55 +323,58 @@ testAPIs.forEach(testAPI => { |
314 | 323 | tests.forEach((test, i) => { |
315 | 324 | it( |
316 | 325 | test.name, |
317 | | - done => { |
| 326 | + async () => { |
318 | 327 | const roleName = `test-role-${i}`; |
319 | 328 | const policyName = `test-policy-${i}`; |
320 | 329 | let policyArn = null; |
321 | | - async.series([ |
| 330 | + |
| 331 | + try { |
322 | 332 | // create a role under account1 and attach different policy to it |
323 | | - next => iamAccount1Client.createRole({ |
| 333 | + await iamAccount1Client.send(new CreateRoleCommand({ |
324 | 334 | RoleName: roleName, |
325 | 335 | AssumeRolePolicyDocument: trustPolicy, |
326 | | - }, next), |
327 | | - next => iamAccount1Client.createPolicy({ |
| 336 | + })); |
| 337 | + |
| 338 | + const res = await iamAccount1Client.send(new CreatePolicyCommand({ |
328 | 339 | PolicyName: policyName, |
329 | 340 | PolicyDocument: JSON.stringify(test.policy), |
330 | | - }, (err, res) => { |
331 | | - if (err) { |
332 | | - return done(err); |
333 | | - } |
334 | | - policyArn = res.Policy.Arn; |
335 | | - return iamAccount1Client.attachRolePolicy({ |
336 | | - RoleName: roleName, |
337 | | - PolicyArn: policyArn, |
338 | | - }, next); |
339 | | - }), |
| 341 | + })); |
| 342 | + policyArn = res.Policy.Arn; |
| 343 | + await iamAccount1Client.send(new AttachRolePolicyCommand({ |
| 344 | + RoleName: roleName, |
| 345 | + PolicyArn: policyArn, |
| 346 | + })); |
| 347 | + |
340 | 348 | // user under account2 assume the role under account1 |
341 | | - next => stsClient.assumeRole({ |
| 349 | + const assumeRoleRes = await stsClient.send(new AssumeRoleCommand({ |
342 | 350 | RoleArn: `arn:aws:iam::${iamAccount1Id}:role/${roleName}`, |
343 | 351 | RoleSessionName: 'test-session', |
344 | | - }, (err, res) => { |
345 | | - if (err) { |
346 | | - return done(err); |
347 | | - } |
348 | | - const sessionUserCredentials = { |
349 | | - accessKeyId: res.Credentials.AccessKeyId, |
350 | | - secretAccessKey: res.Credentials.SecretAccessKey, |
351 | | - sessionToken: res.Credentials.SessionToken, |
352 | | - }; |
353 | | - return async.eachOf(test.buckets, (bucket, idx, eachCb) => { |
354 | | - // make request on specific buckets using session user's credentials |
355 | | - // and see if can get the correct response |
356 | | - testAPI.checkResponse(sessionUserCredentials, bucket, (err, res) => { |
357 | | - if (err) { |
358 | | - assert.ifError(err); |
359 | | - return done(err); |
360 | | - } |
361 | | - test.assertions[idx](res); |
362 | | - return eachCb(); |
363 | | - }, 'file1'); |
364 | | - }, next); |
365 | | - })], err => cleanUp(roleName, policyArn, err, done)); |
| 352 | + })); |
| 353 | + |
| 354 | + const sessionUserCredentials = { |
| 355 | + accessKeyId: assumeRoleRes.Credentials.AccessKeyId, |
| 356 | + secretAccessKey: assumeRoleRes.Credentials.SecretAccessKey, |
| 357 | + sessionToken: assumeRoleRes.Credentials.SessionToken, |
| 358 | + }; |
| 359 | + |
| 360 | + // Test each bucket |
| 361 | + const results = await Promise.all(test.buckets.map(bucket => new Promise((resolve, reject) => { |
| 362 | + // make request on specific buckets using session user's credentials |
| 363 | + // and see if can get the correct response |
| 364 | + testAPI.checkResponse(sessionUserCredentials, bucket, (err, res) => { |
| 365 | + if (err) return reject(err); |
| 366 | + return resolve(res); |
| 367 | + }, 'file1'); |
| 368 | + }))); |
| 369 | + |
| 370 | + results.forEach((result, idx) => { |
| 371 | + test.assertions[idx](result); |
| 372 | + }); |
| 373 | + |
| 374 | + await cleanUp(roleName, policyArn); |
| 375 | + } catch (err) { |
| 376 | + await cleanUp(roleName, policyArn, err); |
| 377 | + } |
366 | 378 | }, |
367 | 379 | ); |
368 | 380 | }); |
|
0 commit comments