Move SignedInUser to user service and RoleType and Roles to org (#53445)

* Move SignedInUser to user service and RoleType and Roles to org

* Use go naming convention for roles

* Fix some imports and leftovers

* Fix ldap debug test

* Fix lint

* Fix lint 2

* Fix lint 3

* Fix type and not needed conversion

* Clean up messages in api tests

* Clean up api tests 2
This commit is contained in:
idafurjes
2022-08-10 11:56:48 +02:00
committed by GitHub
parent 46004037e2
commit 6afad51761
278 changed files with 1758 additions and 1543 deletions
+18 -17
View File
@@ -8,6 +8,7 @@ import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/grafanads"
@@ -74,11 +75,11 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
},
},
Grants: []string{string(models.ROLE_EDITOR)},
Grants: []string{string(org.RoleEditor)},
}
if setting.ViewersCanEdit {
datasourcesExplorerRole.Grants = append(datasourcesExplorerRole.Grants, string(models.ROLE_VIEWER))
datasourcesExplorerRole.Grants = append(datasourcesExplorerRole.Grants, string(org.RoleViewer))
}
datasourcesReaderRole := ac.RoleRegistration{
@@ -98,7 +99,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
builtInDatasourceReader := ac.RoleRegistration{
@@ -119,12 +120,12 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
Hidden: true,
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
// when running oss or enterprise without a license all users should be able to query data sources
if !hs.License.FeatureEnabled("accesscontrol.enforcement") {
datasourcesReaderRole.Grants = []string{string(models.ROLE_VIEWER)}
datasourcesReaderRole.Grants = []string{string(org.RoleViewer)}
}
datasourcesWriterRole := ac.RoleRegistration{
@@ -147,7 +148,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
datasourcesIdReaderRole := ac.RoleRegistration{
@@ -163,7 +164,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
apikeyReaderRole := ac.RoleRegistration{
@@ -179,7 +180,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
apikeyWriterRole := ac.RoleRegistration{
@@ -198,7 +199,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
orgReaderRole := ac.RoleRegistration{
@@ -212,7 +213,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ActionOrgsQuotasRead},
},
},
Grants: []string{string(models.ROLE_VIEWER), ac.RoleGrafanaAdmin},
Grants: []string{string(org.RoleViewer), ac.RoleGrafanaAdmin},
}
orgWriterRole := ac.RoleRegistration{
@@ -227,7 +228,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ActionOrgsPreferencesWrite},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
orgMaintainerRole := ac.RoleRegistration{
@@ -246,9 +247,9 @@ func (hs *HTTPServer) declareFixedRoles() error {
Grants: []string{string(ac.RoleGrafanaAdmin)},
}
teamCreatorGrants := []string{string(models.ROLE_ADMIN)}
teamCreatorGrants := []string{string(org.RoleAdmin)}
if hs.Cfg.EditorsCanAdmin {
teamCreatorGrants = append(teamCreatorGrants, string(models.ROLE_EDITOR))
teamCreatorGrants = append(teamCreatorGrants, string(org.RoleEditor))
}
teamsCreatorRole := ac.RoleRegistration{
Role: ac.RoleDTO{
@@ -279,7 +280,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ac.ActionTeamsWrite, Scope: ac.ScopeTeamsAll},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
annotationsReaderRole := ac.RoleRegistration{
@@ -292,7 +293,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ac.ActionAnnotationsRead, Scope: ac.ScopeAnnotationsAll},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
dashboardAnnotationsWriterRole := ac.RoleRegistration{
@@ -307,7 +308,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsTypeDashboard},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
annotationsWriterRole := ac.RoleRegistration{
@@ -322,7 +323,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsAll},
},
},
Grants: []string{string(models.ROLE_EDITOR)},
Grants: []string{string(org.RoleEditor)},
}
dashboardsCreatorRole := ac.RoleRegistration{
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -53,7 +54,7 @@ func (hs *HTTPServer) AdminGetStats(c *models.ReqContext) response.Response {
return response.JSON(http.StatusOK, statsQuery.Result)
}
func (hs *HTTPServer) getAuthorizedSettings(ctx context.Context, user *models.SignedInUser, bag setting.SettingsBag) (setting.SettingsBag, error) {
func (hs *HTTPServer) getAuthorizedSettings(ctx context.Context, user *user.SignedInUser, bag setting.SettingsBag) (setting.SettingsBag, error) {
if hs.AccessControl.IsDisabled() {
return bag, nil
}
+6 -5
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -30,7 +31,7 @@ const (
)
func TestAdminAPIEndpoint(t *testing.T) {
const role = models.ROLE_ADMIN
const role = org.RoleAdmin
userService := usertest.NewUserServiceFake()
t.Run("Given a server admin attempts to remove themselves as an admin", func(t *testing.T) {
updateCmd := dtos.AdminUpdateUserPermissionsForm{
@@ -236,7 +237,7 @@ func TestAdminAPIEndpoint(t *testing.T) {
})
}
func putAdminScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
func putAdminScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType,
cmd dtos.AdminUpdateUserPermissionsForm, fn scenarioFunc, sqlStore sqlstore.Store) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := &HTTPServer{
@@ -277,7 +278,7 @@ func adminLogoutUserScenario(t *testing.T, desc string, url string, routePattern
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.AdminLogoutUser(c)
})
@@ -305,7 +306,7 @@ func adminRevokeUserAuthTokenScenario(t *testing.T, desc string, url string, rou
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.AdminRevokeUserAuthToken(c)
})
@@ -331,7 +332,7 @@ func adminGetUserAuthTokensScenario(t *testing.T, desc string, url string, route
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.AdminGetUserAuthTokens(c)
})
+6 -4
View File
@@ -14,6 +14,8 @@ import (
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -504,7 +506,7 @@ func (hs *HTTPServer) canSaveAnnotation(c *models.ReqContext, annotation *annota
return canEditDashboard(c, annotation.DashboardId)
} else {
if hs.AccessControl.IsDisabled() {
return c.SignedInUser.HasRole(models.ROLE_EDITOR), nil
return c.SignedInUser.HasRole(org.RoleEditor), nil
}
return true, nil
}
@@ -519,7 +521,7 @@ func canEditDashboard(c *models.ReqContext, dashboardID int64) (bool, error) {
return true, nil
}
func findAnnotationByID(ctx context.Context, repo annotations.Repository, annotationID int64, user *models.SignedInUser) (*annotations.ItemDTO, response.Response) {
func findAnnotationByID(ctx context.Context, repo annotations.Repository, annotationID int64, user *user.SignedInUser) (*annotations.ItemDTO, response.Response) {
query := &annotations.ItemQuery{
AnnotationId: annotationID,
OrgId: user.OrgId,
@@ -583,7 +585,7 @@ func AnnotationTypeScopeResolver() (string, accesscontrol.ScopeAttributeResolver
// tempUser is used to resolve annotation type.
// The annotation doesn't get returned to the real user, so real user's permissions don't matter here.
tempUser := &models.SignedInUser{
tempUser := &user.SignedInUser{
OrgId: orgID,
Permissions: map[int64]map[string][]string{
orgID: {
@@ -620,7 +622,7 @@ func (hs *HTTPServer) canCreateAnnotation(c *models.ReqContext, dashboardId int6
evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeOrganization)
return hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator)
} else {
return c.SignedInUser.HasRole(models.ROLE_EDITOR), nil
return c.SignedInUser.HasRole(org.RoleEditor), nil
}
}
}
+12 -11
View File
@@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
)
@@ -49,7 +50,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
}
t.Run("When user is an Org Viewer", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
t.Run("Should not be allowed to save an annotation", func(t *testing.T) {
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role,
cmd, store, nil, func(sc *scenarioContext) {
@@ -82,7 +83,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Editor", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
t.Run("Should be able to save an annotation", func(t *testing.T) {
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role,
cmd, store, nil, func(sc *scenarioContext) {
@@ -154,7 +155,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
}
t.Run("When user is an Org Viewer", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
t.Run("Should not be allowed to save an annotation", func(t *testing.T) {
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) {
setUpACL()
@@ -187,7 +188,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Editor", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
t.Run("Should be able to save an annotation", func(t *testing.T) {
postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) {
setUpACL()
@@ -220,7 +221,7 @@ func TestAnnotationsAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Admin", func(t *testing.T) {
role := models.ROLE_ADMIN
role := org.RoleAdmin
mockStore := mockstore.NewSQLStoreMock()
@@ -338,7 +339,7 @@ func (repo *fakeAnnotationsRepo) LoadItems() {
var fakeAnnoRepo *fakeAnnotationsRepo
func postAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
func postAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType,
cmd dtos.PostAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := setupSimpleHTTPServer(nil)
@@ -366,7 +367,7 @@ func postAnnotationScenario(t *testing.T, desc string, url string, routePattern
})
}
func putAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
func putAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType,
cmd dtos.UpdateAnnotationsCmd, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := setupSimpleHTTPServer(nil)
@@ -395,7 +396,7 @@ func putAnnotationScenario(t *testing.T, desc string, url string, routePattern s
})
}
func patchAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType, cmd dtos.PatchAnnotationsCmd, fn scenarioFunc) {
func patchAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType, cmd dtos.PatchAnnotationsCmd, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := setupSimpleHTTPServer(nil)
store := sqlstore.InitTestDB(t)
@@ -423,7 +424,7 @@ func patchAnnotationScenario(t *testing.T, desc string, url string, routePattern
})
}
func deleteAnnotationsScenario(t *testing.T, desc string, url string, routePattern string, role models.RoleType,
func deleteAnnotationsScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType,
cmd dtos.MassDeleteAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := setupSimpleHTTPServer(nil)
@@ -998,8 +999,8 @@ func TestAPI_MassDeleteAnnotations_AccessControl(t *testing.T) {
}
func setUpACL() {
viewerRole := models.ROLE_VIEWER
editorRole := models.ROLE_EDITOR
viewerRole := org.RoleViewer
editorRole := org.RoleEditor
store := mockstore.NewSQLStoreMock()
store.ExpectedTeamsByUser = []*models.TeamDTO{}
dashSvc := &dashboards.FakeDashboardService{}
+5 -4
View File
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -49,10 +50,10 @@ func (hs *HTTPServer) initAppPluginRoutes(r *web.Mux) {
ac.EvalPermission(plugins.ActionAppAccess, plugins.ScopeProvider.GetResourceScope(plugin.ID))))
if route.ReqRole != "" {
if route.ReqRole == models.ROLE_ADMIN {
handlers = append(handlers, middleware.RoleAuth(models.ROLE_ADMIN))
} else if route.ReqRole == models.ROLE_EDITOR {
handlers = append(handlers, middleware.RoleAuth(models.ROLE_EDITOR, models.ROLE_ADMIN))
if route.ReqRole == org.RoleAdmin {
handlers = append(handlers, middleware.RoleAuth(org.RoleAdmin))
} else if route.ReqRole == org.RoleEditor {
handlers = append(handlers, middleware.RoleAuth(org.RoleEditor, org.RoleAdmin))
}
}
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/comments"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -33,7 +34,7 @@ func (hs *HTTPServer) commentsCreate(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
if c.SignedInUser.UserId == 0 && !c.SignedInUser.HasRole(models.ROLE_ADMIN) {
if c.SignedInUser.UserId == 0 && !c.SignedInUser.HasRole(org.RoleAdmin) {
return response.Error(http.StatusForbidden, "admin role required", nil)
}
comment, err := hs.commentsService.Create(c.Req.Context(), c.OrgId, c.SignedInUser, cmd)
+10 -9
View File
@@ -39,6 +39,7 @@ import (
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/rendering"
@@ -55,10 +56,10 @@ import (
)
func loggedInUserScenario(t *testing.T, desc string, url string, routePattern string, fn scenarioFunc, sqlStore sqlstore.Store) {
loggedInUserScenarioWithRole(t, desc, "GET", url, routePattern, models.ROLE_EDITOR, fn, sqlStore)
loggedInUserScenarioWithRole(t, desc, "GET", url, routePattern, org.RoleEditor, fn, sqlStore)
}
func loggedInUserScenarioWithRole(t *testing.T, desc string, method string, url string, routePattern string, role models.RoleType, fn scenarioFunc, sqlStore sqlstore.Store) {
func loggedInUserScenarioWithRole(t *testing.T, desc string, method string, url string, routePattern string, role org.RoleType, fn scenarioFunc, sqlStore sqlstore.Store) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
sc := setupScenarioContext(t, url)
sc.sqlStore = sqlStore
@@ -295,7 +296,7 @@ type accessControlScenarioContext struct {
func setAccessControlPermissions(acmock *accesscontrolmock.Mock, perms []accesscontrol.Permission, org int64) {
acmock.GetUserPermissionsFunc =
func(_ context.Context, u *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
func(_ context.Context, u *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
if u.OrgId == org {
return perms, nil
}
@@ -304,24 +305,24 @@ func setAccessControlPermissions(acmock *accesscontrolmock.Mock, perms []accessc
}
// setInitCtxSignedInUser sets a copy of the user in initCtx
func setInitCtxSignedInUser(initCtx *models.ReqContext, user models.SignedInUser) {
func setInitCtxSignedInUser(initCtx *models.ReqContext, user user.SignedInUser) {
initCtx.IsSignedIn = true
initCtx.SignedInUser = &user
}
func setInitCtxSignedInViewer(initCtx *models.ReqContext) {
initCtx.IsSignedIn = true
initCtx.SignedInUser = &models.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: models.ROLE_VIEWER, Login: testUserLogin}
initCtx.SignedInUser = &user.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: org.RoleViewer, Login: testUserLogin}
}
func setInitCtxSignedInEditor(initCtx *models.ReqContext) {
initCtx.IsSignedIn = true
initCtx.SignedInUser = &models.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: models.ROLE_EDITOR, Login: testUserLogin}
initCtx.SignedInUser = &user.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: org.RoleEditor, Login: testUserLogin}
}
func setInitCtxSignedInOrgAdmin(initCtx *models.ReqContext) {
initCtx.IsSignedIn = true
initCtx.SignedInUser = &models.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: models.ROLE_ADMIN, Login: testUserLogin}
initCtx.SignedInUser = &user.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: org.RoleAdmin, Login: testUserLogin}
}
func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
@@ -479,8 +480,8 @@ func SetupAPITestServer(t *testing.T, opts ...APITestServerOption) *webtest.Serv
}
var (
viewerRole = models.ROLE_VIEWER
editorRole = models.ROLE_EDITOR
viewerRole = org.RoleViewer
editorRole = org.RoleEditor
)
type setUpConf struct {
+4 -3
View File
@@ -26,6 +26,7 @@ import (
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/services/user"
@@ -538,7 +539,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
dash := dtos.DashboardFullWithMeta{}
dash.Meta.IsHome = true
dash.Meta.CanEdit = c.SignedInUser.HasRole(models.ROLE_EDITOR)
dash.Meta.CanEdit = c.SignedInUser.HasRole(org.RoleEditor)
dash.Meta.FolderTitle = "General"
dash.Dashboard = simplejson.New()
@@ -555,8 +556,8 @@ func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
func (hs *HTTPServer) addGettingStartedPanelToHomeDashboard(c *models.ReqContext, dash *simplejson.Json) {
// We only add this getting started panel for Admins who have not dismissed it,
// and if a custom default home dashboard hasn't been configured
if !c.HasUserRole(models.ROLE_ADMIN) ||
c.HasHelpFlag(models.HelpFlagGettingStartedPanelDismissed) ||
if !c.HasUserRole(org.RoleAdmin) ||
c.HasHelpFlag(user.HelpFlagGettingStartedPanelDismissed) ||
hs.Cfg.DefaultHomeDashboardPath != "" {
return
}
+5 -4
View File
@@ -18,6 +18,7 @@ import (
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/setting"
)
@@ -53,7 +54,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false})
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", org.RoleEditor, func(sc *scenarioContext) {
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 403, sc.resp.Code)
}, mockSQLStore)
@@ -96,7 +97,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", org.RoleAdmin, func(sc *scenarioContext) {
callGetDashboardPermissions(sc, hs)
assert.Equal(t, 200, sc.resp.Code)
@@ -189,7 +190,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
})
t.Run("When trying to update team or user permissions with a role", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
cmds := []dtos.UpdateDashboardACLCommand{
{
Items: []dtos.DashboardACLUpdateItem{
@@ -264,7 +265,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
mockSQLStore := mockstore.NewSQLStoreMock()
var resp []*models.DashboardACLInfoDTO
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/1/permissions",
"/api/dashboards/id/:dashboardId/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
"/api/dashboards/id/:dashboardId/permissions", org.RoleAdmin, func(sc *scenarioContext) {
setUp()
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{
CanAdminValue: true,
+14 -13
View File
@@ -18,6 +18,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
)
@@ -65,7 +66,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
t.Run("When user has editor role and is not in the ACL", func(t *testing.T) {
loggedInUserScenarioWithRole(t, "Should not be able to delete snapshot when calling DELETE on",
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
hs := &HTTPServer{dashboardsnapshotsService: setUpSnapshotTest(t, 0, "")}
sc.handlerFunc = hs.DeleteDashboardSnapshot
@@ -116,7 +117,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
}).Return(nil)
loggedInUserScenarioWithRole(t, "Should be able to delete a snapshot when calling DELETE on", "DELETE",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
guardian.InitLegacyGuardian(sc.sqlStore, dashSvc)
var externalRequest *http.Request
ts := setupRemoteServer(func(rw http.ResponseWriter, req *http.Request) {
@@ -140,7 +141,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
t.Run("When user is editor and creator of the snapshot", func(t *testing.T) {
loggedInUserScenarioWithRole(t, "Should be able to delete a snapshot when calling DELETE on",
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t, testUserID, "")
hs := &HTTPServer{dashboardsnapshotsService: d}
@@ -159,7 +160,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
t.Run("When deleting an external snapshot", func(t *testing.T) {
loggedInUserScenarioWithRole(t,
"Should gracefully delete local snapshot when remote snapshot has already been removed when calling DELETE on",
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
var writeErr error
ts := setupRemoteServer(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(500)
@@ -180,7 +181,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
loggedInUserScenarioWithRole(t,
"Should fail to delete local snapshot when an unexpected 500 error occurs when calling DELETE on", "DELETE",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
var writeErr error
ts := setupRemoteServer(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(500)
@@ -196,7 +197,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
loggedInUserScenarioWithRole(t,
"Should fail to delete local snapshot when an unexpected remote error occurs when calling DELETE on",
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"DELETE", "/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
ts := setupRemoteServer(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(404)
})
@@ -208,7 +209,7 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) {
}, sqlmock)
loggedInUserScenarioWithRole(t, "Should be able to read a snapshot's unencrypted data when calling GET on",
"GET", "/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"GET", "/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
hs := &HTTPServer{dashboardsnapshotsService: setUpSnapshotTest(t, 0, "")}
sc.handlerFunc = hs.GetDashboardSnapshot
sc.fakeReqWithParams("GET", sc.url, map[string]string{"key": "12345"}).exec()
@@ -243,7 +244,7 @@ func TestGetDashboardSnapshotNotFound(t *testing.T) {
loggedInUserScenarioWithRole(t,
"GET /snapshots/{key} should return 404 when the snapshot does not exist", "GET",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.GetDashboardSnapshot
@@ -254,7 +255,7 @@ func TestGetDashboardSnapshotNotFound(t *testing.T) {
loggedInUserScenarioWithRole(t,
"DELETE /snapshots/{key} should return 404 when the snapshot does not exist", "DELETE",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.DeleteDashboardSnapshot
@@ -265,7 +266,7 @@ func TestGetDashboardSnapshotNotFound(t *testing.T) {
loggedInUserScenarioWithRole(t,
"GET /snapshots-delete/{deleteKey} should return 404 when the snapshot does not exist", "DELETE",
"/api/snapshots-delete/12345", "/api/snapshots-delete/:deleteKey", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots-delete/12345", "/api/snapshots-delete/:deleteKey", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.DeleteDashboardSnapshotByDeleteKey
@@ -293,7 +294,7 @@ func TestGetDashboardSnapshotFailure(t *testing.T) {
loggedInUserScenarioWithRole(t,
"GET /snapshots/{key} should return 404 when the snapshot does not exist", "GET",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.GetDashboardSnapshot
@@ -304,7 +305,7 @@ func TestGetDashboardSnapshotFailure(t *testing.T) {
loggedInUserScenarioWithRole(t,
"DELETE /snapshots/{key} should return 404 when the snapshot does not exist", "DELETE",
"/api/snapshots/12345", "/api/snapshots/:key", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots/12345", "/api/snapshots/:key", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.DeleteDashboardSnapshot
@@ -315,7 +316,7 @@ func TestGetDashboardSnapshotFailure(t *testing.T) {
loggedInUserScenarioWithRole(t,
"GET /snapshots-delete/{deleteKey} should return 404 when the snapshot does not exist", "DELETE",
"/api/snapshots-delete/12345", "/api/snapshots-delete/:deleteKey", models.ROLE_EDITOR, func(sc *scenarioContext) {
"/api/snapshots-delete/12345", "/api/snapshots-delete/:deleteKey", org.RoleEditor, func(sc *scenarioContext) {
d := setUpSnapshotTest(t)
hs := &HTTPServer{dashboardsnapshotsService: d}
sc.handlerFunc = hs.DeleteDashboardSnapshotByDeleteKey
+28 -26
View File
@@ -31,12 +31,14 @@ import (
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/libraryelements"
"github.com/grafana/grafana/pkg/services/live"
"github.com/grafana/grafana/pkg/services/org"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/provisioning"
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@@ -45,7 +47,7 @@ func TestGetHomeDashboard(t *testing.T) {
httpReq, err := http.NewRequest(http.MethodGet, "", nil)
require.NoError(t, err)
httpReq.Header.Add("Content-Type", "application/json")
req := &models.ReqContext{SignedInUser: &models.SignedInUser{}, Context: &web.Context{Req: httpReq}}
req := &models.ReqContext{SignedInUser: &user.SignedInUser{}, Context: &web.Context{Req: httpReq}}
cfg := setting.NewCfg()
cfg.StaticRootPath = "../../public/"
prefService := preftest.NewPreferenceServiceFake()
@@ -145,8 +147,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
}
setUp := func() {
viewerRole := models.ROLE_VIEWER
editorRole := models.ROLE_EDITOR
viewerRole := org.RoleViewer
editorRole := org.RoleEditor
dashboardService.On("GetDashboardACLInfoList", mock.Anything, mock.AnythingOfType("*models.GetDashboardACLInfoListQuery")).Run(func(args mock.Arguments) {
q := args.Get(1).(*models.GetDashboardACLInfoListQuery)
q.Result = []*models.DashboardACLInfoDTO{
@@ -162,7 +164,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
// 2. user is an org editor
t.Run("When user is an Org Viewer", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
setUp()
@@ -194,7 +196,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Editor", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
setUp()
@@ -283,7 +285,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
// 6. user is an org editor AND has been granted a view permission
t.Run("When user is an Org Viewer and has no permissions for this dashboard", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
setUp()
@@ -322,7 +324,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Editor and has no permissions for this dashboard", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/abcdefghi",
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
setUp()
@@ -359,7 +361,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Viewer but has an edit permission", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
setUpInner := func() {
origCanEdit := setting.ViewersCanEdit
@@ -421,7 +423,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Viewer and viewers can edit", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
setUpInner := func() {
origCanEdit := setting.ViewersCanEdit
@@ -461,7 +463,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Viewer but has an admin permission", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
setUpInner := func() {
origCanEdit := setting.ViewersCanEdit
@@ -520,7 +522,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("When user is an Org Editor but has a view permission", func(t *testing.T) {
role := models.ROLE_EDITOR
role := org.RoleEditor
setUpInner := func() {
dashboardService := dashboards.NewFakeDashboardService(t)
@@ -758,7 +760,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
}
t.Run("when user does not have permission", func(t *testing.T) {
role := models.ROLE_VIEWER
role := org.RoleViewer
postDiffScenario(t, "When calling POST on", "/api/dashboards/calculate-diff", "/api/dashboards/calculate-diff", cmd, role, func(sc *scenarioContext) {
setUp()
@@ -768,7 +770,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
})
t.Run("when user does have permission", func(t *testing.T) {
role := models.ROLE_ADMIN
role := org.RoleAdmin
postDiffScenario(t, "When calling POST on", "/api/dashboards/calculate-diff", "/api/dashboards/calculate-diff", cmd, role, func(sc *scenarioContext) {
// This test shouldn't hit GetDashboardACLInfoList, so no setup needed
sc.dashboardVersionService = fakeDashboardVersionService
@@ -872,7 +874,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
}).Return(nil)
guardian.InitLegacyGuardian(mockSQLStore, dashboardService)
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", org.RoleEditor, func(sc *scenarioContext) {
fakeProvisioningService := provisioning.NewProvisioningServiceMock(context.Background())
fakeProvisioningService.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
return "/tmp/grafana/dashboards"
@@ -883,7 +885,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
assert.Equal(t, "../../../dashboard1.json", dash.Meta.ProvisionedExternalId, mockSQLStore)
}, mockSQLStore)
loggedInUserScenarioWithRole(t, "When allowUiUpdates is true and calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When allowUiUpdates is true and calling GET on", "GET", "/api/dashboards/uid/dash", "/api/dashboards/uid/:uid", org.RoleEditor, func(sc *scenarioContext) {
fakeProvisioningService := provisioning.NewProvisioningServiceMock(context.Background())
fakeProvisioningService.GetDashboardProvisionerResolvedPathFunc = func(name string) string {
return "/tmp/grafana/dashboards"
@@ -1032,7 +1034,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{OrgId: cmd.OrgId, UserId: cmd.UserId}
sc.context.SignedInUser = &user.SignedInUser{OrgId: cmd.OrgId, UserId: cmd.UserId}
return hs.PostDashboard(c)
})
@@ -1044,7 +1046,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
}
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions,
role models.RoleType, fn scenarioFunc, sqlmock sqlstore.Store, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) {
role org.RoleType, fn scenarioFunc, sqlmock sqlstore.Store, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
cfg := setting.NewCfg()
hs := HTTPServer{
@@ -1065,7 +1067,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{
sc.context.SignedInUser = &user.SignedInUser{
OrgId: testOrgID,
UserId: testUserID,
}
@@ -1106,11 +1108,11 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{
sc.context.SignedInUser = &user.SignedInUser{
OrgId: testOrgID,
UserId: testUserID,
}
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.RestoreDashboardVersion(c)
})
@@ -1148,23 +1150,23 @@ func (m *mockLibraryPanelService) CleanLibraryPanelsForDashboard(dash *models.Da
return nil
}
func (m *mockLibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error {
func (m *mockLibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
return nil
}
func (m *mockLibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
func (m *mockLibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
return nil
}
type mockLibraryElementService struct {
}
func (l *mockLibraryElementService) CreateElement(c context.Context, signedInUser *models.SignedInUser, cmd libraryelements.CreateLibraryElementCommand) (libraryelements.LibraryElementDTO, error) {
func (l *mockLibraryElementService) CreateElement(c context.Context, signedInUser *user.SignedInUser, cmd libraryelements.CreateLibraryElementCommand) (libraryelements.LibraryElementDTO, error) {
return libraryelements.LibraryElementDTO{}, nil
}
// GetElement gets an element from a UID.
func (l *mockLibraryElementService) GetElement(c context.Context, signedInUser *models.SignedInUser, UID string) (libraryelements.LibraryElementDTO, error) {
func (l *mockLibraryElementService) GetElement(c context.Context, signedInUser *user.SignedInUser, UID string) (libraryelements.LibraryElementDTO, error) {
return libraryelements.LibraryElementDTO{}, nil
}
@@ -1174,7 +1176,7 @@ func (l *mockLibraryElementService) GetElementsForDashboard(c context.Context, d
}
// ConnectElementsToDashboard connects elements to a specific dashboard.
func (l *mockLibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error {
func (l *mockLibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error {
return nil
}
@@ -1184,6 +1186,6 @@ func (l *mockLibraryElementService) DisconnectElementsFromDashboard(c context.Co
}
// DeleteLibraryElementsInFolder deletes all elements for a specific folder.
func (l *mockLibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *models.SignedInUser, folderUID string) error {
func (l *mockLibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *user.SignedInUser, folderUID string) error {
return nil
}
+2 -1
View File
@@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/adapters"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/datasources/permissions"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util/proxyutil"
"github.com/grafana/grafana/pkg/web"
@@ -833,7 +834,7 @@ func (hs *HTTPServer) decryptSecureJsonDataFn(ctx context.Context) func(ds *data
}
}
func (hs *HTTPServer) filterDatasourcesByQueryPermission(ctx context.Context, user *models.SignedInUser, ds []*datasources.DataSource) ([]*datasources.DataSource, error) {
func (hs *HTTPServer) filterDatasourcesByQueryPermission(ctx context.Context, user *user.SignedInUser, ds []*datasources.DataSource) ([]*datasources.DataSource, error) {
query := datasources.DatasourcesPermissionFilterQuery{
User: user,
Datasources: ds,
+2 -1
View File
@@ -19,6 +19,7 @@ import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/datasources/permissions"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/setting"
)
@@ -520,7 +521,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.Login = testUserLogin
sc.context.OrgRole = models.ROLE_VIEWER
sc.context.OrgRole = org.RoleViewer
sc.context.IsSignedIn = true
}
sc.m.Use(pretendSignInMiddleware)
+7 -4
View File
@@ -1,6 +1,9 @@
package dtos
import "github.com/grafana/grafana/pkg/models"
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
)
// swagger:model
type UpdateDashboardACLCommand struct {
@@ -9,9 +12,9 @@ type UpdateDashboardACLCommand struct {
// swagger:model
type DashboardACLUpdateItem struct {
UserID int64 `json:"userId"`
TeamID int64 `json:"teamId"`
Role *models.RoleType `json:"role,omitempty"`
UserID int64 `json:"userId"`
TeamID int64 `json:"teamId"`
Role *org.RoleType `json:"role,omitempty"`
// Permission level
// Description:
// * `1` - View
+2 -2
View File
@@ -3,8 +3,8 @@ package dtos
import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
)
// swagger:model
@@ -20,7 +20,7 @@ type NewApiKeyResult struct {
type ApiKeyDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Role models.RoleType `json:"role"`
Role org.RoleType `json:"role"`
Expiration *time.Time `json:"expiration,omitempty"`
AccessControl accesscontrol.Metadata `json:"accessControl,omitempty"`
}
+5 -5
View File
@@ -1,12 +1,12 @@
package dtos
import "github.com/grafana/grafana/pkg/models"
import "github.com/grafana/grafana/pkg/services/org"
type AddInviteForm struct {
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
Name string `json:"name"`
Role models.RoleType `json:"role" binding:"Required"`
SendEmail bool `json:"sendEmail"`
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
Name string `json:"name"`
Role org.RoleType `json:"role" binding:"Required"`
SendEmail bool `json:"sendEmail"`
}
type InviteInfo struct {
+5 -4
View File
@@ -9,7 +9,8 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -37,13 +38,13 @@ type CurrentUser struct {
OrgCount int `json:"orgCount"`
OrgId int64 `json:"orgId"`
OrgName string `json:"orgName"`
OrgRole models.RoleType `json:"orgRole"`
OrgRole org.RoleType `json:"orgRole"`
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
GravatarUrl string `json:"gravatarUrl"`
Timezone string `json:"timezone"`
WeekStart string `json:"weekStart"`
Locale string `json:"locale"`
HelpFlags1 models.HelpFlags1 `json:"helpFlags1"`
HelpFlags1 user.HelpFlags1 `json:"helpFlags1"`
HasEditPermissionInFolders bool `json:"hasEditPermissionInFolders"`
Permissions UserPermissionsMap `json:"permissions,omitempty"`
}
@@ -120,7 +121,7 @@ func GetGravatarUrlWithDefault(text string, defaultText string) string {
return GetGravatarUrl(text)
}
func IsHiddenUser(userLogin string, signedInUser *models.SignedInUser, cfg *setting.Cfg) bool {
func IsHiddenUser(userLogin string, signedInUser *user.SignedInUser, cfg *setting.Cfg) bool {
if userLogin == "" || signedInUser.IsGrafanaAdmin || userLogin == signedInUser.Login {
return false
}
+7 -7
View File
@@ -3,7 +3,7 @@ package dtos
import (
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
)
@@ -17,14 +17,14 @@ func TestIsHiddenUser(t *testing.T) {
testcases := []struct {
desc string
userLogin string
signedInUser *models.SignedInUser
signedInUser *user.SignedInUser
hiddenUsers map[string]struct{}
expected bool
}{
{
desc: "non-server admin user should see non-hidden user",
userLogin: "user",
signedInUser: &models.SignedInUser{
signedInUser: &user.SignedInUser{
IsGrafanaAdmin: false,
Login: "admin",
},
@@ -34,7 +34,7 @@ func TestIsHiddenUser(t *testing.T) {
{
desc: "non-server admin user should not see hidden user",
userLogin: "user",
signedInUser: &models.SignedInUser{
signedInUser: &user.SignedInUser{
IsGrafanaAdmin: false,
Login: "admin",
},
@@ -44,7 +44,7 @@ func TestIsHiddenUser(t *testing.T) {
{
desc: "non-server admin user should see himself, even if he's hidden",
userLogin: "admin",
signedInUser: &models.SignedInUser{
signedInUser: &user.SignedInUser{
IsGrafanaAdmin: false,
Login: "admin",
},
@@ -56,7 +56,7 @@ func TestIsHiddenUser(t *testing.T) {
{
desc: "server admin user should see hidden user",
userLogin: "user",
signedInUser: &models.SignedInUser{
signedInUser: &user.SignedInUser{
IsGrafanaAdmin: true,
Login: "admin",
},
@@ -66,7 +66,7 @@ func TestIsHiddenUser(t *testing.T) {
{
desc: "server admin user should see non-hidden user",
userLogin: "user",
signedInUser: &models.SignedInUser{
signedInUser: &user.SignedInUser{
IsGrafanaAdmin: true,
Login: "admin",
},
+6 -5
View File
@@ -18,6 +18,7 @@ import (
service "github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/setting"
)
@@ -51,7 +52,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
t.Run("Given folder not exists", func(t *testing.T) {
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, dashboards.ErrFolderNotFound).Twice()
mockSQLStore := mockstore.NewSQLStoreMock()
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleEditor, func(sc *scenarioContext) {
callGetFolderPermissions(sc, hs)
assert.Equal(t, 404, sc.resp.Code)
}, mockSQLStore)
@@ -84,7 +85,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, dashboards.ErrFolderAccessDenied).Twice()
mockSQLStore := mockstore.NewSQLStoreMock()
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_EDITOR, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleEditor, func(sc *scenarioContext) {
callGetFolderPermissions(sc, hs)
assert.Equal(t, 403, sc.resp.Code)
}, mockSQLStore)
@@ -130,7 +131,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
mockSQLStore := mockstore.NewSQLStoreMock()
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleAdmin, func(sc *scenarioContext) {
callGetFolderPermissions(sc, hs)
assert.Equal(t, 200, sc.resp.Code)
@@ -205,7 +206,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
})
t.Run("When trying to update team or user permissions with a role", func(t *testing.T) {
role := models.ROLE_ADMIN
role := org.RoleAdmin
cmds := []dtos.UpdateDashboardACLCommand{
{
Items: []dtos.DashboardACLUpdateItem{
@@ -303,7 +304,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
var resp []*models.DashboardACLInfoDTO
mockSQLStore := mockstore.NewSQLStoreMock()
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", models.ROLE_ADMIN, func(sc *scenarioContext) {
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleAdmin, func(sc *scenarioContext) {
callGetFolderPermissions(sc, hs)
assert.Equal(t, 200, sc.resp.Code)
+12 -11
View File
@@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
)
@@ -155,7 +156,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) {
}, nil)
req := server.NewGetRequest("/api/folders?accesscontrol=true")
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("2")},
@@ -184,7 +185,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) {
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil)
req := server.NewGetRequest("/api/folders/folderUid?accesscontrol=true")
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("folderUid")},
@@ -207,7 +208,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) {
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil)
req := server.NewGetRequest("/api/folders/folderUid")
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("folderUid")},
@@ -255,7 +256,7 @@ func createFolderScenario(t *testing.T, desc string, url string, routePattern st
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{OrgId: testOrgID, UserId: testUserID}
sc.context.SignedInUser = &user.SignedInUser{OrgId: testOrgID, UserId: testUserID}
return hs.CreateFolder(c)
})
@@ -285,7 +286,7 @@ func updateFolderScenario(t *testing.T, desc string, url string, routePattern st
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{OrgId: testOrgID, UserId: testUserID}
sc.context.SignedInUser = &user.SignedInUser{OrgId: testOrgID, UserId: testUserID}
return hs.UpdateFolder(c)
})
@@ -314,28 +315,28 @@ type fakeFolderService struct {
DeletedFolderUids []string
}
func (s *fakeFolderService) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
func (s *fakeFolderService) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
return s.GetFoldersResult, s.GetFoldersError
}
func (s *fakeFolderService) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
func (s *fakeFolderService) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
return s.GetFolderByIDResult, s.GetFolderByIDError
}
func (s *fakeFolderService) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
func (s *fakeFolderService) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
return s.GetFolderByUIDResult, s.GetFolderByUIDError
}
func (s *fakeFolderService) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) {
func (s *fakeFolderService) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) {
return s.CreateFolderResult, s.CreateFolderError
}
func (s *fakeFolderService) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
func (s *fakeFolderService) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
cmd.Result = s.UpdateFolderResult
return s.UpdateFolderError
}
func (s *fakeFolderService) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
func (s *fakeFolderService) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
s.DeletedFolderUids = append(s.DeletedFolderUids, uid)
return s.DeleteFolderResult, s.DeleteFolderError
}
+6 -5
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/setting"
@@ -162,7 +163,7 @@ func enableServiceAccount(hs *HTTPServer, c *models.ReqContext) bool {
}
func (hs *HTTPServer) ReqCanAdminTeams(c *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN || (hs.Cfg.EditorsCanAdmin && c.OrgRole == models.ROLE_EDITOR)
return c.OrgRole == org.RoleAdmin || (hs.Cfg.EditorsCanAdmin && c.OrgRole == org.RoleEditor)
}
func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool, prefs *pref.Preference) ([]*dtos.NavLink, error) {
@@ -202,7 +203,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool, prefs *
}
canExplore := func(context *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR || setting.ViewersCanEdit
return c.OrgRole == org.RoleAdmin || c.OrgRole == org.RoleEditor || setting.ViewersCanEdit
}
if setting.ExploreEnabled && hasAccess(canExplore, ac.EvalPermission(ac.ActionDatasourcesExplore)) {
@@ -284,7 +285,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool, prefs *
})
}
if c.OrgRole == models.ROLE_ADMIN {
if c.OrgRole == org.RoleAdmin {
configNodes = append(configNodes, &dtos.NavLink{
Text: "Plugins",
Id: "plugins",
@@ -537,7 +538,7 @@ func (hs *HTTPServer) buildLegacyAlertNavLinks(c *models.ReqContext) []*dtos.Nav
Text: "Alert rules", Id: "alert-list", Url: hs.Cfg.AppSubURL + "/alerting/list", Icon: "list-ul",
})
if c.HasRole(models.ROLE_EDITOR) {
if c.HasRole(org.RoleEditor) {
alertChildNavs = append(alertChildNavs, &dtos.NavLink{
Text: "Notification channels", Id: "channels", Url: hs.Cfg.AppSubURL + "/alerting/notifications",
Icon: "comment-alt-share",
@@ -581,7 +582,7 @@ func (hs *HTTPServer) buildAlertNavLinks(c *models.ReqContext) []*dtos.NavLink {
alertChildNavs = append(alertChildNavs, &dtos.NavLink{Text: "Alert groups", Id: "groups", Url: hs.Cfg.AppSubURL + "/alerting/groups", Icon: "layer-group"})
}
if c.OrgRole == models.ROLE_ADMIN {
if c.OrgRole == org.RoleAdmin {
alertChildNavs = append(alertChildNavs, &dtos.NavLink{
Text: "Admin", Id: "alerting-admin", Url: hs.Cfg.AppSubURL + "/alerting/admin",
Icon: "cog",
+6 -5
View File
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
@@ -39,10 +40,10 @@ type LDAPAttribute struct {
// RoleDTO is a serializer for mapped roles from LDAP
type LDAPRoleDTO struct {
OrgId int64 `json:"orgId"`
OrgName string `json:"orgName"`
OrgRole models.RoleType `json:"orgRole"`
GroupDN string `json:"groupDN"`
OrgId int64 `json:"orgId"`
OrgName string `json:"orgName"`
OrgRole org.RoleType `json:"orgRole"`
GroupDN string `json:"groupDN"`
}
// LDAPUserDTO is a serializer for users mapped from LDAP
@@ -333,7 +334,7 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) response.Response {
}
orgIDs := []int64{} // IDs of the orgs the user is a member of
orgRolesMap := map[int64]models.RoleType{}
orgRolesMap := map[int64]org.RoleType{}
for _, group := range serverConfig.Groups {
// only use the first match for each org
if orgRolesMap[group.OrgId] != "" {
+9 -8
View File
@@ -20,6 +20,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/usertest"
@@ -107,7 +108,7 @@ func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
Email: "john.doe@example.com",
Login: "johndoe",
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org"},
OrgRoles: map[int64]models.RoleType{1: models.ROLE_ADMIN, 2: models.ROLE_VIEWER},
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin, 2: org.RoleViewer},
IsGrafanaAdmin: &isAdmin,
}
@@ -122,12 +123,12 @@ func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
{
GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
{
GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
OrgId: 2,
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
},
},
}
@@ -162,7 +163,7 @@ func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
Email: "john.doe@example.com",
Login: "johndoe",
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org", "another-group-not-matched"},
OrgRoles: map[int64]models.RoleType{1: models.ROLE_ADMIN},
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin},
IsGrafanaAdmin: &isAdmin,
}
@@ -177,12 +178,12 @@ func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
{
GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
{
GroupDN: "cn=admins2,ou=groups,dc=grafana,dc=org",
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
},
}
@@ -237,7 +238,7 @@ func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
Email: "john.doe@example.com",
Login: "johndoe",
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org"},
OrgRoles: map[int64]models.RoleType{1: models.ROLE_ADMIN},
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin},
IsGrafanaAdmin: &isAdmin,
}
@@ -252,7 +253,7 @@ func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
{
GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
},
}
+3 -2
View File
@@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
@@ -268,12 +269,12 @@ func (hs *HTTPServer) buildExternalUserInfo(token *oauth2.Token, userInfo *socia
Name: userInfo.Name,
Login: userInfo.Login,
Email: userInfo.Email,
OrgRoles: map[int64]models.RoleType{},
OrgRoles: map[int64]org.RoleType{},
Groups: userInfo.Groups,
}
if userInfo.Role != "" && !hs.Cfg.OAuthSkipOrgRoleUpdateSync {
rt := models.RoleType(userInfo.Role)
rt := org.RoleType(userInfo.Role)
if rt.IsValid() {
// The user will be assigned a role in either the auto-assigned organization or in the default one
var orgID int64
+2 -2
View File
@@ -154,7 +154,7 @@ func TestLoginViewRedirect(t *testing.T) {
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
c.IsSignedIn = true
c.SignedInUser = &models.SignedInUser{
c.SignedInUser = &user.SignedInUser{
UserId: 10,
}
hs.LoginView(c)
@@ -571,7 +571,7 @@ func setupAuthProxyLoginTest(t *testing.T, enableLoginToken bool) *scenarioConte
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
c.IsSignedIn = true
c.SignedInUser = &models.SignedInUser{
c.SignedInUser = &user.SignedInUser{
UserId: 10,
}
hs.LoginView(c)
+6 -5
View File
@@ -14,12 +14,13 @@ import (
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web/webtest"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/models"
fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes"
"github.com/grafana/grafana/pkg/services/query"
)
@@ -57,7 +58,7 @@ type fakeOAuthTokenService struct {
token *oauth2.Token
}
func (ts *fakeOAuthTokenService) GetCurrentOAuthToken(context.Context, *models.SignedInUser) *oauth2.Token {
func (ts *fakeOAuthTokenService) GetCurrentOAuthToken(context.Context, *user.SignedInUser) *oauth2.Token {
return ts.token
}
@@ -98,7 +99,7 @@ func TestAPIEndpoint_Metrics_QueryMetricsV2(t *testing.T) {
t.Run("Status code is 400 when data source response has an error and feature toggle is disabled", func(t *testing.T) {
req := serverFeatureDisabled.NewPostRequest("/api/ds/query", strings.NewReader(queryDatasourceInput))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_VIEWER})
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleViewer})
resp, err := serverFeatureDisabled.SendJSON(req)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
@@ -107,7 +108,7 @@ func TestAPIEndpoint_Metrics_QueryMetricsV2(t *testing.T) {
t.Run("Status code is 207 when data source response has an error and feature toggle is enabled", func(t *testing.T) {
req := serverFeatureEnabled.NewPostRequest("/api/ds/query", strings.NewReader(queryDatasourceInput))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_VIEWER})
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleViewer})
resp, err := serverFeatureEnabled.SendJSON(req)
require.NoError(t, err)
require.NoError(t, resp.Body.Close())
@@ -141,7 +142,7 @@ func TestAPIEndpoint_Metrics_PluginDecryptionFailure(t *testing.T) {
t.Run("Status code is 500 and a secrets plugin error is returned if there is a problem getting secrets from the remote plugin", func(t *testing.T) {
req := httpServer.NewPostRequest("/api/ds/query", strings.NewReader(queryDatasourceInput))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_VIEWER})
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleViewer})
resp, err := httpServer.SendJSON(req)
require.NoError(t, err)
require.Equal(t, http.StatusInternalServerError, resp.StatusCode)
+6 -6
View File
@@ -7,8 +7,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/usertest"
)
@@ -29,7 +29,7 @@ func TestOrgInvitesAPIEndpointAccess(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -37,7 +37,7 @@ func TestOrgInvitesAPIEndpointAccess(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -45,7 +45,7 @@ func TestOrgInvitesAPIEndpointAccess(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: "users:id:100"}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusOK,
@@ -53,7 +53,7 @@ func TestOrgInvitesAPIEndpointAccess(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "new user", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "new user", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -61,7 +61,7 @@ func TestOrgInvitesAPIEndpointAccess(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{},
input: `{"loginOrEmail": "new user", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "new user", "role": "` + string(org.RoleViewer) + `"}`,
},
}
+1 -1
View File
@@ -186,7 +186,7 @@ func TestAPIEndpoint_PutCurrentOrgAddress_AccessControl(t *testing.T) {
// `/api/orgs/` endpoints test
// setupOrgsDBForAccessControlTests stores users and create specified number of orgs
func setupOrgsDBForAccessControlTests(t *testing.T, db sqlstore.Store, usr models.SignedInUser, orgsCount int) {
func setupOrgsDBForAccessControlTests(t *testing.T, db sqlstore.Store, usr user.SignedInUser, orgsCount int) {
t.Helper()
_, err := db.CreateUser(context.Background(), user.CreateUserCommand{Email: usr.Email, SkipOrgSetup: true, Login: usr.Login})
+1 -1
View File
@@ -201,7 +201,7 @@ func (hs *HTTPServer) GetOrgUsers(c *models.ReqContext) response.Response {
return response.JSON(http.StatusOK, result)
}
func (hs *HTTPServer) getOrgUsersHelper(c *models.ReqContext, query *models.GetOrgUsersQuery, signedInUser *models.SignedInUser) ([]*models.OrgUserDTO, error) {
func (hs *HTTPServer) getOrgUsersHelper(c *models.ReqContext, query *models.GetOrgUsersQuery, signedInUser *user.SignedInUser) ([]*models.OrgUserDTO, error) {
if err := hs.SQLStore.GetOrgUsers(c.Req.Context(), query); err != nil {
return nil, err
}
+31 -30
View File
@@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -118,7 +119,7 @@ func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
}, mock)
loggedInUserScenarioWithRole(t, "When calling GET as an admin on", "GET", "api/org/users/lookup",
"api/org/users/lookup", models.ROLE_ADMIN, func(sc *scenarioContext) {
"api/org/users/lookup", org.RoleAdmin, func(sc *scenarioContext) {
setUpGetOrgUsersDB(t, sqlStore)
sc.handlerFunc = hs.GetOrgUsersForCurrentOrgLookup
@@ -234,11 +235,11 @@ func TestOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
}
var (
testServerAdminViewer = models.SignedInUser{
testServerAdminViewer = user.SignedInUser{
UserId: 1,
OrgId: 1,
OrgName: "TestOrg1",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testServerAdmin",
Name: "testServerAdmin",
Email: "testServerAdmin@example.org",
@@ -247,11 +248,11 @@ var (
IsAnonymous: false,
}
testAdminOrg2 = models.SignedInUser{
testAdminOrg2 = user.SignedInUser{
UserId: 2,
OrgId: 2,
OrgName: "TestOrg2",
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Login: "testAdmin",
Name: "testAdmin",
Email: "testAdmin@example.org",
@@ -260,11 +261,11 @@ var (
IsAnonymous: false,
}
testEditorOrg1 = models.SignedInUser{
testEditorOrg1 = user.SignedInUser{
UserId: 3,
OrgId: 1,
OrgName: "TestOrg1",
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Login: "testEditor",
Name: "testEditor",
Email: "testEditor@example.org",
@@ -308,7 +309,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
enableAccessControl bool
expectedCode int
expectedMetadata map[string]bool
user models.SignedInUser
user user.SignedInUser
targetOrg int64
}
@@ -365,7 +366,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
enableAccessControl bool
expectedCode int
expectedUserCount int
user models.SignedInUser
user user.SignedInUser
targetOrg int64
}
@@ -458,7 +459,7 @@ func TestPostOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
type testCase struct {
name string
enableAccessControl bool
user models.SignedInUser
user user.SignedInUser
targetOrg int64
input string
expectedCode int
@@ -553,7 +554,7 @@ func TestPostOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
err := json.NewDecoder(response.Body).Decode(&message)
require.NoError(t, err)
getUsersQuery := models.GetOrgUsersQuery{OrgId: tc.targetOrg, User: &models.SignedInUser{
getUsersQuery := models.GetOrgUsersQuery{OrgId: tc.targetOrg, User: &user.SignedInUser{
OrgId: tc.targetOrg,
Permissions: map[int64]map[string][]string{tc.targetOrg: {"org.users:read": {"users:*"}}},
}}
@@ -580,7 +581,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/org/users",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -588,7 +589,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/org/users",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_EDITOR) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleEditor) + `"}`,
},
{
expectedCode: http.StatusOK,
@@ -596,7 +597,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/orgs/1/users",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -604,7 +605,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/orgs/1/users",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(models.ROLE_EDITOR) + `"}`,
input: `{"loginOrEmail": "` + testAdminOrg2.Login + `", "role": "` + string(org.RoleEditor) + `"}`,
},
{
expectedCode: http.StatusOK,
@@ -612,7 +613,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: fmt.Sprintf("/api/org/users/%d", testEditorOrg1.UserId),
method: http.MethodPatch,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersWrite, Scope: accesscontrol.ScopeUsersAll}},
input: `{"role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -620,7 +621,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: fmt.Sprintf("/api/org/users/%d", testEditorOrg1.UserId),
method: http.MethodPatch,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersWrite, Scope: accesscontrol.ScopeUsersAll}},
input: `{"role": "` + string(models.ROLE_EDITOR) + `"}`,
input: `{"role": "` + string(org.RoleEditor) + `"}`,
},
{
expectedCode: http.StatusOK,
@@ -628,7 +629,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: fmt.Sprintf("/api/orgs/1/users/%d", testEditorOrg1.UserId),
method: http.MethodPatch,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersWrite, Scope: accesscontrol.ScopeUsersAll}},
input: `{"role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -636,7 +637,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: fmt.Sprintf("/api/orgs/1/users/%d", testEditorOrg1.UserId),
method: http.MethodPatch,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersWrite, Scope: accesscontrol.ScopeUsersAll}},
input: `{"role": "` + string(models.ROLE_EDITOR) + `"}`,
input: `{"role": "` + string(org.RoleEditor) + `"}`,
},
{
expectedCode: http.StatusOK,
@@ -644,7 +645,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgUsersAdd, Scope: accesscontrol.ScopeUsersAll}},
input: `{"loginOrEmail": "newUserEmail@test.com", "sendEmail": false, "role": "` + string(models.ROLE_VIEWER) + `"}`,
input: `{"loginOrEmail": "newUserEmail@test.com", "sendEmail": false, "role": "` + string(org.RoleViewer) + `"}`,
},
{
expectedCode: http.StatusForbidden,
@@ -652,7 +653,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
url: "/api/org/invites",
method: http.MethodPost,
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionUsersCreate}},
input: `{"loginOrEmail": "newUserEmail@test.com", "sendEmail": false, "role": "` + string(models.ROLE_EDITOR) + `"}`,
input: `{"loginOrEmail": "newUserEmail@test.com", "sendEmail": false, "role": "` + string(org.RoleEditor) + `"}`,
},
}
@@ -678,13 +679,13 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
type testCase struct {
name string
enableAccessControl bool
user models.SignedInUser
user user.SignedInUser
targetUserId int64
targetOrg int64
input string
expectedCode int
expectedMessage util.DynMap
expectedUserRole models.RoleType
expectedUserRole org.RoleType
}
tests := []testCase{
@@ -697,7 +698,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
input: `{"role": "Viewer"}`,
expectedCode: http.StatusOK,
expectedMessage: util.DynMap{"message": "Organization user updated"},
expectedUserRole: models.ROLE_VIEWER,
expectedUserRole: org.RoleViewer,
},
{
name: "server admin can update users in another org (legacy)",
@@ -708,7 +709,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
input: `{"role": "Editor"}`,
expectedCode: http.StatusOK,
expectedMessage: util.DynMap{"message": "Organization user updated"},
expectedUserRole: models.ROLE_EDITOR,
expectedUserRole: org.RoleEditor,
},
{
name: "org admin cannot update users in his org (legacy)",
@@ -737,7 +738,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
input: `{"role": "Viewer"}`,
expectedCode: http.StatusOK,
expectedMessage: util.DynMap{"message": "Organization user updated"},
expectedUserRole: models.ROLE_VIEWER,
expectedUserRole: org.RoleViewer,
},
{
name: "server admin can update users in another org",
@@ -748,7 +749,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
input: `{"role": "Editor"}`,
expectedCode: http.StatusOK,
expectedMessage: util.DynMap{"message": "Organization user updated"},
expectedUserRole: models.ROLE_EDITOR,
expectedUserRole: org.RoleEditor,
},
{
name: "org admin can update users in his org",
@@ -759,7 +760,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
input: `{"role": "Editor"}`,
expectedCode: http.StatusOK,
expectedMessage: util.DynMap{"message": "Organization user updated"},
expectedUserRole: models.ROLE_EDITOR,
expectedUserRole: org.RoleEditor,
},
{
name: "org admin cannot update users in another org",
@@ -807,7 +808,7 @@ func TestDeleteOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
type testCase struct {
name string
enableAccessControl bool
user models.SignedInUser
user user.SignedInUser
targetUserId int64
targetOrg int64
expectedCode int
@@ -909,7 +910,7 @@ func TestDeleteOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
getUsersQuery := models.GetOrgUsersQuery{
OrgId: tc.targetOrg,
User: &models.SignedInUser{
User: &user.SignedInUser{
OrgId: tc.targetOrg,
Permissions: map[int64]map[string][]string{tc.targetOrg: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
+3 -2
View File
@@ -9,6 +9,7 @@ import (
_ "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/user"
)
func (hs *HTTPServer) populateDashboardsByID(ctx context.Context, dashboardByIDs []int64, dashboardIDOrder map[int64]int) (dtos.PlaylistDashboardsSlice, error) {
@@ -35,7 +36,7 @@ func (hs *HTTPServer) populateDashboardsByID(ctx context.Context, dashboardByIDs
return result, nil
}
func (hs *HTTPServer) populateDashboardsByTag(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, dashboardByTag []string, dashboardTagOrder map[string]int) dtos.PlaylistDashboardsSlice {
func (hs *HTTPServer) populateDashboardsByTag(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, dashboardByTag []string, dashboardTagOrder map[string]int) dtos.PlaylistDashboardsSlice {
result := make(dtos.PlaylistDashboardsSlice, 0)
for _, tag := range dashboardByTag {
@@ -65,7 +66,7 @@ func (hs *HTTPServer) populateDashboardsByTag(ctx context.Context, orgID int64,
return result
}
func (hs *HTTPServer) LoadPlaylistDashboards(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, playlistUID string) (dtos.PlaylistDashboardsSlice, error) {
func (hs *HTTPServer) LoadPlaylistDashboards(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, playlistUID string) (dtos.PlaylistDashboardsSlice, error) {
playlistItems, _ := hs.LoadPlaylistItems(ctx, playlistUID, orgID)
dashboardByIDs := make([]int64, 0)
+7 -6
View File
@@ -8,10 +8,11 @@ import (
"net/http"
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/plugindashboards"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web/webtest"
"github.com/stretchr/testify/require"
)
@@ -52,9 +53,9 @@ func TestGetPluginDashboards(t *testing.T) {
})
t.Run("Signed in and not org admin should return 403 Forbidden", func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
}
resp, err := sendGetPluginDashboardsRequestForSignedInUser(t, s, existingPluginID, user)
@@ -64,10 +65,10 @@ func TestGetPluginDashboards(t *testing.T) {
})
t.Run("Signed in and org admin", func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: 1,
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
}
t.Run("When plugin doesn't exist should return 404 Not Found", func(t *testing.T) {
@@ -101,7 +102,7 @@ func TestGetPluginDashboards(t *testing.T) {
})
}
func sendGetPluginDashboardsRequestForSignedInUser(t *testing.T, s *webtest.Server, pluginID string, user *models.SignedInUser) (*http.Response, error) {
func sendGetPluginDashboardsRequestForSignedInUser(t *testing.T, s *webtest.Server, pluginID string, user *user.SignedInUser) (*http.Response, error) {
t.Helper()
req := s.NewGetRequest(fmt.Sprintf("/api/plugins/%s/dashboards", pluginID))
+20 -18
View File
@@ -28,10 +28,12 @@ import (
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/secrets/kvstore"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@@ -46,7 +48,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
{
Path: "api/v4/",
URL: "https://www.google.com",
ReqRole: models.ROLE_EDITOR,
ReqRole: org.RoleEditor,
Headers: []plugins.Header{
{Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"},
},
@@ -54,7 +56,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
{
Path: "api/admin",
URL: "https://www.google.com",
ReqRole: models.ROLE_ADMIN,
ReqRole: org.RoleAdmin,
Headers: []plugins.Header{
{Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"},
},
@@ -78,7 +80,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
},
{
Path: "api/restricted",
ReqRole: models.ROLE_ADMIN,
ReqRole: org.RoleAdmin,
},
{
Path: "api/body",
@@ -125,7 +127,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
require.NoError(t, err)
ctx := &models.ReqContext{
Context: &web.Context{Req: req},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor},
}
return ctx, req
}
@@ -200,7 +202,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("plugin route with admin role and user is admin", func(t *testing.T) {
ctx, _ := setUp()
ctx.SignedInUser.OrgRole = models.ROLE_ADMIN
ctx.SignedInUser.OrgRole = org.RoleAdmin
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/admin", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -265,7 +267,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
require.NoError(t, err)
ctx := &models.ReqContext{
Context: &web.Context{Req: req},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor},
}
t.Run("When creating and caching access tokens", func(t *testing.T) {
@@ -479,7 +481,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req, err := http.NewRequest("GET", "http://localhost/asd", nil)
require.NoError(t, err)
ctx := &models.ReqContext{
SignedInUser: &models.SignedInUser{UserId: 1},
SignedInUser: &user.SignedInUser{UserId: 1},
Context: &web.Context{Req: req},
}
@@ -517,7 +519,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req := getDatasourceProxiedRequest(
t,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
},
@@ -530,7 +532,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req := getDatasourceProxiedRequest(
t,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
},
@@ -544,7 +546,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req := getDatasourceProxiedRequest(
t,
&models.ReqContext{
SignedInUser: &models.SignedInUser{IsAnonymous: true},
SignedInUser: &user.SignedInUser{IsAnonymous: true},
},
&setting.Cfg{SendUserHeader: true},
)
@@ -621,7 +623,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
}
return &models.ReqContext{
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
Context: &web.Context{
Req: httptest.NewRequest("GET", "/render", nil),
Resp: responseWriter,
@@ -758,7 +760,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
ctx := models.ReqContext{
Context: &web.Context{},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor},
}
ds := datasources.DataSource{
Type: "test",
@@ -778,7 +780,7 @@ func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
ctx := models.ReqContext{
Context: &web.Context{},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor},
}
ds := datasources.DataSource{
Type: "test",
@@ -800,7 +802,7 @@ func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
func TestNewDataSourceProxy_MSSQL(t *testing.T) {
ctx := models.ReqContext{
Context: &web.Context{},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor},
}
tracer := tracing.InitializeTracerForTest()
@@ -996,13 +998,13 @@ func Test_PathCheck(t *testing.T) {
{
Path: "a",
URL: "https://www.google.com",
ReqRole: models.ROLE_EDITOR,
ReqRole: org.RoleEditor,
Method: http.MethodGet,
},
{
Path: "b",
URL: "https://www.google.com",
ReqRole: models.ROLE_VIEWER,
ReqRole: org.RoleViewer,
Method: http.MethodGet,
},
}
@@ -1013,7 +1015,7 @@ func Test_PathCheck(t *testing.T) {
require.NoError(t, err)
ctx := &models.ReqContext{
Context: &web.Context{Req: req},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleViewer},
}
return ctx, req
}
@@ -1033,7 +1035,7 @@ type mockOAuthTokenService struct {
oAuthEnabled bool
}
func (m *mockOAuthTokenService) GetCurrentOAuthToken(ctx context.Context, user *models.SignedInUser) *oauth2.Token {
func (m *mockOAuthTokenService) GetCurrentOAuthToken(ctx context.Context, user *user.SignedInUser) *oauth2.Token {
return m.token
}
+11 -9
View File
@@ -9,10 +9,12 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/pluginsettings"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
@@ -45,7 +47,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -71,7 +73,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -98,7 +100,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -124,7 +126,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{IsAnonymous: true},
SignedInUser: &user.SignedInUser{IsAnonymous: true},
Context: &web.Context{
Req: httpReq,
},
@@ -158,7 +160,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -189,7 +191,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -228,7 +230,7 @@ func TestPluginProxy(t *testing.T) {
t,
secretsService,
&models.ReqContext{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
Login: "test_user",
},
Context: &web.Context{
@@ -261,7 +263,7 @@ func TestPluginProxy(t *testing.T) {
}
ctx := &models.ReqContext{
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
Context: &web.Context{
Req: httptest.NewRequest("GET", "/", nil),
Resp: responseWriter,
@@ -292,7 +294,7 @@ func getPluginProxiedRequest(t *testing.T, secretsService secrets.Service, ctx *
route = &plugins.Route{
Path: "api/v4/",
URL: "https://www.google.com",
ReqRole: models.ROLE_EDITOR,
ReqRole: org.RoleEditor,
}
}
proxy := NewApiPluginProxy(ctx, "", route, "", cfg, pluginSettingsService, secretsService)
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"strings"
"text/template"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/user"
)
// interpolateString accepts template data and return a string with substitutions
@@ -86,7 +86,7 @@ func setBodyContent(req *http.Request, route *plugins.Route, data templateData)
}
// Set the X-Grafana-User header if needed (and remove if not)
func applyUserHeader(sendUserHeader bool, req *http.Request, user *models.SignedInUser) {
func applyUserHeader(sendUserHeader bool, req *http.Request, user *user.SignedInUser) {
req.Header.Del("X-Grafana-User")
if sendUserHeader && !user.IsAnonymous {
req.Header.Set("X-Grafana-User", user.Login)
+2 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/api/dtos"
@@ -38,7 +39,7 @@ func (hs *HTTPServer) GetPluginList(c *models.ReqContext) response.Response {
// When using access control anyone that can create a data source should be able to list all data sources installed
// Fallback to only letting admins list non-core plugins
hasAccess := accesscontrol.HasAccess(hs.AccessControl, c)
if !hasAccess(accesscontrol.ReqOrgAdmin, accesscontrol.EvalPermission(datasources.ActionCreate)) && !c.HasRole(models.ROLE_ADMIN) {
if !hasAccess(accesscontrol.ReqOrgAdmin, accesscontrol.EvalPermission(datasources.ActionCreate)) && !c.HasRole(org.RoleAdmin) {
coreFilter = "1"
}
+4 -2
View File
@@ -21,7 +21,9 @@ import (
"github.com/grafana/grafana/pkg/infra/log/logtest"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
)
@@ -60,7 +62,7 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
t.Run(testName("Install", tc), func(t *testing.T) {
req := srv.NewPostRequest("/api/plugins/test/install", strings.NewReader("{ \"version\": \"1.0.2\" }"))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_EDITOR, IsGrafanaAdmin: true})
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleEditor, IsGrafanaAdmin: true})
resp, err := srv.SendJSON(req)
require.NoError(t, err)
@@ -78,7 +80,7 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
t.Run(testName("Uninstall", tc), func(t *testing.T) {
req := srv.NewPostRequest("/api/plugins/test/uninstall", strings.NewReader("{}"))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_VIEWER, IsGrafanaAdmin: true})
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleViewer, IsGrafanaAdmin: true})
resp, err := srv.SendJSON(req)
require.NoError(t, err)
+3 -2
View File
@@ -12,12 +12,13 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/user"
)
func TestHTTPServer_Search(t *testing.T) {
sc := setupHTTPServer(t, true, true)
sc.initCtx.IsSignedIn = true
sc.initCtx.SignedInUser = &models.SignedInUser{}
sc.initCtx.SignedInUser = &user.SignedInUser{}
sc.hs.SearchService = &mockSearchService{
ExpectedResult: models.HitList{
@@ -27,7 +28,7 @@ func TestHTTPServer_Search(t *testing.T) {
},
}
sc.acmock.GetUserPermissionsFunc = func(ctx context.Context, user *models.SignedInUser, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
sc.acmock.GetUserPermissionsFunc = func(ctx context.Context, user *user.SignedInUser, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
return []accesscontrol.Permission{
{Action: "folders:read", Scope: "folders:*"},
{Action: "folders:write", Scope: "folders:uid:folder2"},
+6 -5
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/shorturls"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
@@ -29,7 +30,7 @@ func TestShortURLAPIEndpoint(t *testing.T) {
Path: cmd.Path,
}
service := &fakeShortURLService{
createShortURLFunc: func(ctx context.Context, user *models.SignedInUser, path string) (*models.ShortUrl, error) {
createShortURLFunc: func(ctx context.Context, user *user.SignedInUser, path string) (*models.ShortUrl, error) {
return createResp, nil
},
}
@@ -64,7 +65,7 @@ func createShortURLScenario(t *testing.T, desc string, url string, routePattern
c.Req.Body = mockRequestBody(cmd)
c.Req.Header.Add("Content-Type", "application/json")
sc.context = c
sc.context.SignedInUser = &models.SignedInUser{OrgId: testOrgID, UserId: testUserID}
sc.context.SignedInUser = &user.SignedInUser{OrgId: testOrgID, UserId: testUserID}
return hs.createShortURL(c)
})
@@ -76,14 +77,14 @@ func createShortURLScenario(t *testing.T, desc string, url string, routePattern
}
type fakeShortURLService struct {
createShortURLFunc func(ctx context.Context, user *models.SignedInUser, path string) (*models.ShortUrl, error)
createShortURLFunc func(ctx context.Context, user *user.SignedInUser, path string) (*models.ShortUrl, error)
}
func (s *fakeShortURLService) GetShortURLByUID(ctx context.Context, user *models.SignedInUser, uid string) (*models.ShortUrl, error) {
func (s *fakeShortURLService) GetShortURLByUID(ctx context.Context, user *user.SignedInUser, uid string) (*models.ShortUrl, error) {
return nil, nil
}
func (s *fakeShortURLService) CreateShortURL(ctx context.Context, user *models.SignedInUser, path string) (*models.ShortUrl, error) {
func (s *fakeShortURLService) CreateShortURL(ctx context.Context, user *user.SignedInUser, path string) (*models.ShortUrl, error) {
if s.createShortURLFunc != nil {
return s.createShortURLFunc(ctx, user, path)
}
+4 -3
View File
@@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -28,7 +29,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
accessControlEnabled := !hs.AccessControl.IsDisabled()
if !accessControlEnabled && c.OrgRole == models.ROLE_VIEWER {
if !accessControlEnabled && c.OrgRole == org.RoleViewer {
return response.Error(403, "Not allowed to create team.", nil)
}
@@ -40,7 +41,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
return response.Error(500, "Failed to create Team", err)
}
if accessControlEnabled || (c.OrgRole == models.ROLE_EDITOR && hs.Cfg.EditorsCanAdmin) {
if accessControlEnabled || (c.OrgRole == org.RoleEditor && hs.Cfg.EditorsCanAdmin) {
// if the request is authenticated using API tokens
// the SignedInUser is an empty struct therefore
// an additional check whether it is an actual user is required
@@ -194,7 +195,7 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response {
// 2. If the user is an admin, this will return models.FilterIgnoreUser (0)
func userFilter(c *models.ReqContext) int64 {
userIdFilter := c.SignedInUser.UserId
if c.OrgRole == models.ROLE_ADMIN {
if c.OrgRole == org.RoleAdmin {
userIdFilter = models.FilterIgnoreUser
}
return userIdFilter
+4 -3
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/teamguardian/database"
@@ -27,7 +28,7 @@ type TeamGuardianMock struct {
result error
}
func (t *TeamGuardianMock) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *models.SignedInUser) error {
func (t *TeamGuardianMock) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *user.SignedInUser) error {
return t.result
}
@@ -66,7 +67,7 @@ func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
mock := mockstore.NewSQLStoreMock()
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members",
"api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) {
"api/teams/:teamId/members", org.RoleAdmin, func(sc *scenarioContext) {
setUpGetTeamMembersHandler(t, sqlStore)
sc.handlerFunc = hs.GetTeamMembers
@@ -88,7 +89,7 @@ func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
t.Cleanup(func() { settings.HiddenUsers = make(map[string]struct{}) })
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "api/teams/1/members",
"api/teams/:teamId/members", models.ROLE_ADMIN, func(sc *scenarioContext) {
"api/teams/:teamId/members", org.RoleAdmin, func(sc *scenarioContext) {
setUpGetTeamMembersHandler(t, sqlStore)
sc.handlerFunc = hs.GetTeamMembers
+7 -5
View File
@@ -15,10 +15,12 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@@ -33,7 +35,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
mock := &mockstore.SQLStoreMock{}
loggedInUserScenarioWithRole(t, "When admin is calling GET on", "GET", "/api/teams/search", "/api/teams/search",
models.ROLE_ADMIN, func(sc *scenarioContext) {
org.RoleAdmin, func(sc *scenarioContext) {
_, err := hs.SQLStore.CreateTeam("team1", "", 1)
require.NoError(t, err)
_, err = hs.SQLStore.CreateTeam("team2", "", 1)
@@ -117,10 +119,10 @@ func TestTeamAPIEndpoint(t *testing.T) {
logger := &logtest.Fake{}
c := &models.ReqContext{
Context: &web.Context{Req: req},
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
Logger: logger,
}
c.OrgRole = models.ROLE_EDITOR
c.OrgRole = org.RoleEditor
c.Req.Body = mockRequestBody(models.CreateTeamCommand{Name: teamName})
c.Req.Header.Add("Content-Type", "application/json")
r := hs.CreateTeam(c)
@@ -134,10 +136,10 @@ func TestTeamAPIEndpoint(t *testing.T) {
logger := &logtest.Fake{}
c := &models.ReqContext{
Context: &web.Context{Req: req},
SignedInUser: &models.SignedInUser{UserId: 42},
SignedInUser: &user.SignedInUser{UserId: 42},
Logger: logger,
}
c.OrgRole = models.ROLE_EDITOR
c.OrgRole = org.RoleEditor
c.Req.Body = mockRequestBody(models.CreateTeamCommand{Name: teamName})
c.Req.Header.Add("Content-Type", "application/json")
r := hs.CreateTeam(c)
+2 -2
View File
@@ -447,7 +447,7 @@ func (hs *HTTPServer) SetHelpFlag(c *models.ReqContext) response.Response {
}
bitmask := &c.HelpFlags1
bitmask.AddFlag(models.HelpFlags1(flag))
bitmask.AddFlag(user.HelpFlags1(flag))
cmd := models.SetUserHelpFlagCommand{
UserId: c.UserId,
@@ -473,7 +473,7 @@ func (hs *HTTPServer) SetHelpFlag(c *models.ReqContext) response.Response {
func (hs *HTTPServer) ClearHelpFlags(c *models.ReqContext) response.Response {
cmd := models.SetUserHelpFlagCommand{
UserId: c.UserId,
HelpFlags1: models.HelpFlags1(0),
HelpFlags1: user.HelpFlags1(0),
}
if err := hs.SQLStore.SetUserHelpFlag(c.Req.Context(), &cmd); err != nil {
+6 -5
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/usertest"
)
@@ -161,7 +162,7 @@ func revokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePat
sc.context = c
sc.context.UserId = userId
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.RevokeUserAuthToken(c)
})
@@ -187,7 +188,7 @@ func getUserAuthTokensScenario(t *testing.T, desc string, url string, routePatte
sc.context = c
sc.context.UserId = userId
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.GetUserAuthTokens(c)
})
@@ -210,7 +211,7 @@ func logoutUserFromAllDevicesInternalScenario(t *testing.T, desc string, userId
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
return hs.logoutUserFromAllDevicesInternal(context.Background(), userId)
})
@@ -237,7 +238,7 @@ func revokeUserAuthTokenInternalScenario(t *testing.T, desc string, cmd models.R
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
sc.context.UserToken = token
return hs.revokeUserAuthTokenInternal(c, userId, cmd)
@@ -262,7 +263,7 @@ func getUserAuthTokensInternalScenario(t *testing.T, desc string, token *models.
sc.context = c
sc.context.UserId = testUserID
sc.context.OrgId = testOrgID
sc.context.OrgRole = models.ROLE_ADMIN
sc.context.OrgRole = org.RoleAdmin
sc.context.UserToken = token
return hs.getUserAuthTokensInternal(c, testUserID)