mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Access Control: Store permissions on SignedInUser (#43040)
* add permission structure to signedinuser * add middleware to load user permissions into signedinuser struct * apply LoadPermissionsMiddleware to http server * check for permissions in signedinuser struct Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/plugincontext"
|
"github.com/grafana/grafana/pkg/plugins/plugincontext"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
|
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/cleanup"
|
"github.com/grafana/grafana/pkg/services/cleanup"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
@@ -440,6 +441,7 @@ func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() {
|
|||||||
|
|
||||||
m.Use(hs.ContextHandler.Middleware)
|
m.Use(hs.ContextHandler.Middleware)
|
||||||
m.Use(middleware.OrgRedirect(hs.Cfg))
|
m.Use(middleware.OrgRedirect(hs.Cfg))
|
||||||
|
m.Use(acmiddleware.LoadPermissionsMiddleware(hs.AccessControl))
|
||||||
|
|
||||||
// needs to be after context handler
|
// needs to be after context handler
|
||||||
if hs.Cfg.EnforceDomain {
|
if hs.Cfg.EnforceDomain {
|
||||||
|
|||||||
@@ -183,6 +183,8 @@ type SignedInUser struct {
|
|||||||
HelpFlags1 HelpFlags1
|
HelpFlags1 HelpFlags1
|
||||||
LastSeenAt time.Time
|
LastSeenAt time.Time
|
||||||
Teams []int64
|
Teams []int64
|
||||||
|
// Permissions grouped by orgID and actions
|
||||||
|
Permissions map[int64]map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *SignedInUser) ShouldUpdateLastSeenAt() bool {
|
func (u *SignedInUser) ShouldUpdateLastSeenAt() bool {
|
||||||
|
|||||||
@@ -97,14 +97,10 @@ func BuildPermissionsMap(permissions []*Permission) map[string]bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GroupScopesByAction will group scopes on action
|
// GroupScopesByAction will group scopes on action
|
||||||
func GroupScopesByAction(permissions []*Permission) map[string]map[string]struct{} {
|
func GroupScopesByAction(permissions []*Permission) map[string][]string {
|
||||||
m := make(map[string]map[string]struct{})
|
m := make(map[string][]string)
|
||||||
for _, p := range permissions {
|
for _, p := range permissions {
|
||||||
if _, ok := m[p.Action]; ok {
|
m[p.Action] = append(m[p.Action], p.Scope)
|
||||||
m[p.Action][p.Scope] = struct{}{}
|
|
||||||
} else {
|
|
||||||
m[p.Action] = map[string]struct{}{p.Scope: {}}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ var logger = log.New("accesscontrol.evaluator")
|
|||||||
|
|
||||||
type Evaluator interface {
|
type Evaluator interface {
|
||||||
// Evaluate permissions that are grouped by action
|
// Evaluate permissions that are grouped by action
|
||||||
Evaluate(permissions map[string]map[string]struct{}) (bool, error)
|
Evaluate(permissions map[string][]string) (bool, error)
|
||||||
// Inject params into the evaluator's templated scopes. e.g. "settings:" + eval.Parameters(":id") and returns a new Evaluator
|
// Inject params into the evaluator's templated scopes. e.g. "settings:" + eval.Parameters(":id") and returns a new Evaluator
|
||||||
Inject(params ScopeParams) (Evaluator, error)
|
Inject(params ScopeParams) (Evaluator, error)
|
||||||
// String returns a string representation of permission required by the evaluator
|
// String returns a string representation of permission required by the evaluator
|
||||||
@@ -32,7 +32,7 @@ type permissionEvaluator struct {
|
|||||||
Scopes []string
|
Scopes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p permissionEvaluator) Evaluate(permissions map[string]map[string]struct{}) (bool, error) {
|
func (p permissionEvaluator) Evaluate(permissions map[string][]string) (bool, error) {
|
||||||
userScopes, ok := permissions[p.Action]
|
userScopes, ok := permissions[p.Action]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, nil
|
return false, nil
|
||||||
@@ -46,7 +46,7 @@ func (p permissionEvaluator) Evaluate(permissions map[string]map[string]struct{}
|
|||||||
var err error
|
var err error
|
||||||
var matches bool
|
var matches bool
|
||||||
|
|
||||||
for scope := range userScopes {
|
for _, scope := range userScopes {
|
||||||
matches, err = match(scope, target)
|
matches, err = match(scope, target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -120,7 +120,7 @@ type allEvaluator struct {
|
|||||||
allOf []Evaluator
|
allOf []Evaluator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a allEvaluator) Evaluate(permissions map[string]map[string]struct{}) (bool, error) {
|
func (a allEvaluator) Evaluate(permissions map[string][]string) (bool, error) {
|
||||||
for _, e := range a.allOf {
|
for _, e := range a.allOf {
|
||||||
if ok, err := e.Evaluate(permissions); !ok || err != nil {
|
if ok, err := e.Evaluate(permissions); !ok || err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -160,7 +160,7 @@ type anyEvaluator struct {
|
|||||||
anyOf []Evaluator
|
anyOf []Evaluator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a anyEvaluator) Evaluate(permissions map[string]map[string]struct{}) (bool, error) {
|
func (a anyEvaluator) Evaluate(permissions map[string][]string) (bool, error) {
|
||||||
for _, e := range a.anyOf {
|
for _, e := range a.anyOf {
|
||||||
ok, err := e.Evaluate(permissions)
|
ok, err := e.Evaluate(permissions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,15 +10,7 @@ type evaluateTestCase struct {
|
|||||||
desc string
|
desc string
|
||||||
expected bool
|
expected bool
|
||||||
evaluator Evaluator
|
evaluator Evaluator
|
||||||
permissions map[string]map[string]struct{}
|
permissions map[string][]string
|
||||||
}
|
|
||||||
|
|
||||||
type injectTestCase struct {
|
|
||||||
desc string
|
|
||||||
expected bool
|
|
||||||
evaluator Evaluator
|
|
||||||
params ScopeParams
|
|
||||||
permissions map[string]map[string]struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPermission_Evaluate(t *testing.T) {
|
func TestPermission_Evaluate(t *testing.T) {
|
||||||
@@ -27,41 +19,32 @@ func TestPermission_Evaluate(t *testing.T) {
|
|||||||
desc: "should evaluate to true",
|
desc: "should evaluate to true",
|
||||||
expected: true,
|
expected: true,
|
||||||
evaluator: EvalPermission("reports:read", "reports:1"),
|
evaluator: EvalPermission("reports:read", "reports:1"),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "should evaluate to true when allEvaluator required scopes matches",
|
desc: "should evaluate to true when allEvaluator required scopes matches",
|
||||||
expected: true,
|
expected: true,
|
||||||
evaluator: EvalPermission("reports:read", "reports:1", "reports:2"),
|
evaluator: EvalPermission("reports:read", "reports:1", "reports:2"),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1", "reports:2"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
"reports:2": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "should evaluate to true for empty scope",
|
desc: "should evaluate to true for empty scope",
|
||||||
expected: true,
|
expected: true,
|
||||||
evaluator: EvalPermission("reports:read"),
|
evaluator: EvalPermission("reports:read"),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "should evaluate to false when only one of required scopes exists",
|
desc: "should evaluate to false when only one of required scopes exists",
|
||||||
expected: false,
|
expected: false,
|
||||||
evaluator: EvalPermission("reports:read", "reports:1", "reports:2"),
|
evaluator: EvalPermission("reports:read", "reports:1", "reports:2"),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -75,6 +58,14 @@ func TestPermission_Evaluate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type injectTestCase struct {
|
||||||
|
desc string
|
||||||
|
expected bool
|
||||||
|
evaluator Evaluator
|
||||||
|
params ScopeParams
|
||||||
|
permissions map[string][]string
|
||||||
|
}
|
||||||
|
|
||||||
func TestPermission_Inject(t *testing.T) {
|
func TestPermission_Inject(t *testing.T) {
|
||||||
tests := []injectTestCase{
|
tests := []injectTestCase{
|
||||||
{
|
{
|
||||||
@@ -84,10 +75,8 @@ func TestPermission_Inject(t *testing.T) {
|
|||||||
params: ScopeParams{
|
params: ScopeParams{
|
||||||
OrgID: 3,
|
OrgID: 3,
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"orgs:read": {
|
"orgs:read": {"orgs:3"},
|
||||||
"orgs:3": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -100,10 +89,8 @@ func TestPermission_Inject(t *testing.T) {
|
|||||||
":reportId": "1",
|
":reportId": "1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -111,10 +98,8 @@ func TestPermission_Inject(t *testing.T) {
|
|||||||
expected: false,
|
expected: false,
|
||||||
evaluator: EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
evaluator: EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
||||||
params: ScopeParams{},
|
params: ScopeParams{},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -127,10 +112,8 @@ func TestPermission_Inject(t *testing.T) {
|
|||||||
":reportId2": "report2",
|
":reportId2": "report2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:report:report2"},
|
||||||
"reports:report:report2": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -153,8 +136,8 @@ func TestAll_Evaluate(t *testing.T) {
|
|||||||
evaluator: EvalAll(
|
evaluator: EvalAll(
|
||||||
EvalPermission("settings:write", Scope("settings", "*")),
|
EvalPermission("settings:write", Scope("settings", "*")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
@@ -164,9 +147,9 @@ func TestAll_Evaluate(t *testing.T) {
|
|||||||
EvalPermission("settings:write", Scope("settings", "*")),
|
EvalPermission("settings:write", Scope("settings", "*")),
|
||||||
EvalPermission("settings:read", Scope("settings", "auth.saml", "*")),
|
EvalPermission("settings:read", Scope("settings", "auth.saml", "*")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
"settings:read": {"settings:*": struct{}{}},
|
"settings:read": {"settings:*"},
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
@@ -177,10 +160,10 @@ func TestAll_Evaluate(t *testing.T) {
|
|||||||
EvalPermission("settings:read", Scope("settings", "auth.saml", "*")),
|
EvalPermission("settings:read", Scope("settings", "auth.saml", "*")),
|
||||||
EvalPermission("report:read", Scope("reports", "*")),
|
EvalPermission("report:read", Scope("reports", "*")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
"settings:read": {"settings:*": struct{}{}},
|
"settings:read": {"settings:*"},
|
||||||
"report:read": {"report:1": struct{}{}},
|
"report:read": {"report:1"},
|
||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
@@ -211,13 +194,9 @@ func TestAll_Inject(t *testing.T) {
|
|||||||
":reportId": "1",
|
":reportId": "1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
"settings:read": {"settings:3"},
|
||||||
},
|
|
||||||
"settings:read": {
|
|
||||||
"settings:3": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -233,11 +212,8 @@ func TestAll_Inject(t *testing.T) {
|
|||||||
":orgId": "4",
|
":orgId": "4",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"orgs:read": {
|
"orgs:read": {"orgs:3", "orgs:4"},
|
||||||
"orgs:3": struct{}{},
|
|
||||||
"orgs:4": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -248,13 +224,9 @@ func TestAll_Inject(t *testing.T) {
|
|||||||
EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
||||||
),
|
),
|
||||||
params: ScopeParams{},
|
params: ScopeParams{},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
"settings:read": {"settings:3"},
|
||||||
},
|
|
||||||
"settings:read": {
|
|
||||||
"settings:3": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -277,8 +249,8 @@ func TestAny_Evaluate(t *testing.T) {
|
|||||||
evaluator: EvalAny(
|
evaluator: EvalAny(
|
||||||
EvalPermission("settings:write", Scope("settings", "*")),
|
EvalPermission("settings:write", Scope("settings", "*")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
@@ -289,8 +261,8 @@ func TestAny_Evaluate(t *testing.T) {
|
|||||||
EvalPermission("report:read", Scope("reports", "1")),
|
EvalPermission("report:read", Scope("reports", "1")),
|
||||||
EvalPermission("report:write", Scope("reports", "10")),
|
EvalPermission("report:write", Scope("reports", "10")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
@@ -301,8 +273,8 @@ func TestAny_Evaluate(t *testing.T) {
|
|||||||
EvalPermission("report:read", Scope("reports", "1")),
|
EvalPermission("report:read", Scope("reports", "1")),
|
||||||
EvalPermission("report:write", Scope("reports", "10")),
|
EvalPermission("report:write", Scope("reports", "10")),
|
||||||
),
|
),
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"permissions:write": {"permissions:delegate": struct{}{}},
|
"permissions:write": {"permissions:delegate"},
|
||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
@@ -333,13 +305,9 @@ func TestAny_Inject(t *testing.T) {
|
|||||||
":reportId": "1",
|
":reportId": "1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
"settings:read": {"settings:3"},
|
||||||
},
|
|
||||||
"settings:read": {
|
|
||||||
"settings:3": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -355,11 +323,8 @@ func TestAny_Inject(t *testing.T) {
|
|||||||
":orgId": "4",
|
":orgId": "4",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"orgs:read": {
|
"orgs:read": {"orgs:3", "orgs:4"},
|
||||||
"orgs:3": struct{}{},
|
|
||||||
"orgs:4": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -370,13 +335,9 @@ func TestAny_Inject(t *testing.T) {
|
|||||||
EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
EvalPermission("reports:read", Scope("reports", Parameter(":reportId"))),
|
||||||
),
|
),
|
||||||
params: ScopeParams{},
|
params: ScopeParams{},
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"reports:read": {
|
"reports:read": {"reports:1"},
|
||||||
"reports:1": struct{}{},
|
"settings:read": {"settings:3"},
|
||||||
},
|
|
||||||
"settings:read": {
|
|
||||||
"settings:3": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -396,7 +357,7 @@ type combinedTestCase struct {
|
|||||||
desc string
|
desc string
|
||||||
evaluator Evaluator
|
evaluator Evaluator
|
||||||
expected bool
|
expected bool
|
||||||
permissions map[string]map[string]struct{}
|
permissions map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEval(t *testing.T) {
|
func TestEval(t *testing.T) {
|
||||||
@@ -411,8 +372,8 @@ func TestEval(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
expected: true,
|
expected: true,
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {"settings:*": struct{}{}},
|
"settings:write": {"settings:*"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -425,11 +386,8 @@ func TestEval(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
expected: true,
|
expected: true,
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {
|
"settings:write": {"settings:auth.saml:enabled", "settings:auth.saml:max_issue_delay"},
|
||||||
"settings:auth.saml:enabled": struct{}{},
|
|
||||||
"settings:auth.saml:max_issue_delay": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -442,10 +400,8 @@ func TestEval(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
expected: false,
|
expected: false,
|
||||||
permissions: map[string]map[string]struct{}{
|
permissions: map[string][]string{
|
||||||
"settings:write": {
|
"settings:write": {"settings:auth.saml:enabled"},
|
||||||
"settings:auth.saml:enabled": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,3 +137,22 @@ func UseOrgFromContextParams(c *models.ReqContext) (int64, error) {
|
|||||||
func UseGlobalOrg(c *models.ReqContext) (int64, error) {
|
func UseGlobalOrg(c *models.ReqContext) (int64, error) {
|
||||||
return accesscontrol.GlobalOrgID, nil
|
return accesscontrol.GlobalOrgID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadPermissionsMiddleware(ac accesscontrol.AccessControl) web.Handler {
|
||||||
|
return func(c *models.ReqContext) {
|
||||||
|
if ac.IsDisabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions, err := ac.GetUserPermissions(c.Req.Context(), c.SignedInUser)
|
||||||
|
if err != nil {
|
||||||
|
c.JsonApiErr(http.StatusForbidden, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.SignedInUser.Permissions == nil {
|
||||||
|
c.SignedInUser.Permissions = make(map[int64]map[string][]string)
|
||||||
|
}
|
||||||
|
c.SignedInUser.Permissions[c.OrgId] = accesscontrol.GroupScopesByAction(permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,12 +64,19 @@ func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.Si
|
|||||||
defer timer.ObserveDuration()
|
defer timer.ObserveDuration()
|
||||||
metrics.MAccessEvaluationCount.Inc()
|
metrics.MAccessEvaluationCount.Inc()
|
||||||
|
|
||||||
permissions, err := ac.GetUserPermissions(ctx, user)
|
if user.Permissions == nil {
|
||||||
if err != nil {
|
user.Permissions = map[int64]map[string][]string{}
|
||||||
return false, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return evaluator.Evaluate(accesscontrol.GroupScopesByAction(permissions))
|
if _, ok := user.Permissions[user.OrgId]; !ok {
|
||||||
|
permissions, err := ac.GetUserPermissions(ctx, user)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
user.Permissions[user.OrgId] = accesscontrol.GroupScopesByAction(permissions)
|
||||||
|
}
|
||||||
|
|
||||||
|
return evaluator.Evaluate(user.Permissions[user.OrgId])
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserRoles returns user permissions based on built-in roles
|
// GetUserRoles returns user permissions based on built-in roles
|
||||||
|
|||||||
Reference in New Issue
Block a user