Access: Fetch fresh permissions for target GlobalOrgID in AuthorizeInOrgMiddleware (#76569)

fetch fresh permissions for global in AuthorizeInOrgMiddleware

Update pkg/services/accesscontrol/authorize_in_org_test.go

do not load viewer permissions in global ID
This commit is contained in:
Jo 2023-10-13 20:01:47 +02:00 committed by GitHub
parent 335b73d9ae
commit 48ef88aed7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 17 deletions

View File

@ -249,11 +249,11 @@ func TestAPIEndpoint_GetOrg(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: &user.SignedInUser{OrgID: 0}}
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: &user.SignedInUser{OrgID: 1}}
hs.accesscontrolService = &actest.FakeService{ExpectedPermissions: tt.permissions}
})
verify := func(path string) {
req := webtest.RequestWithSignedInUser(server.NewGetRequest(path), userWithPermissions(2, tt.permissions))
req := webtest.RequestWithSignedInUser(server.NewGetRequest(path), authedUserWithPermissions(1, 1, tt.permissions))
res, err := server.Send(req)
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, res.StatusCode)

View File

@ -35,16 +35,18 @@ func TestAuthorizeInOrgMiddleware(t *testing.T) {
expectedStatus int
}{
{
name: "should authorize user with global org ID - no fetch",
name: "should authorize user with global org ID - fetch",
orgIDGetter: func(c *contextmodel.ReqContext) (int64, error) {
return accesscontrol.GlobalOrgID, nil
},
evaluator: accesscontrol.EvalPermission("users:read", "users:*"),
accessControl: ac,
acService: &actest.FakeService{},
userCache: &usertest.FakeUserService{},
ctxSignedInUser: &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{1: {"users:read": {"users:*"}}}},
expectedStatus: http.StatusOK,
acService: &actest.FakeService{
ExpectedPermissions: []accesscontrol.Permission{{Action: "users:read", Scope: "users:*"}},
},
expectedStatus: http.StatusOK,
},
{
name: "should authorize user with non-global org ID - no fetch",
@ -70,6 +72,30 @@ func TestAuthorizeInOrgMiddleware(t *testing.T) {
acService: &actest.FakeService{},
expectedStatus: http.StatusForbidden,
},
{
name: "should return 200 when user has permissions for a global org",
orgIDGetter: func(c *contextmodel.ReqContext) (int64, error) {
return accesscontrol.GlobalOrgID, nil
},
evaluator: accesscontrol.EvalPermission("users:read", "users:*"),
accessControl: ac,
userCache: &usertest.FakeUserService{},
ctxSignedInUser: &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{accesscontrol.GlobalOrgID: {"users:read": {"users:*"}}}},
acService: &actest.FakeService{},
expectedStatus: http.StatusOK,
},
{
name: "should return 403 when user has no permissions for a global org",
orgIDGetter: func(c *contextmodel.ReqContext) (int64, error) {
return accesscontrol.GlobalOrgID, nil
},
evaluator: accesscontrol.EvalPermission("users:read", "users:*"),
accessControl: ac,
userCache: &usertest.FakeUserService{},
ctxSignedInUser: &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{1: {"users:read": {"users:*"}}}},
acService: &actest.FakeService{},
expectedStatus: http.StatusForbidden,
},
{
name: "should return 403 when user org ID doesn't match and user does not exist in org 2",
orgIDGetter: func(c *contextmodel.ReqContext) (int64, error) {

View File

@ -190,19 +190,26 @@ func AuthorizeInOrgMiddleware(ac AccessControl, service Service, cache userCache
return
}
if targetOrgID != GlobalOrgID && userCopy.Permissions[targetOrgID] == nil {
query := user.GetSignedInUserQuery{UserID: c.UserID, OrgID: targetOrgID}
queryResult, err := cache.GetSignedInUserWithCacheCtx(c.Req.Context(), &query)
if err != nil {
deny(c, nil, fmt.Errorf("failed to authenticate user in target org: %w", err))
return
if userCopy.OrgID != targetOrgID {
switch targetOrgID {
case GlobalOrgID:
userCopy.OrgID = GlobalOrgID
userCopy.OrgRole = org.RoleNone
userCopy.OrgName = ""
default:
query := user.GetSignedInUserQuery{UserID: c.UserID, OrgID: targetOrgID}
queryResult, err := cache.GetSignedInUserWithCacheCtx(c.Req.Context(), &query)
if err != nil {
deny(c, nil, fmt.Errorf("failed to authenticate user in target org: %w", err))
return
}
userCopy.OrgID = queryResult.OrgID
userCopy.OrgName = queryResult.OrgName
userCopy.OrgRole = queryResult.OrgRole
}
userCopy.OrgID = queryResult.OrgID
userCopy.OrgName = queryResult.OrgName
userCopy.OrgRole = queryResult.OrgRole
}
if userCopy.Permissions[userCopy.OrgID] == nil {
if userCopy.Permissions[targetOrgID] == nil {
permissions, err := service.GetUserPermissions(c.Req.Context(), &userCopy, Options{})
if err != nil {
deny(c, nil, fmt.Errorf("failed to authenticate user in target org: %w", err))
@ -212,7 +219,7 @@ func AuthorizeInOrgMiddleware(ac AccessControl, service Service, cache userCache
if userCopy.Permissions == nil {
userCopy.Permissions = make(map[int64]map[string][]string)
}
userCopy.Permissions[userCopy.OrgID] = GroupScopesByAction(permissions)
userCopy.Permissions[targetOrgID] = GroupScopesByAction(permissions)
}
authorize(c, ac, &userCopy, evaluator)
@ -221,7 +228,7 @@ func AuthorizeInOrgMiddleware(ac AccessControl, service Service, cache userCache
if c.SignedInUser.Permissions == nil {
c.SignedInUser.Permissions = make(map[int64]map[string][]string)
}
c.SignedInUser.Permissions[userCopy.OrgID] = userCopy.Permissions[userCopy.OrgID]
c.SignedInUser.Permissions[targetOrgID] = userCopy.Permissions[targetOrgID]
}
}
}