4
4
"github.com/secrethub/secrethub-go/internals/api"
5
5
"github.com/secrethub/secrethub-go/internals/api/uuid"
6
6
"github.com/secrethub/secrethub-go/internals/errio"
7
+ "github.com/secrethub/secrethub-go/pkg/secrethub/iterator"
7
8
)
8
9
9
10
// AccessRuleService handles operations on access rules from SecretHub.
@@ -14,13 +15,20 @@ type AccessRuleService interface {
14
15
Set (path string , permission string , accountName string ) (* api.AccessRule , error )
15
16
// Delete removes the accessrule for the given directory and account.
16
17
Delete (path string , accountName string ) error
17
- // List etrieves all access rules that apply to a directory, including
18
+ // List retrieves all access rules that apply to a directory, including
18
19
// rules that apply to its children up to a specified depth. When ancestors is set
19
20
// to true, it also includes rules for any parent directories. When the depth is
20
21
// set to -1, all children are retrieved without limit.
22
+ // Deprecated: Use iterator function instead.
21
23
List (path string , depth int , ancestors bool ) ([]* api.AccessRule , error )
24
+ // Iterator returns an iterator that retrieves all access rules that apply to a
25
+ // directory.
26
+ Iterator (path string , _ * AccessRuleIteratorParams ) AccessRuleIterator
22
27
// ListLevels lists the access levels on the given directory.
28
+ // Deprecated: Use iterator function instead.
23
29
ListLevels (path string ) ([]* api.AccessLevel , error )
30
+ // LevelIterator returns an iterator that retrieves all access levels on the given directory.
31
+ LevelIterator (path string , _ * AccessLevelIteratorParams ) AccessLevelIterator
24
32
}
25
33
26
34
func newAccessRuleService (client * Client ) AccessRuleService {
@@ -87,7 +95,7 @@ func (s accessRuleService) Get(path string, accountName string) (*api.AccessRule
87
95
return accessRule , nil
88
96
}
89
97
90
- // List etrieves all access rules that apply to a directory, including
98
+ // List retrieves all access rules that apply to a directory, including
91
99
// rules that apply to its children up to a specified depth. When ancestors is set
92
100
// to true, it also includes rules for any parent directories. When the depth is
93
101
// set to -1, all children are retrieved without limit.
@@ -286,3 +294,157 @@ func (c *Client) getAccessLevel(path api.BlindNamePath, accountName api.AccountN
286
294
287
295
return accessLevel , nil
288
296
}
297
+
298
+ // Iterator returns an iterator that retrieves all access rules that apply to a
299
+ // directory.
300
+ func (s accessRuleService ) Iterator (path string , params * AccessRuleIteratorParams ) AccessRuleIterator {
301
+ if params == nil {
302
+ params = & AccessRuleIteratorParams {}
303
+ }
304
+
305
+ depth := - 1
306
+ if params .Depth != nil {
307
+ depth = int (* params .Depth )
308
+ }
309
+ ancestors := params .Ancestors
310
+
311
+ return & accessRuleIterator {
312
+ iterator : iterator .New (
313
+ iterator .PaginatorFactory (
314
+ func () ([]interface {}, error ) {
315
+ p , err := api .NewDirPath (path )
316
+ if err != nil {
317
+ return nil , errio .Error (err )
318
+ }
319
+
320
+ blindName , err := s .client .convertPathToBlindName (p )
321
+ if err != nil {
322
+ return nil , errio .Error (err )
323
+ }
324
+
325
+ accessRules , err := s .client .httpClient .ListAccessRules (blindName , depth , ancestors )
326
+ if err != nil {
327
+ return nil , errio .Error (err )
328
+ }
329
+
330
+ res := make ([]interface {}, len (accessRules ))
331
+ for i , element := range accessRules {
332
+ res [i ] = element
333
+ }
334
+ return res , nil
335
+ },
336
+ ),
337
+ ),
338
+ }
339
+ }
340
+
341
+ // LevelIterator returns an iterator that retrieves all access levels on the given directory.
342
+ func (s accessRuleService ) LevelIterator (path string , _ * AccessLevelIteratorParams ) AccessLevelIterator {
343
+ return & accessLevelIterator {
344
+ iterator : iterator .New (
345
+ iterator .PaginatorFactory (
346
+ func () ([]interface {}, error ) {
347
+ p , err := api .NewDirPath (path )
348
+ if err != nil {
349
+ return nil , errio .Error (err )
350
+ }
351
+
352
+ blindName , err := s .client .convertPathToBlindName (p )
353
+ if err != nil {
354
+ return nil , errio .Error (err )
355
+ }
356
+
357
+ rules , err := s .client .httpClient .ListAccessRules (blindName , 0 , true )
358
+ if err != nil {
359
+ return nil , errio .Error (err )
360
+ }
361
+
362
+ dir , err := s .dirService .GetTree (path , 0 , false )
363
+ if err != nil {
364
+ return nil , errio .Error (err )
365
+ }
366
+
367
+ rights := make (map [uuid.UUID ][]* api.AccessRule )
368
+ for _ , rule := range rules {
369
+ list := rights [rule .AccountID ]
370
+ rights [rule .AccountID ] = append (list , rule )
371
+ }
372
+
373
+ accessLevels := make ([]* api.AccessLevel , len (rights ))
374
+ i := 0
375
+ for _ , list := range rights {
376
+ first := list [0 ]
377
+ maxPerm := first .Permission
378
+ for _ , rule := range list {
379
+ if maxPerm < rule .Permission {
380
+ maxPerm = rule .Permission
381
+ }
382
+ }
383
+
384
+ accessLevels [i ] = & api.AccessLevel {
385
+ Account : first .Account ,
386
+ AccountID : first .AccountID ,
387
+ DirID : dir .RootDir .DirID , // add this for completeness
388
+ Permission : maxPerm ,
389
+ }
390
+
391
+ i ++
392
+ }
393
+
394
+ res := make ([]interface {}, len (accessLevels ))
395
+ for i , element := range accessLevels {
396
+ res [i ] = element
397
+ }
398
+ return res , nil
399
+ },
400
+ ),
401
+ ),
402
+ }
403
+ }
404
+
405
+ // AccessLevelIterator iterates over access rules.
406
+ type AccessRuleIterator interface {
407
+ Next () (api.AccessRule , error )
408
+ }
409
+
410
+ type accessRuleIterator struct {
411
+ iterator iterator.Iterator
412
+ }
413
+
414
+ // Next returns the next access rule or iterator.Done if all of them have been returned.
415
+ func (it * accessRuleIterator ) Next () (api.AccessRule , error ) {
416
+ item , err := it .iterator .Next ()
417
+ if err != nil {
418
+ return api.AccessRule {}, err
419
+ }
420
+
421
+ return * item .(* api.AccessRule ), nil
422
+ }
423
+
424
+ // AccessRuleIteratorParams specify parameters used when listing access rules.
425
+ type AccessRuleIteratorParams struct {
426
+ Depth * uint // Depth defines the depth of traversal for the iterator, nil means listing all subdirectories.
427
+ Ancestors bool // Ancestors defines whether the iterator should also list access rules of parent directories.
428
+ }
429
+
430
+ // AccessLevelIteratorParams defines the parameters used when listing access levels.
431
+ type AccessLevelIteratorParams struct {}
432
+
433
+ // AccessLevelIterator iterates over access levels.
434
+ type AccessLevelIterator interface {
435
+ Next () (api.AccessLevel , error )
436
+ }
437
+
438
+ type accessLevelIterator struct {
439
+ iterator iterator.Iterator
440
+ }
441
+
442
+ // Next returns the next access level or iterator.Done if all of them have been returned.
443
+ func (it * accessLevelIterator ) Next () (api.AccessLevel , error ) {
444
+ item , err := it .iterator .Next ()
445
+ if err != nil {
446
+ return api.AccessLevel {}, err
447
+ }
448
+
449
+ return * item .(* api.AccessLevel ), nil
450
+ }
0 commit comments