@@ -8,6 +8,7 @@ package cluster
88
99import (
1010 "fmt"
11+ "slices"
1112 "strings"
1213
1314 "github.com/signal18/replication-manager/config"
@@ -21,9 +22,42 @@ type APIUser struct {
2122 Password string `json:"-"`
2223 GitToken string `json:"-"`
2324 GitUser string `json:"-"`
25+ Roles map [string ]bool `json:"roles"`
2426 Grants map [string ]bool `json:"grants"`
2527}
2628
29+ func (cluster * Cluster ) SetNewUserGrants (u * APIUser , grant string ) {
30+ acls := strings .Split (grant , " " )
31+ for key , value := range cluster .Grants {
32+ found := false
33+ for _ , acl := range acls {
34+ if strings .HasPrefix (key , acl ) && acl != "" {
35+ found = true
36+ break
37+ }
38+ }
39+ u .Grants [value ] = found
40+ }
41+ }
42+
43+ func (cluster * Cluster ) SetNewUserRoles (u * APIUser , roles string ) {
44+ list := strings .Split (roles , " " )
45+
46+ if u .Grants [config .GrantGlobalGrant ] && roles == "" {
47+ u .Roles [config .RoleSysOps ] = true
48+ u .Roles [config .RoleDBOps ] = true
49+ return
50+ }
51+
52+ for key , value := range cluster .Roles {
53+ found := false
54+ if slices .Contains (list , key ) {
55+ found = true
56+ }
57+ u .Roles [value ] = found
58+ }
59+ }
60+
2761func (u * APIUser ) Granted (grant string ) error {
2862 if value , ok := u .Grants [grant ]; ok {
2963 if ! value {
@@ -59,19 +93,34 @@ func (cluster *Cluster) GetAPIUser(strUser string, strPassword string) (APIUser,
5993 return APIUser {}, fmt .Errorf ("user not found" )
6094}
6195
96+ func (cluster * Cluster ) SaveUserAcls (user string ) string {
97+ var aEnabledAcls []string
98+ for grant , value := range cluster .APIUsers [user ].Grants {
99+ if value {
100+ aEnabledAcls = append (aEnabledAcls , grant )
101+ }
102+ }
103+ return strings .Join (aEnabledAcls , " " )
104+ }
105+
106+ func (cluster * Cluster ) SaveUserRoles (user string ) string {
107+ var aEnabledRoles []string
108+ for grant , value := range cluster .APIUsers [user ].Roles {
109+ if value {
110+ aEnabledRoles = append (aEnabledRoles , grant )
111+ }
112+ }
113+ return strings .Join (aEnabledRoles , " " )
114+ }
115+
62116func (cluster * Cluster ) SaveAcls () {
63117 credentials := strings .Split (cluster .Conf .GetDecryptedValue ("api-credentials" )+ "," + cluster .Conf .GetDecryptedValue ("api-credentials-external" ), "," )
64118 var aUserAcls []string
65119 for _ , credential := range credentials {
66120 user , _ := misc .SplitPair (credential )
67- var aEnabledAcls []string
68- for grant , value := range cluster .APIUsers [user ].Grants {
69- if value {
70- aEnabledAcls = append (aEnabledAcls , grant )
71- }
72- }
73- enabledAclsCredential := user + ":" + strings .Join (aEnabledAcls , " " )
74- aUserAcls = append (aUserAcls , enabledAclsCredential )
121+ enabledAcls := cluster .SaveUserAcls (user )
122+ enabledRoles := cluster .SaveUserRoles (user )
123+ aUserAcls = append (aUserAcls , user + ":" + enabledAcls + ":" + enabledRoles )
75124 }
76125 cluster .Conf .APIUsersACLAllow = strings .Join (aUserAcls , "," )
77126 cluster .Conf .APIUsersACLDiscard = ""
@@ -92,28 +141,26 @@ func (cluster *Cluster) LoadAPIUsers() error {
92141 // fmt.Printf(cluster.Conf.Secrets["api-credentials"].Value + "," + cluster.Conf.Secrets["api-credentials-external"].Value)
93142 meUsers := make (map [string ]APIUser )
94143 for _ , credential := range credentials {
144+ // Assign User Credentials
95145 var newapiuser APIUser
96-
97146 newapiuser .User , newapiuser .Password = misc .SplitPair (credential )
98147 newapiuser .Password = cluster .Conf .GetDecryptedPassword ("api-credentials" , newapiuser .Password )
99- usersAllowACL := strings .Split (cluster .Conf .APIUsersACLAllow , "," )
100148 newapiuser .Grants = make (map [string ]bool )
149+ newapiuser .Roles = make (map [string ]bool )
150+
151+ // Assign Roles and ACLs
152+ usersAllowACL := strings .Split (cluster .Conf .APIUsersACLAllow , "," )
101153 for _ , userACL := range usersAllowACL {
102- useracl , listacls := misc .SplitPair (userACL )
103- acls := strings .Split (listacls , " " )
104- if useracl == newapiuser .User {
105- for key , value := range cluster .Grants {
106- found := false
107- for _ , acl := range acls {
108- if strings .HasPrefix (key , acl ) && acl != "" {
109- found = true
110- break
111- }
112- }
113- newapiuser .Grants [value ] = found
114- }
154+ useracl , listacls , listroles , listcluster := misc .SplitAcls (userACL )
155+ cluster_acls := strings .Split (listcluster , " " )
156+
157+ // For compatibility allow empty cluster list ACL
158+ if useracl == newapiuser .User && (listcluster == "" || slices .Contains (cluster_acls , cluster .Name )) {
159+ cluster .SetNewUserGrants (& newapiuser , listacls )
160+ cluster .SetNewUserRoles (& newapiuser , listroles )
115161 }
116162 }
163+
117164 usersDiscardACL := strings .Split (cluster .Conf .APIUsersACLDiscard , "," )
118165 for _ , userACL := range usersDiscardACL {
119166 useracl , listacls := misc .SplitPair (userACL )
0 commit comments