RBAC: Add a function to delete external service roles (#68317)

* RBAC: Add function to delete external service roles

* Adding a test to the service

* Update pkg/services/accesscontrol/acimpl/service_test.go

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>

---------

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Gabriel MABILLE
2023-05-16 15:01:27 +02:00
committed by GitHub
co-authored by Ieva
parent 0612f1f87a
commit d7eea0d207
7 changed files with 251 additions and 3 deletions
@@ -2,6 +2,7 @@ package database
import (
"context"
"errors"
"fmt"
"testing"
@@ -189,3 +190,113 @@ func TestAccessControlStore_SaveExternalServiceRole(t *testing.T) {
})
}
}
func TestAccessControlStore_DeleteExternalServiceRole(t *testing.T) {
extID := "app1"
tests := []struct {
name string
init func(t *testing.T, ctx context.Context, s *AccessControlStore)
id string
wantErr bool
}{
{
name: "delete no role",
id: extID,
wantErr: false,
},
{
name: "delete local role",
init: func(t *testing.T, ctx context.Context, s *AccessControlStore) {
errSave := s.SaveExternalServiceRole(ctx, accesscontrol.SaveExternalServiceRoleCommand{
OrgID: 2,
ExternalServiceID: extID,
ServiceAccountID: 3,
Permissions: []accesscontrol.Permission{
{Action: "users:read", Scope: "users:id:1"},
{Action: "users:write", Scope: "users:id:1"},
},
})
require.NoError(t, errSave)
},
id: extID,
wantErr: false,
},
{
name: "delete global role",
init: func(t *testing.T, ctx context.Context, s *AccessControlStore) {
errSave := s.SaveExternalServiceRole(ctx, accesscontrol.SaveExternalServiceRoleCommand{
Global: true,
ExternalServiceID: extID,
ServiceAccountID: 3,
Permissions: []accesscontrol.Permission{
{Action: "users:read", Scope: "users:id:1"},
{Action: "users:write", Scope: "users:id:1"},
},
})
require.NoError(t, errSave)
},
id: extID,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
s := &AccessControlStore{
sql: db.InitTestDB(t),
}
if tt.init != nil {
tt.init(t, ctx, s)
}
roleID := int64(-1)
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
role, err := getRoleByUID(ctx, sess, extServiceRoleUID(tt.id))
if err != nil && !errors.Is(err, accesscontrol.ErrRoleNotFound) {
return err
}
if role != nil {
roleID = role.ID
}
return nil
})
require.NoError(t, err)
err = s.DeleteExternalServiceRole(ctx, tt.id)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
// Only check removal if the role existed before
if roleID == -1 {
return
}
// Assignments should be deleted
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
var assignment accesscontrol.UserRole
count, err := sess.Where("role_id = ?", roleID).Count(&assignment)
require.NoError(t, err)
require.Zero(t, count)
return nil
})
// Permissions should be deleted
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
var permission accesscontrol.Permission
count, err := sess.Where("role_id = ?", roleID).Count(&permission)
require.NoError(t, err)
require.Zero(t, count)
return nil
})
// Role should be deleted
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
storedRole, err := getRoleByUID(ctx, sess, extServiceRoleUID(tt.id))
require.ErrorIs(t, err, accesscontrol.ErrRoleNotFound)
require.Nil(t, storedRole)
return nil
})
})
}
}