RBAC: Make RBAC action names more consistent (#49730)
* update action names * correctly retrieve teams for signed in user * remove test * undo swagger changes * undo swagger changes pt2 * add migration from old action names to the new ones * rename from list to read * linting * also update alertign actions * fix migration
This commit is contained in:
+3
-3
@@ -179,7 +179,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
usersRoute.Get("/", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead)), routing.Wrap(hs.searchUsersService.SearchUsers))
|
||||
usersRoute.Get("/search", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead)), routing.Wrap(hs.searchUsersService.SearchUsersWithPaging))
|
||||
usersRoute.Get("/:id", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserByID))
|
||||
usersRoute.Get("/:id/teams", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersTeamRead, userIDScope)), routing.Wrap(hs.GetUserTeams))
|
||||
usersRoute.Get("/:id/teams", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserTeams))
|
||||
usersRoute.Get("/:id/orgs", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserOrgList))
|
||||
// query parameters /users/lookup?loginOrEmail=admin@example.com
|
||||
usersRoute.Get("/lookup", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll)), routing.Wrap(hs.GetUserByLoginOrEmail))
|
||||
@@ -233,7 +233,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
orgRoute.Get("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.GetOrgUsersForCurrentOrg))
|
||||
orgRoute.Get("/users/search", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.SearchOrgUsersWithPaging))
|
||||
orgRoute.Post("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), quota("user"), routing.Wrap(hs.AddOrgUserToCurrentOrg))
|
||||
orgRoute.Patch("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRoleUpdate, userIDScope)), routing.Wrap(hs.UpdateOrgUserForCurrentOrg))
|
||||
orgRoute.Patch("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersWrite, userIDScope)), routing.Wrap(hs.UpdateOrgUserForCurrentOrg))
|
||||
orgRoute.Delete("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUserForCurrentOrg))
|
||||
|
||||
// invites
|
||||
@@ -279,7 +279,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
orgsRoute.Delete("/", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsDelete)), routing.Wrap(hs.DeleteOrgByID))
|
||||
orgsRoute.Get("/users", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.GetOrgUsers))
|
||||
orgsRoute.Post("/users", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), routing.Wrap(hs.AddOrgUser))
|
||||
orgsRoute.Patch("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRoleUpdate, userIDScope)), routing.Wrap(hs.UpdateOrgUser))
|
||||
orgsRoute.Patch("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersWrite, userIDScope)), routing.Wrap(hs.UpdateOrgUser))
|
||||
orgsRoute.Delete("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUser))
|
||||
orgsRoute.Get("/quotas", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsQuotasRead)), routing.Wrap(hs.GetOrgQuotas))
|
||||
orgsRoute.Put("/quotas/:target", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsQuotasWrite)), routing.Wrap(hs.UpdateOrgQuota))
|
||||
|
||||
@@ -325,10 +325,10 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
|
||||
enableAccessControl: true,
|
||||
expectedCode: http.StatusOK,
|
||||
expectedMetadata: map[string]bool{
|
||||
"org.users.role:update": true,
|
||||
"org.users:add": true,
|
||||
"org.users:read": true,
|
||||
"org.users:remove": true},
|
||||
"org.users:write": true,
|
||||
"org.users:add": true,
|
||||
"org.users:read": true,
|
||||
"org.users:remove": true},
|
||||
user: testServerAdminViewer,
|
||||
targetOrg: testServerAdminViewer.OrgId,
|
||||
},
|
||||
|
||||
+5
-5
@@ -154,7 +154,7 @@ func (hs *HTTPServer) GetSignedInUserOrgList(c *models.ReqContext) response.Resp
|
||||
|
||||
// GET /api/user/teams
|
||||
func (hs *HTTPServer) GetSignedInUserTeamList(c *models.ReqContext) response.Response {
|
||||
return hs.getUserTeamList(c.Req.Context(), c.OrgId, c.UserId)
|
||||
return hs.getUserTeamList(c, c.OrgId, c.UserId)
|
||||
}
|
||||
|
||||
// GET /api/users/:id/teams
|
||||
@@ -163,13 +163,13 @@ func (hs *HTTPServer) GetUserTeams(c *models.ReqContext) response.Response {
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "id is invalid", err)
|
||||
}
|
||||
return hs.getUserTeamList(c.Req.Context(), c.OrgId, id)
|
||||
return hs.getUserTeamList(c, c.OrgId, id)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) getUserTeamList(ctx context.Context, orgID int64, userID int64) response.Response {
|
||||
query := models.GetTeamsByUserQuery{OrgId: orgID, UserId: userID}
|
||||
func (hs *HTTPServer) getUserTeamList(c *models.ReqContext, orgID int64, userID int64) response.Response {
|
||||
query := models.GetTeamsByUserQuery{OrgId: orgID, UserId: userID, SignedInUser: c.SignedInUser}
|
||||
|
||||
if err := hs.SQLStore.GetTeamsByUser(ctx, &query); err != nil {
|
||||
if err := hs.SQLStore.GetTeamsByUser(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(500, "Failed to get user teams", err)
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -62,9 +62,10 @@ type GetTeamByIdQuery struct {
|
||||
const FilterIgnoreUser int64 = 0
|
||||
|
||||
type GetTeamsByUserQuery struct {
|
||||
OrgId int64
|
||||
UserId int64 `json:"userId"`
|
||||
Result []*TeamDTO `json:"teams"`
|
||||
OrgId int64
|
||||
UserId int64 `json:"userId"`
|
||||
Result []*TeamDTO `json:"teams"`
|
||||
SignedInUser *SignedInUser
|
||||
}
|
||||
|
||||
type SearchTeamsQuery struct {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
var sqlIDAcceptList = map[string]struct{}{
|
||||
"id": {},
|
||||
"org_user.user_id": {},
|
||||
"role.id": {},
|
||||
"role.uid": {},
|
||||
"t.id": {},
|
||||
"team.id": {},
|
||||
"u.id": {},
|
||||
|
||||
@@ -285,32 +285,31 @@ const (
|
||||
ActionAPIKeyDelete = "apikeys:delete"
|
||||
|
||||
// Users actions
|
||||
ActionUsersRead = "users:read"
|
||||
ActionUsersWrite = "users:write"
|
||||
ActionUsersTeamRead = "users.teams:read"
|
||||
ActionUsersRead = "users:read"
|
||||
ActionUsersWrite = "users:write"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersAuthTokenList = "users.authtoken:list"
|
||||
ActionUsersAuthTokenList = "users.authtoken:read"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersAuthTokenUpdate = "users.authtoken:update"
|
||||
ActionUsersAuthTokenUpdate = "users.authtoken:write"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersPasswordUpdate = "users.password:update"
|
||||
ActionUsersPasswordUpdate = "users.password:write"
|
||||
ActionUsersDelete = "users:delete"
|
||||
ActionUsersCreate = "users:create"
|
||||
ActionUsersEnable = "users:enable"
|
||||
ActionUsersDisable = "users:disable"
|
||||
ActionUsersPermissionsUpdate = "users.permissions:update"
|
||||
ActionUsersPermissionsUpdate = "users.permissions:write"
|
||||
ActionUsersLogout = "users:logout"
|
||||
ActionUsersQuotasList = "users.quotas:list"
|
||||
ActionUsersQuotasUpdate = "users.quotas:update"
|
||||
ActionUsersQuotasList = "users.quotas:read"
|
||||
ActionUsersQuotasUpdate = "users.quotas:write"
|
||||
|
||||
// Org actions
|
||||
ActionOrgUsersRead = "org.users:read"
|
||||
ActionOrgUsersAdd = "org.users:add"
|
||||
ActionOrgUsersRemove = "org.users:remove"
|
||||
ActionOrgUsersRoleUpdate = "org.users.role:update"
|
||||
ActionOrgUsersRead = "org.users:read"
|
||||
ActionOrgUsersAdd = "org.users:add"
|
||||
ActionOrgUsersRemove = "org.users:remove"
|
||||
ActionOrgUsersWrite = "org.users:write"
|
||||
|
||||
// LDAP actions
|
||||
ActionLDAPUsersRead = "ldap.user:read"
|
||||
@@ -363,12 +362,12 @@ const (
|
||||
// Alerting rules actions
|
||||
ActionAlertingRuleCreate = "alert.rules:create"
|
||||
ActionAlertingRuleRead = "alert.rules:read"
|
||||
ActionAlertingRuleUpdate = "alert.rules:update"
|
||||
ActionAlertingRuleUpdate = "alert.rules:write"
|
||||
ActionAlertingRuleDelete = "alert.rules:delete"
|
||||
|
||||
// Alerting instances (+silences) actions
|
||||
ActionAlertingInstanceCreate = "alert.instances:create"
|
||||
ActionAlertingInstanceUpdate = "alert.instances:update"
|
||||
ActionAlertingInstanceUpdate = "alert.instances:write"
|
||||
ActionAlertingInstanceRead = "alert.instances:read"
|
||||
|
||||
// Alerting Notification policies actions
|
||||
|
||||
@@ -47,14 +47,14 @@ var (
|
||||
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.",
|
||||
Group: "User administration (organizational)",
|
||||
Version: 3,
|
||||
Version: 4,
|
||||
Permissions: ConcatPermissions(orgUsersReaderRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersAdd,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRoleUpdate,
|
||||
Action: ActionOrgUsersWrite,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
@@ -110,16 +110,12 @@ var (
|
||||
DisplayName: "User reader",
|
||||
Description: "Read all users and their information, such as team memberships, authentication tokens, and quotas.",
|
||||
Group: "User administration (global)",
|
||||
Version: 4,
|
||||
Version: 6,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionUsersRead,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersTeamRead,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenList,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
@@ -136,7 +132,7 @@ var (
|
||||
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.",
|
||||
Group: "User administration (global)",
|
||||
Version: 4,
|
||||
Version: 5,
|
||||
Permissions: ConcatPermissions(usersReaderRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionUsersPasswordUpdate,
|
||||
|
||||
@@ -273,7 +273,7 @@ func (g *dashboardGuardianImpl) getTeams() ([]*models.TeamDTO, error) {
|
||||
return g.teams, nil
|
||||
}
|
||||
|
||||
query := models.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId}
|
||||
query := models.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId, SignedInUser: g.user}
|
||||
err := g.store.GetTeamsByUser(g.ctx, &query)
|
||||
|
||||
g.teams = query.Result
|
||||
|
||||
@@ -4,7 +4,7 @@ import "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
|
||||
const (
|
||||
ActionRead = "licensing:read"
|
||||
ActionUpdate = "licensing:update"
|
||||
ActionUpdate = "licensing:write"
|
||||
ActionDelete = "licensing:delete"
|
||||
ActionReportsRead = "licensing.reports:read"
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ var (
|
||||
DisplayName: "Rules Editor",
|
||||
Description: "Can add, update, and delete rules in any Grafana folder and external providers",
|
||||
Group: AlertRolesGroup,
|
||||
Version: 2,
|
||||
Version: 3,
|
||||
Permissions: accesscontrol.ConcatPermissions(rulesReaderRole.Role.Permissions, []accesscontrol.Permission{
|
||||
{
|
||||
Action: accesscontrol.ActionAlertingRuleCreate,
|
||||
@@ -84,7 +84,7 @@ var (
|
||||
DisplayName: "Silences Editor",
|
||||
Description: "Can add and update silences in Grafana and external providers",
|
||||
Group: AlertRolesGroup,
|
||||
Version: 1,
|
||||
Version: 2,
|
||||
Permissions: accesscontrol.ConcatPermissions(instancesReaderRole.Role.Permissions, []accesscontrol.Permission{
|
||||
{
|
||||
Action: accesscontrol.ActionAlertingInstanceCreate,
|
||||
|
||||
@@ -209,25 +209,7 @@ func (s *ServiceAccountsStoreImpl) RetrieveServiceAccount(ctx context.Context, o
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get Teams of service account. Can be optimized by combining with the query above
|
||||
// in refactor
|
||||
getTeamQuery := models.GetTeamsByUserQuery{UserId: serviceAccountID, OrgId: orgID}
|
||||
if err := s.sqlStore.GetTeamsByUser(ctx, &getTeamQuery); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
teams := make([]string, len(getTeamQuery.Result))
|
||||
|
||||
for i := range getTeamQuery.Result {
|
||||
teams[i] = getTeamQuery.Result[i].Name
|
||||
}
|
||||
|
||||
serviceAccount.Teams = teams
|
||||
|
||||
return serviceAccount, nil
|
||||
return serviceAccount, err
|
||||
}
|
||||
|
||||
func (s *ServiceAccountsStoreImpl) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/tests"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
@@ -107,20 +106,3 @@ func TestStore_RetrieveServiceAccount(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestStore_RetrieveServiceAccountWithTeams(t *testing.T) {
|
||||
userToCreate := tests.TestUser{Login: "servicetestwithTeam@admin", IsServiceAccount: true}
|
||||
db, store := setupTestDatabase(t)
|
||||
user := tests.SetupUserServiceAccount(t, db, userToCreate)
|
||||
|
||||
team, err := store.sqlStore.CreateTeam("serviceTeam", "serviceTeam", user.OrgId)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = store.sqlStore.AddTeamMember(user.Id, user.OrgId, team.Id, false, models.PERMISSION_VIEW)
|
||||
require.NoError(t, err)
|
||||
|
||||
dto, err := store.RetrieveServiceAccount(context.Background(), user.OrgId, user.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, userToCreate.Login, dto.Login)
|
||||
require.Len(t, dto.Teams, 1)
|
||||
require.Equal(t, "serviceTeam", dto.Teams[0])
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package accesscontrol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddActionNameMigrator(mg *migrator.Migrator) {
|
||||
mg.AddMigration("RBAC action name migrator", &actionNameMigrator{})
|
||||
}
|
||||
|
||||
type actionNameMigrator struct {
|
||||
sess *xorm.Session
|
||||
migrator *migrator.Migrator
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
var _ migrator.CodeMigration = new(actionNameMigrator)
|
||||
|
||||
func (m *actionNameMigrator) SQL(migrator.Dialect) string {
|
||||
return CodeMigrationSQL
|
||||
}
|
||||
|
||||
func (m *actionNameMigrator) Exec(sess *xorm.Session, migrator *migrator.Migrator) error {
|
||||
m.sess = sess
|
||||
m.migrator = migrator
|
||||
return m.migrateActionNames()
|
||||
}
|
||||
|
||||
func (m *actionNameMigrator) migrateActionNames() error {
|
||||
actionNameMapping := map[string]string{
|
||||
"licensing:update": "licensing:write",
|
||||
"reports.admin:create": "reports:create",
|
||||
"reports.admin:write": "reports:write",
|
||||
"org.users.role:update": accesscontrol.ActionOrgUsersWrite,
|
||||
"users.authtoken:update": accesscontrol.ActionUsersAuthTokenUpdate,
|
||||
"users.password:update": accesscontrol.ActionUsersPasswordUpdate,
|
||||
"users.permissions:update": accesscontrol.ActionUsersPermissionsUpdate,
|
||||
"users.quotas:update": accesscontrol.ActionUsersQuotasUpdate,
|
||||
"teams.roles:list": "teams.roles:read",
|
||||
"users.roles:list": "users.roles:read",
|
||||
"users.authtoken:list": accesscontrol.ActionUsersAuthTokenList,
|
||||
"users.quotas:list": accesscontrol.ActionUsersQuotasList,
|
||||
"users.permissions:list": "users.permissions:read",
|
||||
"alert.instances:update": accesscontrol.ActionAlertingInstanceUpdate,
|
||||
"alert.rules:update": accesscontrol.ActionAlertingRuleUpdate,
|
||||
}
|
||||
for oldName, newName := range actionNameMapping {
|
||||
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", oldName).Update(&accesscontrol.Permission{Action: newName})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update permission table for action %s: %w", oldName, err)
|
||||
}
|
||||
}
|
||||
|
||||
actionsToDelete := []string{"users.teams:read", "roles:list"}
|
||||
for _, action := range actionsToDelete {
|
||||
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", action).Delete(accesscontrol.Permission{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update permission table for action %s: %w", action, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -90,6 +90,7 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
||||
|
||||
accesscontrol.AddManagedPermissionsMigration(mg)
|
||||
accesscontrol.AddManagedFolderAlertActionsMigration(mg)
|
||||
accesscontrol.AddActionNameMigrator(mg)
|
||||
}
|
||||
|
||||
func addMigrationLogMigrations(mg *Migrator) {
|
||||
|
||||
@@ -310,12 +310,23 @@ func (ss *SQLStore) GetTeamsByUser(ctx context.Context, query *models.GetTeamsBy
|
||||
query.Result = make([]*models.TeamDTO, 0)
|
||||
|
||||
var sql bytes.Buffer
|
||||
var params []interface{}
|
||||
params = append(params, query.OrgId, query.UserId)
|
||||
|
||||
sql.WriteString(getTeamSelectSQLBase([]string{}))
|
||||
sql.WriteString(` INNER JOIN team_member on team.id = team_member.team_id`)
|
||||
sql.WriteString(` WHERE team.org_id = ? and team_member.user_id = ?`)
|
||||
|
||||
err := sess.SQL(sql.String(), query.OrgId, query.UserId).Find(&query.Result)
|
||||
if !ac.IsDisabled(ss.Cfg) {
|
||||
acFilter, err := ac.Filter(query.SignedInUser, "team.id", "teams:id:", ac.ActionTeamsRead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sql.WriteString(` and` + acFilter.Where)
|
||||
params = append(params, acFilter.Args...)
|
||||
}
|
||||
|
||||
err := sess.SQL(sql.String(), params...).Find(&query.Result)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -219,7 +219,14 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
|
||||
err := sqlStore.AddTeamMember(userIds[0], testOrgID, groupId, false, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
query := &models.GetTeamsByUserQuery{OrgId: testOrgID, UserId: userIds[0]}
|
||||
query := &models.GetTeamsByUserQuery{
|
||||
OrgId: testOrgID,
|
||||
UserId: userIds[0],
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgId: testOrgID,
|
||||
Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}, ac.ActionTeamsRead: {ac.ScopeTeamsAll}}},
|
||||
},
|
||||
}
|
||||
err = sqlStore.GetTeamsByUser(context.Background(), query)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
|
||||
@@ -577,7 +577,20 @@ func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSigned
|
||||
user.ExternalAuthId = ""
|
||||
}
|
||||
|
||||
getTeamsByUserQuery := &models.GetTeamsByUserQuery{OrgId: user.OrgId, UserId: user.UserId}
|
||||
// tempUser is used to retrieve the teams for the signed in user for internal use.
|
||||
tempUser := &models.SignedInUser{
|
||||
OrgId: user.OrgId,
|
||||
Permissions: map[int64]map[string][]string{
|
||||
user.OrgId: {
|
||||
ac.ActionTeamsRead: {ac.ScopeTeamsAll},
|
||||
},
|
||||
},
|
||||
}
|
||||
getTeamsByUserQuery := &models.GetTeamsByUserQuery{
|
||||
OrgId: user.OrgId,
|
||||
UserId: user.UserId,
|
||||
SignedInUser: tempUser,
|
||||
}
|
||||
err = ss.GetTeamsByUser(ctx, getTeamsByUserQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -617,7 +617,7 @@ func TestRulerAccess(t *testing.T) {
|
||||
desc: "viewer request should fail",
|
||||
url: "http://viewer:viewer@%s/api/ruler/grafana/api/v1/rules/default",
|
||||
expStatus: http.StatusForbidden,
|
||||
expectedMessage: `You'll need additional permissions to perform this action. Permissions needed: any of alert.rules:update, alert.rules:create, alert.rules:delete`,
|
||||
expectedMessage: `You'll need additional permissions to perform this action. Permissions needed: any of alert.rules:write, alert.rules:create, alert.rules:delete`,
|
||||
},
|
||||
{
|
||||
desc: "editor request should succeed",
|
||||
|
||||
Reference in New Issue
Block a user