Access control: Filter users and teams by read permissions (#45968)

* pass signed in user and filter based on permissions
This commit is contained in:
Karl Persson
2022-03-01 10:58:41 +01:00
committed by GitHub
parent 07dda8a299
commit 18cbfba596
10 changed files with 83 additions and 27 deletions
@@ -82,7 +82,7 @@ type resourcePermissionDTO struct {
func (a *api) getPermissions(c *models.ReqContext) response.Response {
resourceID := web.Params(c.Req)[":resourceID"]
permissions, err := a.service.GetPermissions(c.Req.Context(), c.OrgId, resourceID)
permissions, err := a.service.GetPermissions(c.Req.Context(), c.SignedInUser, resourceID)
if err != nil {
return response.Error(http.StatusInternalServerError, "failed to get permissions", err)
}
@@ -136,9 +136,13 @@ type getPermissionsTestCase struct {
func TestApi_getPermissions(t *testing.T) {
tests := []getPermissionsTestCase{
{
desc: "expect permissions for resource with id 1",
resourceID: "1",
permissions: []*accesscontrol.Permission{{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"}},
desc: "expect permissions for resource with id 1",
resourceID: "1",
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
expectedStatus: 200,
},
{
@@ -152,7 +156,7 @@ func TestApi_getPermissions(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
seedPermissions(t, tt.resourceID, sql, service)
@@ -195,6 +199,8 @@ func TestApi_setBuiltinRolePermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -206,6 +212,8 @@ func TestApi_setBuiltinRolePermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -234,7 +242,7 @@ func TestApi_setBuiltinRolePermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, _ := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
recorder := setPermission(t, server, testOptions.Resource, tt.resourceID, tt.permission, "builtInRoles", tt.builtInRole)
assert.Equal(t, tt.expectedStatus, recorder.Code)
@@ -269,6 +277,8 @@ func TestApi_setTeamPermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -280,6 +290,8 @@ func TestApi_setTeamPermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -308,7 +320,7 @@ func TestApi_setTeamPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed team
_, err := sql.CreateTeam("test", "test@test.com", 1)
@@ -348,6 +360,8 @@ func TestApi_setUserPermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -359,6 +373,8 @@ func TestApi_setUserPermission(t *testing.T) {
permissions: []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: "dashboards.permissions:write", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
},
},
{
@@ -387,7 +403,7 @@ func TestApi_setUserPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed user
_, err := sql.CreateUser(context.Background(), models.CreateUserCommand{Login: "test", OrgId: 1})
@@ -432,9 +448,17 @@ func TestApi_UidSolver(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
userPermissions := []*accesscontrol.Permission{{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"}}
userPermissions := []*accesscontrol.Permission{
{Action: "dashboards.permissions:read", Scope: "dashboards:id:1"},
{Action: accesscontrol.ActionTeamsRead, Scope: accesscontrol.ScopeTeamsAll},
{Action: accesscontrol.ActionOrgUsersRead, Scope: accesscontrol.ScopeUsersAll},
}
service, sql := setupTestEnvironment(t, userPermissions, withSolver(testOptions, testSolver))
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
1: accesscontrol.GroupScopesByAction(userPermissions),
}}, service)
seedPermissions(t, tt.resourceID, sql, service)
permissions, recorder := getPermission(t, server, testOptions.Resource, tt.uid)
@@ -98,8 +98,9 @@ type Service struct {
sqlStore *sqlstore.SQLStore
}
func (s *Service) GetPermissions(ctx context.Context, orgID int64, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return s.store.GetResourcesPermissions(ctx, orgID, types.GetResourcesPermissionsQuery{
func (s *Service) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return s.store.GetResourcesPermissions(ctx, user.OrgId, types.GetResourcesPermissionsQuery{
User: user,
Actions: s.actions,
Resource: s.options.Resource,
ResourceIDs: []string{resourceID},
@@ -1,6 +1,9 @@
package types
import "github.com/grafana/grafana/pkg/services/accesscontrol"
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
type SetResourcePermissionCommand struct {
Actions []string
@@ -22,4 +25,5 @@ type GetResourcesPermissionsQuery struct {
Resource string
ResourceIDs []string
OnlyManaged bool
User *models.SignedInUser
}