grafana/pkg/services/accesscontrol/resource_manager.go
Karl Persson 3c659f1ea0
Access Control: Move part of access control database (#40483)
* Add accesscontrol migrations

* Add ResourceStore interface and related structs

* Add team/user/builtin-role

* Add accesscontrol database with functions to handle managed roles and
permissions

* Add ResourceManager

* Add GetUserPermissions

* Update pkg/services/accesscontrol/accesscontrol.go

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
2021-11-11 14:02:53 +01:00

110 lines
3.3 KiB
Go

package accesscontrol
import (
"context"
"fmt"
)
type ResourceManager struct {
resource string
actions []string
validActions map[string]struct{}
store ResourceStore
validator ResourceValidator
}
type ResourceValidator func(ctx context.Context, orgID int64, resourceID string) error
func NewResourceManager(resource string, actions []string, validator ResourceValidator, store ResourceStore) *ResourceManager {
validActions := make(map[string]struct{}, len(actions))
for _, a := range actions {
validActions[a] = struct{}{}
}
return &ResourceManager{
store: store,
actions: actions,
validActions: validActions,
resource: resource,
validator: validator,
}
}
func (r *ResourceManager) GetPermissions(ctx context.Context, orgID int64, resourceID string) ([]ResourcePermission, error) {
return r.store.GetResourcesPermissions(ctx, orgID, GetResourcesPermissionsQuery{
Actions: r.actions,
Resource: r.resource,
ResourceIDs: []string{resourceID},
})
}
func (r *ResourceManager) GetPermissionsByIds(ctx context.Context, orgID int64, resourceIDs []string) ([]ResourcePermission, error) {
return r.store.GetResourcesPermissions(ctx, orgID, GetResourcesPermissionsQuery{
Actions: r.actions,
Resource: r.resource,
ResourceIDs: resourceIDs,
})
}
func (r *ResourceManager) SetUserPermissions(ctx context.Context, orgID int64, resourceID string, actions []string, userID int64) ([]ResourcePermission, error) {
if !r.validateActions(actions) {
return nil, fmt.Errorf("invalid actions: %s", actions)
}
return r.store.SetUserResourcePermissions(ctx, orgID, userID, SetResourcePermissionsCommand{
Actions: actions,
Resource: r.resource,
ResourceID: resourceID,
})
}
func (r *ResourceManager) SetTeamPermission(ctx context.Context, orgID int64, resourceID string, actions []string, teamID int64) ([]ResourcePermission, error) {
if !r.validateActions(actions) {
return nil, fmt.Errorf("invalid action: %s", actions)
}
return r.store.SetTeamResourcePermissions(ctx, orgID, teamID, SetResourcePermissionsCommand{
Actions: actions,
Resource: r.resource,
ResourceID: resourceID,
})
}
func (r *ResourceManager) SetBuiltinRolePermissions(ctx context.Context, orgID int64, resourceID string, actions []string, builtinRole string) ([]ResourcePermission, error) {
if !r.validateActions(actions) {
return nil, fmt.Errorf("invalid action: %s", actions)
}
return r.store.SetBuiltinResourcePermissions(ctx, orgID, builtinRole, SetResourcePermissionsCommand{
Actions: actions,
Resource: r.resource,
ResourceID: resourceID,
})
}
func (r *ResourceManager) RemovePermission(ctx context.Context, orgID int64, resourceID string, permissionID int64) error {
return r.store.RemoveResourcePermission(ctx, orgID, RemoveResourcePermissionCommand{
Actions: r.actions,
Resource: r.resource,
ResourceID: resourceID,
PermissionID: permissionID,
})
}
// Validate will run supplied ResourceValidator
func (r *ResourceManager) Validate(ctx context.Context, orgID int64, resourceID string) error {
if r.validator != nil {
return r.validator(ctx, orgID, resourceID)
}
return nil
}
func (r *ResourceManager) validateActions(actions []string) bool {
for _, a := range actions {
if _, ok := r.validActions[a]; !ok {
return false
}
}
return true
}