AccessControl: Remove scopes from orgs endpoints (#41709)
* AccessControl: Check permissions in target org * Remove org scopes and add an authorizeInOrg middleware * Use query result org id and perform users permission check globally for GetOrgByName * Remove scope translation for orgs current * Suggestion from Ieva
This commit is contained in:
@@ -7,11 +7,26 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
func authorize(c *models.ReqContext, ac accesscontrol.AccessControl, user *models.SignedInUser, evaluator accesscontrol.Evaluator) {
|
||||
injected, err := evaluator.Inject(buildScopeParams(c))
|
||||
if err != nil {
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Internal server error", err)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := ac.Evaluate(c.Req.Context(), user, injected)
|
||||
if !hasAccess || err != nil {
|
||||
Deny(c, injected, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func Middleware(ac accesscontrol.AccessControl) func(web.Handler, accesscontrol.Evaluator) web.Handler {
|
||||
return func(fallback web.Handler, evaluator accesscontrol.Evaluator) web.Handler {
|
||||
if ac.IsDisabled() {
|
||||
@@ -19,17 +34,7 @@ func Middleware(ac accesscontrol.AccessControl) func(web.Handler, accesscontrol.
|
||||
}
|
||||
|
||||
return func(c *models.ReqContext) {
|
||||
injected, err := evaluator.Inject(buildScopeParams(c))
|
||||
if err != nil {
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Internal server error", err)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := ac.Evaluate(c.Req.Context(), c.SignedInUser, injected)
|
||||
if !hasAccess || err != nil {
|
||||
Deny(c, injected, err)
|
||||
return
|
||||
}
|
||||
authorize(c, ac, c.SignedInUser, evaluator)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,3 +87,53 @@ func buildScopeParams(c *models.ReqContext) accesscontrol.ScopeParams {
|
||||
URLParams: web.Params(c.Req),
|
||||
}
|
||||
}
|
||||
|
||||
type OrgIDGetter func(c *models.ReqContext) (int64, error)
|
||||
|
||||
func AuthorizeInOrgMiddleware(ac accesscontrol.AccessControl, db *sqlstore.SQLStore) func(web.Handler, OrgIDGetter, accesscontrol.Evaluator) web.Handler {
|
||||
return func(fallback web.Handler, getTargetOrg OrgIDGetter, evaluator accesscontrol.Evaluator) web.Handler {
|
||||
if ac.IsDisabled() {
|
||||
return fallback
|
||||
}
|
||||
|
||||
return func(c *models.ReqContext) {
|
||||
// using a copy of the user not to modify the signedInUser, yet perform the permission evaluation in another org
|
||||
userCopy := *(c.SignedInUser)
|
||||
orgID, err := getTargetOrg(c)
|
||||
if err != nil {
|
||||
Deny(c, nil, fmt.Errorf("failed to get target org: %w", err))
|
||||
return
|
||||
}
|
||||
if orgID == accesscontrol.GlobalOrgID {
|
||||
userCopy.OrgId = orgID
|
||||
userCopy.OrgName = ""
|
||||
userCopy.OrgRole = ""
|
||||
} else {
|
||||
query := models.GetSignedInUserQuery{UserId: c.UserId, OrgId: orgID}
|
||||
if err := db.GetSignedInUserWithCacheCtx(c.Req.Context(), &query); err != nil {
|
||||
Deny(c, nil, fmt.Errorf("failed to authenticate user in target org: %w", err))
|
||||
return
|
||||
}
|
||||
userCopy.OrgId = query.Result.OrgId
|
||||
userCopy.OrgName = query.Result.OrgName
|
||||
userCopy.OrgRole = query.Result.OrgRole
|
||||
}
|
||||
|
||||
authorize(c, ac, &userCopy, evaluator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func UseOrgFromContextParams(c *models.ReqContext) (int64, error) {
|
||||
orgID := c.ParamsInt64(":orgId")
|
||||
// Special case of macaron handling invalid params
|
||||
if orgID == 0 {
|
||||
return 0, models.ErrOrgNotFound
|
||||
}
|
||||
|
||||
return orgID, nil
|
||||
}
|
||||
|
||||
func UseGlobalOrg(c *models.ReqContext) (int64, error) {
|
||||
return accesscontrol.GlobalOrgID, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user