github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/auth/acl/write.go (about) 1 package acl 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "time" 9 10 "github.com/hashicorp/go-multierror" 11 "github.com/treeverse/lakefs/pkg/auth" 12 "github.com/treeverse/lakefs/pkg/auth/model" 13 "github.com/treeverse/lakefs/pkg/logging" 14 ) 15 16 const ( 17 AdminsGroup = "Admins" 18 SupersGroup = "Supers" 19 WritersGroup = "Writers" 20 ReadersGroup = "Readers" 21 ) 22 23 func WriteGroupACL(ctx context.Context, svc auth.Service, groupName string, acl model.ACL, creationTime time.Time, warnIfCreate bool) error { 24 log := logging.FromContext(ctx).WithField("group", groupName) 25 26 statements, err := ACLToStatement(acl) 27 if err != nil { 28 return fmt.Errorf("%s: translate ACL %+v to statements: %w", groupName, acl, err) 29 } 30 31 aclPolicyName := PolicyName(groupName) 32 33 policy := &model.Policy{ 34 CreatedAt: creationTime, 35 DisplayName: aclPolicyName, 36 Statement: statements, 37 ACL: acl, 38 } 39 40 policyJSON, err := json.MarshalIndent(policy, "", " ") 41 if err != nil { 42 return err 43 } 44 45 log.WithField("policy", fmt.Sprintf("%+v", policy)). 46 WithField("policyJSON", string(policyJSON)). 47 Debug("Set policy derived from ACL") 48 49 err = svc.WritePolicy(ctx, policy, true) 50 if errors.Is(err, auth.ErrNotFound) { 51 if warnIfCreate { 52 log.WithField("group", groupName). 53 Info("Define an ACL for the first time because none was defined (bad migrate?)") 54 } 55 err = svc.WritePolicy(ctx, policy, false) 56 } 57 if err != nil { 58 return fmt.Errorf("write policy %s %+v for group %s: %w", aclPolicyName, policy, groupName, err) 59 } 60 61 // Detach any existing policies from group 62 existingPolicies, _, err := svc.ListGroupPolicies(ctx, groupName, &model.PaginationParams{ 63 Amount: -1, 64 }) 65 if err != nil { 66 return fmt.Errorf("list existing group policies for group %s: %w", groupName, err) 67 } 68 69 err = svc.AttachPolicyToGroup(ctx, aclPolicyName, groupName) 70 if errors.Is(err, auth.ErrAlreadyExists) { 71 err = nil 72 } 73 if err != nil { 74 return fmt.Errorf("attach policy %s to group %s: %w", aclPolicyName, groupName, err) 75 } 76 77 for _, existingPolicy := range existingPolicies { 78 if existingPolicy.DisplayName != aclPolicyName { 79 oneErr := svc.DetachPolicyFromGroup(ctx, existingPolicy.DisplayName, groupName) 80 if oneErr != nil { 81 err = multierror.Append( 82 err, 83 fmt.Errorf("detach policy %s from group %s: %w", existingPolicy.DisplayName, groupName, oneErr), 84 ) 85 } 86 } 87 } 88 if err != nil { 89 return err 90 } 91 return nil 92 }