mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* RBAC: Move access control evaluator to acimpl package * RBAC: Move service to acimpl package
143 lines
4.1 KiB
Go
143 lines
4.1 KiB
Go
package acimpl
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol/api"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
func ProvideService(cfg *setting.Cfg, store accesscontrol.Store, routeRegister routing.RouteRegister) (*Service, error) {
|
|
service := ProvideOSSService(cfg, store)
|
|
|
|
if !accesscontrol.IsDisabled(cfg) {
|
|
api.NewAccessControlAPI(routeRegister, service).RegisterAPIEndpoints()
|
|
if err := accesscontrol.DeclareFixedRoles(service); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return service, nil
|
|
}
|
|
|
|
func ProvideOSSService(cfg *setting.Cfg, store accesscontrol.Store) *Service {
|
|
s := &Service{
|
|
cfg: cfg,
|
|
store: store,
|
|
log: log.New("accesscontrol.service"),
|
|
roles: accesscontrol.BuildBasicRoleDefinitions(),
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// Service is the service implementing role based access control.
|
|
type Service struct {
|
|
log log.Logger
|
|
cfg *setting.Cfg
|
|
store accesscontrol.Store
|
|
registrations accesscontrol.RegistrationList
|
|
roles map[string]*accesscontrol.RoleDTO
|
|
}
|
|
|
|
func (s *Service) GetUsageStats(_ context.Context) map[string]interface{} {
|
|
enabled := 0
|
|
if !accesscontrol.IsDisabled(s.cfg) {
|
|
enabled = 1
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
"stats.oss.accesscontrol.enabled.count": enabled,
|
|
}
|
|
}
|
|
|
|
var actionsToFetch = append(
|
|
ossaccesscontrol.TeamAdminActions, append(ossaccesscontrol.DashboardAdminActions, ossaccesscontrol.FolderAdminActions...)...,
|
|
)
|
|
|
|
// GetUserPermissions returns user permissions based on built-in roles
|
|
func (s *Service) GetUserPermissions(ctx context.Context, user *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
|
|
timer := prometheus.NewTimer(metrics.MAccessPermissionsSummary)
|
|
defer timer.ObserveDuration()
|
|
|
|
permissions := make([]accesscontrol.Permission, 0)
|
|
|
|
for _, builtin := range accesscontrol.GetOrgRoles(user) {
|
|
if basicRole, ok := s.roles[builtin]; ok {
|
|
permissions = append(permissions, basicRole.Permissions...)
|
|
}
|
|
}
|
|
|
|
dbPermissions, err := s.store.GetUserPermissions(ctx, accesscontrol.GetUserPermissionsQuery{
|
|
OrgID: user.OrgID,
|
|
UserID: user.UserID,
|
|
Roles: accesscontrol.GetOrgRoles(user),
|
|
TeamIDs: user.Teams,
|
|
Actions: actionsToFetch,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return append(permissions, dbPermissions...), nil
|
|
}
|
|
|
|
func (s *Service) DeleteUserPermissions(ctx context.Context, orgID int64, userID int64) error {
|
|
return s.store.DeleteUserPermissions(ctx, orgID, userID)
|
|
}
|
|
|
|
// DeclareFixedRoles allow the caller to declare, to the service, fixed roles and their assignments
|
|
// to organization roles ("Viewer", "Editor", "Admin") or "Grafana Admin"
|
|
func (s *Service) DeclareFixedRoles(registrations ...accesscontrol.RoleRegistration) error {
|
|
// If accesscontrol is disabled no need to register roles
|
|
if accesscontrol.IsDisabled(s.cfg) {
|
|
return nil
|
|
}
|
|
|
|
for _, r := range registrations {
|
|
err := accesscontrol.ValidateFixedRole(r.Role)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = accesscontrol.ValidateBuiltInRoles(r.Grants)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.registrations.Append(r)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RegisterFixedRoles registers all declared roles in RAM
|
|
func (s *Service) RegisterFixedRoles(ctx context.Context) error {
|
|
// If accesscontrol is disabled no need to register roles
|
|
if accesscontrol.IsDisabled(s.cfg) {
|
|
return nil
|
|
}
|
|
s.registrations.Range(func(registration accesscontrol.RoleRegistration) bool {
|
|
for br := range accesscontrol.BuiltInRolesWithParents(registration.Grants) {
|
|
if basicRole, ok := s.roles[br]; ok {
|
|
basicRole.Permissions = append(basicRole.Permissions, registration.Role.Permissions...)
|
|
} else {
|
|
s.log.Error("Unknown builtin role", "builtInRole", br)
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) IsDisabled() bool {
|
|
return accesscontrol.IsDisabled(s.cfg)
|
|
}
|