@@ -25,6 +25,7 @@ const test_bucket = 'bucket1';
25
25
const test_not_empty_bucket = 'notemptybucket' ;
26
26
const test_bucket_temp_dir = 'buckettempdir' ;
27
27
const test_bucket_invalid = 'bucket_invalid' ;
28
+ const test_bucket_iam_account = 'bucket-iam-account-can-access' ;
28
29
29
30
const tmp_fs_path = path . join ( TMP_PATH , 'test_bucketspace_fs' ) ;
30
31
const config_root = path . join ( tmp_fs_path , 'config_root' ) ;
@@ -191,6 +192,57 @@ function make_dummy_object_sdk() {
191
192
}
192
193
} ;
193
194
}
195
+
196
+ // account_user2 (copied from the dummy sdk)
197
+ // is the root account of account_iam_user1
198
+ const account_iam_user1 = {
199
+ _id : '65a8edc9bc5d5bbf9db71b94' ,
200
+ name : 'iam_user_1' ,
201
+
202
+ owner : dummy_object_sdk . requesting_account . _id ,
203
+ allow_bucket_creation : dummy_object_sdk . requesting_account . allow_bucket_creation ,
204
+ access_keys : [ {
205
+ access_key : 'a-abcdefghijklmn123459' ,
206
+ secret_key : 's-abcdefghijklmn123459Example'
207
+ } ] ,
208
+ nsfs_account_config : {
209
+ uid : dummy_object_sdk . requesting_account . nsfs_account_config . uid ,
210
+ gid : dummy_object_sdk . requesting_account . nsfs_account_config . gid ,
211
+ new_buckets_path : dummy_object_sdk . requesting_account . nsfs_account_config . new_buckets_path
212
+ } ,
213
+ creation_date : '2023-11-30T04:46:33.815Z' ,
214
+ } ;
215
+
216
+ // account_user2 (copied from the dummy sdk)
217
+ // is the root account of account_iam_user2
218
+ const account_iam_user2 = {
219
+ _id : '65a8edc9bc5d5bbf9db71b95' ,
220
+ name : 'iam_user_2' ,
221
+
222
+ owner : dummy_object_sdk . requesting_account . _id ,
223
+ allow_bucket_creation : dummy_object_sdk . requesting_account . allow_bucket_creation ,
224
+ access_keys : [ {
225
+ access_key : 'a-abcdefghijklmn123460' ,
226
+ secret_key : 's-abcdefghijklmn123460Example'
227
+ } ] ,
228
+ nsfs_account_config : {
229
+ uid : dummy_object_sdk . requesting_account . nsfs_account_config . uid ,
230
+ gid : dummy_object_sdk . requesting_account . nsfs_account_config . gid ,
231
+ new_buckets_path : dummy_object_sdk . requesting_account . nsfs_account_config . new_buckets_path
232
+ } ,
233
+ creation_date : '2023-12-30T04:46:33.815Z' ,
234
+ } ;
235
+
236
+ function make_dummy_object_sdk_for_account ( dummy_object_sdk_to_copy , account ) {
237
+ const dummy_object_sdk_for_account = _ . cloneDeep ( dummy_object_sdk_to_copy ) ;
238
+ dummy_object_sdk_for_account . requesting_account = account ;
239
+ dummy_object_sdk_for_account . requesting_account . name = new SensitiveString (
240
+ dummy_object_sdk_for_account . requesting_account . name ) ;
241
+ dummy_object_sdk_for_account . requesting_account . email = new SensitiveString (
242
+ dummy_object_sdk_for_account . requesting_account . email ) ;
243
+ return dummy_object_sdk_for_account ;
244
+ }
245
+
194
246
function make_invalid_dummy_object_sdk ( ) {
195
247
return {
196
248
requesting_account : {
@@ -216,7 +268,7 @@ mocha.describe('bucketspace_fs', function() {
216
268
await fs_utils . create_fresh_path ( `${ config_root } /${ dir } ` ) )
217
269
) ;
218
270
await fs_utils . create_fresh_path ( new_buckets_path ) ;
219
- for ( let account of [ account_user1 , account_user2 , account_user3 ] ) {
271
+ for ( let account of [ account_user1 , account_user2 , account_user3 , account_iam_user1 , account_iam_user2 ] ) {
220
272
account = await nc_mkm . encrypt_access_keys ( account ) ;
221
273
const account_path = get_config_file_path ( CONFIG_SUBDIRS . ACCOUNTS , account . name ) ;
222
274
const account_access_path = get_access_key_symlink_path ( CONFIG_SUBDIRS . ACCESS_KEYS , account . access_keys [ 0 ] . access_key ) ;
@@ -312,9 +364,23 @@ mocha.describe('bucketspace_fs', function() {
312
364
assert . ok ( err . rpc_code === 'UNAUTHORIZED' ) ;
313
365
}
314
366
} ) ;
367
+ mocha . it ( 'should fail - create bucket by iam account' , async function ( ) {
368
+ // currently we do not allow IAM accounts to create buckets
369
+ try {
370
+ const param = { name : test_bucket_iam_account } ;
371
+ const dummy_object_sdk_for_iam_account = make_dummy_object_sdk_for_account ( dummy_object_sdk , account_iam_user1 ) ;
372
+ await bucketspace_fs . create_bucket ( param , dummy_object_sdk_for_iam_account ) ;
373
+ assert . fail ( 'should have failed with UNAUTHORIZED bucket creation' ) ;
374
+ } catch ( err ) {
375
+ assert . ok ( err . rpc_code === 'UNAUTHORIZED' ) ;
376
+ }
377
+ } ) ;
315
378
mocha . after ( async function ( ) {
316
379
await fs_utils . folder_delete ( `${ new_buckets_path } /${ test_bucket } ` ) ;
317
- const file_path = get_config_file_path ( CONFIG_SUBDIRS . BUCKETS , test_bucket ) ;
380
+ await fs_utils . folder_delete ( `${ new_buckets_path } /${ test_bucket_iam_account } ` ) ;
381
+ let file_path = get_config_file_path ( CONFIG_SUBDIRS . BUCKETS , test_bucket ) ;
382
+ await fs_utils . file_delete ( file_path ) ;
383
+ file_path = get_config_file_path ( CONFIG_SUBDIRS . BUCKETS , test_bucket_iam_account ) ;
318
384
await fs_utils . file_delete ( file_path ) ;
319
385
} ) ;
320
386
} ) ;
@@ -333,6 +399,19 @@ mocha.describe('bucketspace_fs', function() {
333
399
const objects = await bucketspace_fs . list_buckets ( dummy_object_sdk ) ;
334
400
assert . equal ( objects . buckets . length , 1 ) ;
335
401
} ) ;
402
+ mocha . it ( 'list buckets - iam accounts' , async function ( ) {
403
+ // root account created a bucket
404
+
405
+ // account_iam_user2 can list the created bucket (the implicit policy - same root account)
406
+ const dummy_object_sdk_for_iam_account = make_dummy_object_sdk_for_account ( dummy_object_sdk , account_iam_user1 ) ;
407
+ const res = await bucketspace_fs . list_buckets ( dummy_object_sdk_for_iam_account ) ;
408
+ assert . equal ( res . buckets . length , 1 ) ;
409
+
410
+ // account_iam_user2 can list the created bucket (the implicit policy - same root account)
411
+ const dummy_object_sdk_for_iam_account2 = make_dummy_object_sdk_for_account ( dummy_object_sdk , account_iam_user2 ) ;
412
+ const res2 = await bucketspace_fs . list_buckets ( dummy_object_sdk_for_iam_account2 ) ;
413
+ assert . equal ( res2 . buckets . length , 1 ) ;
414
+ } ) ;
336
415
mocha . after ( async function ( ) {
337
416
await fs_utils . folder_delete ( `${ new_buckets_path } /${ test_bucket } ` ) ;
338
417
const file_path = get_config_file_path ( CONFIG_SUBDIRS . BUCKETS , test_bucket ) ;
@@ -413,6 +492,22 @@ mocha.describe('bucketspace_fs', function() {
413
492
}
414
493
await fs . promises . stat ( path . join ( new_buckets_path , param . name ) ) ;
415
494
} ) ;
495
+
496
+ mocha . it ( 'delete buckets - iam accounts (another IAM account deletes the bucket)' , async function ( ) {
497
+ // root account created the bucket
498
+ await create_bucket ( test_bucket_iam_account ) ;
499
+
500
+ // account_iam_user1 can see the bucket in the list
501
+ const dummy_object_sdk_for_account_iam_user1 = make_dummy_object_sdk_for_account ( dummy_object_sdk , account_iam_user1 ) ;
502
+ const res = await bucketspace_fs . list_buckets ( dummy_object_sdk_for_account_iam_user1 ) ;
503
+ assert . ok ( res . buckets . length > 0 ) ;
504
+ assert . ok ( res . buckets . some ( bucket => bucket . name . unwrap ( ) === test_bucket_iam_account ) ) ;
505
+
506
+ const param = { name : test_bucket_iam_account } ;
507
+ // account_iam_user2 can delete the created bucket (the implicit policy - same root account)
508
+ const dummy_object_sdk_for_account_iam_user2 = make_dummy_object_sdk_for_account ( dummy_object_sdk , account_iam_user2 ) ;
509
+ await bucketspace_fs . delete_bucket ( param , dummy_object_sdk_for_account_iam_user2 ) ;
510
+ } ) ;
416
511
} ) ;
417
512
mocha . describe ( 'set_bucket_versioning' , function ( ) {
418
513
mocha . before ( async function ( ) {
0 commit comments