2021-04-14 09:31:27 -05:00
package accesscontrol
2021-08-04 07:44:37 -05:00
import (
"fmt"
"strings"
"sync"
2021-07-02 07:43:12 -05:00
2021-08-04 07:44:37 -05:00
"github.com/grafana/grafana/pkg/models"
)
2021-04-23 08:44:42 -05:00
2021-08-25 08:11:22 -05:00
type RoleRegistry interface {
// RegisterFixedRoles registers all roles declared to AccessControl
RegisterFixedRoles ( ) error
}
2021-08-04 07:44:37 -05:00
// Roles definition
var (
2021-11-17 08:40:39 -06:00
datasourcesExplorerRole = RoleDTO {
2021-11-18 03:16:18 -06:00
Version : 3 ,
2021-11-17 08:40:39 -06:00
Name : datasourcesExplorer ,
DisplayName : "Data source explorer" ,
Description : "Enable the Explore feature. Data source permissions still apply; you can only query data sources for which you have query permissions." ,
2021-11-18 03:16:18 -06:00
Group : "Data sources" ,
2021-08-04 07:44:37 -05:00
Permissions : [ ] Permission {
{
Action : ActionDatasourcesExplore ,
} ,
2021-07-30 06:58:49 -05:00
} ,
2021-08-04 07:44:37 -05:00
}
2021-04-23 08:44:42 -05:00
2021-11-17 08:40:39 -06:00
ldapReaderRole = RoleDTO {
Name : ldapReader ,
DisplayName : "LDAP reader" ,
Description : "Read LDAP configuration and status." ,
2021-11-18 03:16:18 -06:00
Group : "LDAP" ,
Version : 3 ,
2021-08-04 07:44:37 -05:00
Permissions : [ ] Permission {
{
Action : ActionLDAPUsersRead ,
} ,
{
Action : ActionLDAPStatusRead ,
} ,
2021-06-14 10:36:48 -05:00
} ,
2021-08-04 07:44:37 -05:00
}
2021-06-14 10:36:48 -05:00
2021-11-17 08:40:39 -06:00
ldapWriterRole = RoleDTO {
Name : ldapWriter ,
DisplayName : "LDAP writer" ,
Description : "Read and update LDAP configuration and read LDAP status." ,
2021-11-18 03:16:18 -06:00
Group : "LDAP" ,
Version : 4 ,
2021-11-17 08:40:39 -06:00
Permissions : ConcatPermissions ( ldapReaderRole . Permissions , [ ] Permission {
2021-08-04 07:44:37 -05:00
{
Action : ActionLDAPUsersSync ,
} ,
{
Action : ActionLDAPConfigReload ,
} ,
} ) ,
}
2021-06-14 10:36:48 -05:00
2021-11-17 08:40:39 -06:00
orgUsersWriterRole = RoleDTO {
Name : orgUsersWriter ,
DisplayName : "Organization user writer" ,
Description : "Within a single organization, add a user, invite a user, read information about a user and their role, remove a user from that organization, or change the role of a user." ,
2021-11-18 03:16:18 -06:00
Group : "User administration (organizational)" ,
Version : 3 ,
2021-11-17 08:40:39 -06:00
Permissions : ConcatPermissions ( orgUsersReaderRole . Permissions , [ ] Permission {
2021-08-04 07:44:37 -05:00
{
2021-11-17 08:40:39 -06:00
Action : ActionOrgUsersAdd ,
Scope : ScopeUsersAll ,
2021-08-04 07:44:37 -05:00
} ,
{
2021-11-17 08:40:39 -06:00
Action : ActionOrgUsersRoleUpdate ,
Scope : ScopeUsersAll ,
2021-08-04 07:44:37 -05:00
} ,
2021-11-17 08:40:39 -06:00
{
Action : ActionOrgUsersRemove ,
Scope : ScopeUsersAll ,
} ,
} ) ,
2021-08-04 07:44:37 -05:00
}
2021-04-23 08:44:42 -05:00
2021-11-17 08:40:39 -06:00
orgUsersReaderRole = RoleDTO {
Name : orgUsersReader ,
DisplayName : "Organization user reader" ,
Description : "Read users within a single organization." ,
2021-11-18 03:16:18 -06:00
Group : "User administration (organizational)" ,
Version : 3 ,
2021-08-04 07:44:37 -05:00
Permissions : [ ] Permission {
{
Action : ActionOrgUsersRead ,
Scope : ScopeUsersAll ,
} ,
2021-07-30 06:58:49 -05:00
} ,
2021-08-04 07:44:37 -05:00
}
2021-04-23 08:44:42 -05:00
2021-11-17 08:40:39 -06:00
settingsReaderRole = RoleDTO {
2021-11-18 03:16:18 -06:00
Version : 4 ,
2021-11-17 08:40:39 -06:00
DisplayName : "Setting reader" ,
Description : "Read Grafana instance settings." ,
2021-11-18 03:16:18 -06:00
Group : "Settings" ,
2021-11-17 08:40:39 -06:00
Name : settingsReader ,
Permissions : [ ] Permission {
2021-08-04 07:44:37 -05:00
{
2021-11-17 08:40:39 -06:00
Action : ActionSettingsRead ,
Scope : ScopeSettingsAll ,
2021-08-04 07:44:37 -05:00
} ,
2021-11-17 08:40:39 -06:00
} ,
}
statsReaderRole = RoleDTO {
2021-11-18 03:16:18 -06:00
Version : 3 ,
2021-11-17 08:40:39 -06:00
Name : statsReader ,
DisplayName : "Statistics reader" ,
Description : "Read Grafana instance statistics." ,
2021-11-18 03:16:18 -06:00
Group : "Statistics" ,
2021-11-17 08:40:39 -06:00
Permissions : [ ] Permission {
2021-08-04 07:44:37 -05:00
{
2021-11-17 08:40:39 -06:00
Action : ActionServerStatsRead ,
2021-08-04 07:44:37 -05:00
} ,
2021-11-17 08:40:39 -06:00
} ,
2021-08-04 07:44:37 -05:00
}
2021-04-23 08:44:42 -05:00
2021-11-17 08:40:39 -06:00
usersReaderRole = RoleDTO {
Name : usersReader ,
DisplayName : "User reader" ,
Description : "Read all users and their information, such as team memberships, authentication tokens, and quotas." ,
2021-11-18 03:16:18 -06:00
Group : "User administration (global)" ,
Version : 3 ,
2021-08-04 07:44:37 -05:00
Permissions : [ ] Permission {
{
Action : ActionUsersRead ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersTeamRead ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersAuthTokenList ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersQuotasList ,
Scope : ScopeGlobalUsersAll ,
} ,
2021-05-10 04:46:42 -05:00
} ,
2021-08-04 07:44:37 -05:00
}
2021-07-30 06:58:49 -05:00
2021-11-17 08:40:39 -06:00
usersWriterRole = RoleDTO {
Name : usersWriter ,
DisplayName : "User writer" ,
Description : "Read and update all attributes and settings for all users in Grafana: update user information, read user information, create or enable or disable a user, make a user a Grafana administrator, sign out a user, update a user’ s authentication token, or update quotas for all users." ,
2021-11-18 03:16:18 -06:00
Group : "User administration (global)" ,
Version : 3 ,
2021-11-17 08:40:39 -06:00
Permissions : ConcatPermissions ( usersReaderRole . Permissions , [ ] Permission {
2021-08-04 07:44:37 -05:00
{
Action : ActionUsersPasswordUpdate ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersCreate ,
} ,
{
Action : ActionUsersWrite ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersDelete ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersEnable ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersDisable ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersPermissionsUpdate ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersLogout ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersAuthTokenUpdate ,
Scope : ScopeGlobalUsersAll ,
} ,
{
Action : ActionUsersQuotasUpdate ,
Scope : ScopeGlobalUsersAll ,
} ,
} ) ,
}
)
2021-04-14 09:31:27 -05:00
2021-08-04 07:44:37 -05:00
// Role names definitions
2021-04-14 09:31:27 -05:00
const (
2021-11-17 08:40:39 -06:00
datasourcesExplorer = "fixed:datasources:explorer"
ldapReader = "fixed:ldap:reader"
ldapWriter = "fixed:ldap:writer"
orgUsersReader = "fixed:org.users:reader"
orgUsersWriter = "fixed:org.users:writer"
settingsReader = "fixed:settings:reader"
statsReader = "fixed:stats:reader"
usersReader = "fixed:users:reader"
usersWriter = "fixed:users:writer"
2021-07-30 02:52:09 -05:00
)
2021-04-23 08:44:42 -05:00
2021-08-04 07:44:37 -05:00
var (
// FixedRoles provides a map of permission sets/roles which can be
// assigned to a set of users. When adding a new resource protected by
// Grafana access control the default permissions should be added to a
// new fixed role in this set so that users can access the new
// resource. FixedRoleGrants lists which built-in roles are
// assigned which fixed roles in this list.
FixedRoles = map [ string ] RoleDTO {
2021-11-17 08:40:39 -06:00
datasourcesExplorer : datasourcesExplorerRole ,
ldapReader : ldapReaderRole ,
ldapWriter : ldapWriterRole ,
orgUsersReader : orgUsersReaderRole ,
orgUsersWriter : orgUsersWriterRole ,
settingsReader : settingsReaderRole ,
statsReader : statsReaderRole ,
usersReader : usersReaderRole ,
usersWriter : usersWriterRole ,
2021-08-04 07:44:37 -05:00
}
// FixedRoleGrants specifies which built-in roles are assigned
// to which set of FixedRoles by default. Alphabetically sorted.
FixedRoleGrants = map [ string ] [ ] string {
RoleGrafanaAdmin : {
2021-11-17 08:40:39 -06:00
ldapReader ,
ldapWriter ,
orgUsersReader ,
orgUsersWriter ,
settingsReader ,
statsReader ,
usersReader ,
usersWriter ,
2021-08-04 07:44:37 -05:00
} ,
string ( models . ROLE_ADMIN ) : {
2021-11-17 08:40:39 -06:00
orgUsersReader ,
orgUsersWriter ,
2021-08-04 07:44:37 -05:00
} ,
string ( models . ROLE_EDITOR ) : {
2021-11-17 08:40:39 -06:00
datasourcesExplorer ,
2021-08-04 07:44:37 -05:00
} ,
}
)
2021-07-30 06:58:49 -05:00
2021-04-27 11:22:18 -05:00
func ConcatPermissions ( permissions ... [ ] Permission ) [ ] Permission {
2021-04-23 08:44:42 -05:00
if permissions == nil {
return nil
}
perms := make ( [ ] Permission , 0 )
for _ , p := range permissions {
pCopy := make ( [ ] Permission , 0 , len ( p ) )
copy ( pCopy , p )
perms = append ( perms , p ... )
}
return perms
2021-04-14 09:31:27 -05:00
}
2021-08-04 07:44:37 -05:00
// ValidateFixedRole errors when a fixed role does not match expected pattern
func ValidateFixedRole ( role RoleDTO ) error {
if ! strings . HasPrefix ( role . Name , FixedRolePrefix ) {
return ErrFixedRolePrefixMissing
}
return nil
}
// ValidateBuiltInRoles errors when a built-in role does not match expected pattern
func ValidateBuiltInRoles ( builtInRoles [ ] string ) error {
for _ , br := range builtInRoles {
if ! models . RoleType ( br ) . IsValid ( ) && br != RoleGrafanaAdmin {
return fmt . Errorf ( "'%s' %w" , br , ErrInvalidBuiltinRole )
}
}
return nil
}
type RegistrationList struct {
mx sync . RWMutex
registrations [ ] RoleRegistration
}
func ( m * RegistrationList ) Append ( regs ... RoleRegistration ) {
m . mx . Lock ( )
defer m . mx . Unlock ( )
m . registrations = append ( m . registrations , regs ... )
}
func ( m * RegistrationList ) Range ( f func ( registration RoleRegistration ) bool ) {
m . mx . RLock ( )
defer m . mx . RUnlock ( )
for _ , registration := range m . registrations {
if ok := f ( registration ) ; ! ok {
return
}
}
}