@@ -43,6 +43,15 @@ func (r *RBAC) CreateRole(ctx context.Context, name, description string) error {
4343 if n == "" {
4444 return ErrInvalidName
4545 }
46+
47+ exists , err := r .roleNameExists (ctx , n )
48+ if err != nil {
49+ return err
50+ }
51+ if exists {
52+ return ErrDuplicateRole
53+ }
54+
4655 role := Role {ID : uuid .New ().String (), Name : n , Description : description }
4756 return r .store .CreateRole (ctx , role )
4857}
@@ -51,6 +60,19 @@ func (r *RBAC) RemoveRole(ctx context.Context, roleID string) error {
5160 if err := validateUUIDs (roleID ); err != nil {
5261 return err
5362 }
63+
64+ if _ , err := r .store .GetRole (ctx , roleID ); err != nil {
65+ return ErrNotFound
66+ }
67+
68+ inUse , err := r .isRoleInUse (ctx , roleID )
69+ if err != nil {
70+ return err
71+ }
72+ if inUse {
73+ return ErrRoleInUse
74+ }
75+
5476 return r .store .RemoveRole (ctx , roleID )
5577}
5678
@@ -60,6 +82,15 @@ func (r *RBAC) CreatePermission(ctx context.Context, resource, action string) er
6082 if res == "" || a == "" {
6183 return ErrInvalidResourceOrAction
6284 }
85+
86+ exists , err := r .permissionExists (ctx , res , a )
87+ if err != nil {
88+ return err
89+ }
90+ if exists {
91+ return ErrDuplicatePermission
92+ }
93+
6394 p := Permission {ID : uuid .New ().String (), Resource : res , Action : a }
6495 return r .store .CreatePermission (ctx , p )
6596}
@@ -68,20 +99,64 @@ func (r *RBAC) RemovePermission(ctx context.Context, permID string) error {
6899 if err := validateUUIDs (permID ); err != nil {
69100 return err
70101 }
102+
103+ if _ , err := r .store .GetPermission (ctx , permID ); err != nil {
104+ return ErrNotFound
105+ }
106+
107+ inUse , err := r .isPermissionInUse (ctx , permID )
108+ if err != nil {
109+ return err
110+ }
111+ if inUse {
112+ return ErrPermissionInUse
113+ }
114+
71115 return r .store .RemovePermission (ctx , permID )
72116}
73117
74118func (r * RBAC ) AssignRole (ctx context.Context , subjectID , roleID string ) error {
75119 if err := validateUUIDs (roleID ); err != nil {
76120 return err
77121 }
122+
123+ if _ , err := r .store .GetRole (ctx , roleID ); err != nil {
124+ return ErrNotFound
125+ }
126+
127+ roles , err := r .store .ListSubjectRoles (ctx , subjectID )
128+ if err != nil {
129+ return err
130+ }
131+ for _ , role := range roles {
132+ if role .ID == roleID {
133+ return ErrAlreadyExists
134+ }
135+ }
136+
78137 return r .store .AssignRole (ctx , subjectID , roleID )
79138}
80139
81140func (r * RBAC ) RevokeRole (ctx context.Context , subjectID , roleID string ) error {
82141 if err := validateUUIDs (roleID ); err != nil {
83142 return err
84143 }
144+
145+ roles , err := r .store .ListSubjectRoles (ctx , subjectID )
146+ if err != nil {
147+ return err
148+ }
149+ found := false
150+ for _ , role := range roles {
151+ if role .ID == roleID {
152+ found = true
153+ break
154+ }
155+ }
156+ if ! found {
157+ return ErrNotFound
158+ }
159+
85160 return r .store .RevokeRole (ctx , subjectID , roleID )
86161}
87162
@@ -91,14 +166,14 @@ func (r *RBAC) AddPermissionToRole(ctx context.Context, roleID, permID string) e
91166 }
92167 role , err := r .store .GetRole (ctx , roleID )
93168 if err != nil {
94- return err
169+ return ErrNotFound
95170 }
96171 if r .roleHasPermission (& role , permID ) {
97172 return ErrAlreadyExists
98173 }
99174 p , err := r .store .GetPermission (ctx , permID )
100175 if err != nil {
101- return err
176+ return ErrNotFound
102177 }
103178 role .Permissions = append (role .Permissions , p )
104179 return r .store .UpdateRole (ctx , role )
@@ -110,8 +185,13 @@ func (r *RBAC) RemovePermissionFromRole(ctx context.Context, roleID, permID stri
110185 }
111186 role , err := r .store .GetRole (ctx , roleID )
112187 if err != nil {
113- return err
188+ return ErrNotFound
114189 }
190+
191+ if ! r .roleHasPermission (& role , permID ) {
192+ return ErrNotFound
193+ }
194+
115195 role .Permissions = r .filterOutPermission (role .Permissions , permID )
116196 return r .store .UpdateRole (ctx , role )
117197}
@@ -132,6 +212,22 @@ func (r *RBAC) RevokeSubjectGrant(ctx context.Context, subjectID, grantID string
132212 if err := validateUUIDs (grantID ); err != nil {
133213 return err
134214 }
215+
216+ grants , err := r .store .ListSubjectGrants (ctx , subjectID )
217+ if err != nil {
218+ return err
219+ }
220+ found := false
221+ for _ , grant := range grants {
222+ if grant .ID == grantID {
223+ found = true
224+ break
225+ }
226+ }
227+ if ! found {
228+ return ErrNotFound
229+ }
230+
135231 return r .store .RevokeSubjectGrant (ctx , subjectID , grantID )
136232}
137233
@@ -212,3 +308,70 @@ func validateUUIDs(ids ...string) error {
212308 }
213309 return nil
214310}
311+
312+
313+ func (r * RBAC ) roleNameExists (ctx context.Context , name string ) (bool , error ) {
314+ roles , err := r .store .ListRoles (ctx )
315+ if err != nil {
316+ return false , err
317+ }
318+ for _ , role := range roles {
319+ if role .Name == name {
320+ return true , nil
321+ }
322+ }
323+ return false , nil
324+ }
325+
326+
327+ func (r * RBAC ) permissionExists (ctx context.Context , resource , action string ) (bool , error ) {
328+ perms , err := r .store .ListPermissions (ctx )
329+ if err != nil {
330+ return false , err
331+ }
332+ for _ , p := range perms {
333+ if p .Resource != resource {
334+ continue
335+ }
336+ if p .Action != action {
337+ continue
338+ }
339+ return true , nil
340+ }
341+ return false , nil
342+ }
343+
344+
345+ func (r * RBAC ) isRoleInUse (ctx context.Context , roleID string ) (bool , error ) {
346+ subjects , err := r .store .ListSubjects (ctx )
347+ if err != nil {
348+ return false , err
349+ }
350+ for _ , subjectID := range subjects {
351+ roles , err := r .store .ListSubjectRoles (ctx , subjectID )
352+ if err != nil {
353+ return false , err
354+ }
355+ for _ , role := range roles {
356+ if role .ID == roleID {
357+ return true , nil
358+ }
359+ }
360+ }
361+ return false , nil
362+ }
363+
364+ func (r * RBAC ) isPermissionInUse (ctx context.Context , permID string ) (bool , error ) {
365+ roles , err := r .store .ListRoles (ctx )
366+ if err != nil {
367+ return false , err
368+ }
369+ for _ , role := range roles {
370+ for _ , p := range role .Permissions {
371+ if p .ID == permID {
372+ return true , nil
373+ }
374+ }
375+ }
376+ return false , nil
377+ }
0 commit comments