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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
278 changed files with 1758 additions and 1543 deletions

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{

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
}

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)
})

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
}
}
}

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{}

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))
}
}

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)

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 {

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
}

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,

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

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
}

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,

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)

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

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"`
}

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 {

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
}

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",
},

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)

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
}

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",

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] != "" {

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,
},
},
}

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

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)

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)

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) + `"}`,
},
}

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})

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
}

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}}},
},

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)

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))

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
}

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)

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)

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"
}

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)

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"},

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)
}

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

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

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)

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 {

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)

View File

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/datasources"
"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"
)
@ -58,7 +59,7 @@ func TestApi_getUsageStats(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
uss.Cfg.ReportingEnabled = tt.enabled
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, IsGrafanaAdmin: tt.IsGrafanaAdmin}, uss)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, IsGrafanaAdmin: tt.IsGrafanaAdmin}, uss)
usageStats, recorder := getUsageStats(t, server)
require.Equal(t, tt.expectedStatus, recorder.Code)
@ -83,7 +84,7 @@ func getUsageStats(t *testing.T, server *web.Mux) (*models.SystemStats, *httptes
return &usageStats, recorder
}
func setupTestServer(t *testing.T, user *models.SignedInUser, service *UsageStats) *web.Mux {
func setupTestServer(t *testing.T, user *user.SignedInUser, service *UsageStats) *web.Mux {
server := web.New()
server.UseMiddleware(web.Renderer(path.Join(setting.StaticRootPath, "views"), "[[", "]]"))
server.Use(contextProvider(&testContext{user}))
@ -92,7 +93,7 @@ func setupTestServer(t *testing.T, user *models.SignedInUser, service *UsageStat
}
type testContext struct {
user *models.SignedInUser
user *user.SignedInUser
}
func contextProvider(tc *testContext) web.Handler {

View File

@ -10,6 +10,7 @@ import (
"strings"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"golang.org/x/oauth2"
"gopkg.in/square/go-jose.v2/jwt"
@ -122,19 +123,19 @@ func (claims *azureClaims) extractEmail() string {
return claims.Email
}
func (claims *azureClaims) extractRole(autoAssignRole string, strictMode bool) models.RoleType {
func (claims *azureClaims) extractRole(autoAssignRole string, strictMode bool) org.RoleType {
if len(claims.Roles) == 0 {
if strictMode {
return models.RoleType("")
return org.RoleType("")
}
return models.RoleType(autoAssignRole)
return org.RoleType(autoAssignRole)
}
roleOrder := []models.RoleType{
models.ROLE_ADMIN,
models.ROLE_EDITOR,
models.ROLE_VIEWER,
roleOrder := []org.RoleType{
org.RoleAdmin,
org.RoleEditor,
org.RoleViewer,
}
for _, role := range roleOrder {
@ -144,13 +145,13 @@ func (claims *azureClaims) extractRole(autoAssignRole string, strictMode bool) m
}
if strictMode {
return models.RoleType("")
return org.RoleType("")
}
return models.ROLE_VIEWER
return org.RoleViewer
}
func hasRole(roles []string, role models.RoleType) bool {
func hasRole(roles []string, role org.RoleType) bool {
for _, item := range roles {
if strings.EqualFold(item, string(role)) {
return true

View File

@ -14,6 +14,7 @@ import (
"strconv"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"golang.org/x/oauth2"
)
@ -180,7 +181,7 @@ func (s *SocialGenericOAuth) UserInfo(client *http.Client, token *oauth2.Token)
userInfo.Login = userInfo.Email
}
if s.roleAttributeStrict && !models.RoleType(userInfo.Role).IsValid() {
if s.roleAttributeStrict && !org.RoleType(userInfo.Role).IsValid() {
return nil, errors.New("invalid role")
}

View File

@ -7,6 +7,7 @@ import (
"net/http"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"golang.org/x/oauth2"
"gopkg.in/square/go-jose.v2/jwt"
)
@ -81,7 +82,7 @@ func (s *SocialOkta) UserInfo(client *http.Client, token *oauth2.Token) (*BasicU
if err != nil {
s.log.Error("Failed to extract role", "error", err)
}
if s.roleAttributeStrict && !models.RoleType(role).IsValid() {
if s.roleAttributeStrict && !org.RoleType(role).IsValid() {
return nil, errors.New("invalid role")
}

View File

@ -14,7 +14,7 @@ import (
"golang.org/x/oauth2"
"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/setting"
"github.com/grafana/grafana/pkg/util"
)
@ -311,10 +311,10 @@ type groupStruct struct {
Groups []string `json:"groups"`
}
func (s *SocialBase) extractRole(rawJSON []byte, groups []string) (models.RoleType, error) {
func (s *SocialBase) extractRole(rawJSON []byte, groups []string) (org.RoleType, error) {
if s.roleAttributePath == "" {
if s.autoAssignOrgRole != "" {
return models.RoleType(s.autoAssignOrgRole), nil
return org.RoleType(s.autoAssignOrgRole), nil
}
return "", nil
@ -322,13 +322,13 @@ func (s *SocialBase) extractRole(rawJSON []byte, groups []string) (models.RoleTy
role, err := s.searchJSONForStringAttr(s.roleAttributePath, rawJSON)
if err == nil && role != "" {
return models.RoleType(role), nil
return org.RoleType(role), nil
}
if groupBytes, err := json.Marshal(groupStruct{groups}); err == nil {
if role, err := s.searchJSONForStringAttr(
s.roleAttributePath, groupBytes); err == nil && role != "" {
return models.RoleType(role), nil
return org.RoleType(role), nil
}
}

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
@ -75,12 +76,12 @@ func removeForceLoginParams(str string) string {
}
func EnsureEditorOrViewerCanEdit(c *models.ReqContext) {
if !c.SignedInUser.HasRole(models.ROLE_EDITOR) && !setting.ViewersCanEdit {
if !c.SignedInUser.HasRole(org.RoleEditor) && !setting.ViewersCanEdit {
accessForbidden(c)
}
}
func RoleAuth(roles ...models.RoleType) web.Handler {
func RoleAuth(roles ...org.RoleType) web.Handler {
return func(c *models.ReqContext) {
ok := false
for _, role := range roles {
@ -136,11 +137,11 @@ func Auth(options *AuthOptions) web.Handler {
// are otherwise only available to admins.
func AdminOrEditorAndFeatureEnabled(enabled bool) web.Handler {
return func(c *models.ReqContext) {
if c.OrgRole == models.ROLE_ADMIN {
if c.OrgRole == org.RoleAdmin {
return
}
if c.OrgRole == models.ROLE_EDITOR && enabled {
if c.OrgRole == org.RoleEditor && enabled {
return
}
@ -194,7 +195,7 @@ func shouldForceLogin(c *models.ReqContext) bool {
func OrgAdminDashOrFolderAdminOrTeamAdmin(ss sqlstore.Store, ds dashboards.DashboardService) func(c *models.ReqContext) {
return func(c *models.ReqContext) {
if c.OrgRole == models.ROLE_ADMIN {
if c.OrgRole == org.RoleAdmin {
return
}

View File

@ -5,6 +5,7 @@ import (
"strings"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -16,8 +17,8 @@ var (
})
ReqSignedIn = Auth(&AuthOptions{ReqSignedIn: true})
ReqSignedInNoAnonymous = Auth(&AuthOptions{ReqSignedIn: true, ReqNoAnonynmous: true})
ReqEditorRole = RoleAuth(models.ROLE_EDITOR, models.ROLE_ADMIN)
ReqOrgAdmin = RoleAuth(models.ROLE_ADMIN)
ReqEditorRole = RoleAuth(org.RoleEditor, org.RoleAdmin)
ReqOrgAdmin = RoleAuth(org.RoleAdmin)
)
func HandleNoCacheHeader(ctx *models.ReqContext) {

View File

@ -5,10 +5,10 @@ import (
"testing"
"github.com/grafana/grafana/pkg/login"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/usertest"
"github.com/grafana/grafana/pkg/setting"
@ -30,7 +30,7 @@ func TestMiddlewareBasicAuth(t *testing.T) {
keyhash, err := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd")
require.NoError(t, err)
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: orgID, Role: models.ROLE_EDITOR, Key: keyhash}
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: orgID, Role: org.RoleEditor, Key: keyhash}
authHeader := util.GetBasicAuthHeader("api_key", "eyJrIjoidjVuQXdwTWFmRlA2em5hUzR1cmhkV0RMUzU1MTFNNDIiLCJuIjoiYXNkIiwiaWQiOjF9")
sc.fakeReq("GET", "/").withAuthorizationHeader(authHeader).exec()
@ -38,14 +38,14 @@ func TestMiddlewareBasicAuth(t *testing.T) {
assert.Equal(t, 200, sc.resp.Code)
assert.True(t, sc.context.IsSignedIn)
assert.Equal(t, orgID, sc.context.OrgId)
assert.Equal(t, models.ROLE_EDITOR, sc.context.OrgRole)
assert.Equal(t, org.RoleEditor, sc.context.OrgRole)
}, configure)
middlewareScenario(t, "Handle auth", func(t *testing.T, sc *scenarioContext) {
const password = "MyPass"
const orgID int64 = 2
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: id}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: id}
authHeader := util.GetBasicAuthHeader("myUser", password)
sc.fakeReq("GET", "/").withAuthorizationHeader(authHeader).exec()
@ -63,7 +63,7 @@ func TestMiddlewareBasicAuth(t *testing.T) {
require.NoError(t, err)
sc.mockSQLStore.ExpectedUser = &user.User{Password: encoded, ID: id, Salt: salt}
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: id}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{UserId: id}
login.ProvideService(sc.mockSQLStore, &logintest.LoginServiceFake{}, usertest.NewUserServiceFake())
authHeader := util.GetBasicAuthHeader("myUser", password)

View File

@ -46,7 +46,7 @@ func TestMiddlewareJWTAuth(t *testing.T) {
"foo-username": myUsername,
}, nil
}
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: id, OrgId: orgID, Login: myUsername}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{UserId: id, OrgId: orgID, Login: myUsername}
sc.fakeReq("GET", "/").withJWTAuthHeader(token).exec()
assert.Equal(t, verifiedToken, token)
@ -67,7 +67,7 @@ func TestMiddlewareJWTAuth(t *testing.T) {
"foo-email": myEmail,
}, nil
}
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: id, OrgId: orgID, Email: myEmail}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{UserId: id, OrgId: orgID, Email: myEmail}
sc.fakeReq("GET", "/").withJWTAuthHeader(token).exec()
assert.Equal(t, verifiedToken, token)
@ -108,7 +108,7 @@ func TestMiddlewareJWTAuth(t *testing.T) {
"foo-email": myEmail,
}, nil
}
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: id, OrgId: orgID, Email: myEmail}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{UserId: id, OrgId: orgID, Email: myEmail}
sc.fakeReq("GET", "/").withJWTAuthHeader(token).exec()
assert.Equal(t, verifiedToken, token)

View File

@ -27,6 +27,7 @@ import (
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
"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/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@ -153,7 +154,7 @@ func TestMiddlewareContext(t *testing.T) {
keyhash, err := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd")
require.NoError(t, err)
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: orgID, Role: models.ROLE_EDITOR, Key: keyhash}
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: orgID, Role: org.RoleEditor, Key: keyhash}
sc.fakeReq("GET", "/").withValidApiKey().exec()
@ -161,12 +162,12 @@ func TestMiddlewareContext(t *testing.T) {
assert.True(t, sc.context.IsSignedIn)
assert.Equal(t, orgID, sc.context.OrgId)
assert.Equal(t, models.ROLE_EDITOR, sc.context.OrgRole)
assert.Equal(t, org.RoleEditor, sc.context.OrgRole)
})
middlewareScenario(t, "Valid API key, but does not match DB hash", func(t *testing.T, sc *scenarioContext) {
const keyhash = "Something_not_matching"
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: 12, Role: models.ROLE_EDITOR, Key: keyhash}
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: 12, Role: org.RoleEditor, Key: keyhash}
sc.fakeReq("GET", "/").withValidApiKey().exec()
@ -181,7 +182,7 @@ func TestMiddlewareContext(t *testing.T) {
require.NoError(t, err)
expires := sc.contextHandler.GetTime().Add(-1 * time.Second).Unix()
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: 12, Role: models.ROLE_EDITOR, Key: keyhash, Expires: &expires}
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: 12, Role: org.RoleEditor, Key: keyhash, Expires: &expires}
sc.fakeReq("GET", "/").withValidApiKey().exec()
@ -194,7 +195,7 @@ func TestMiddlewareContext(t *testing.T) {
const userID int64 = 12
sc.withTokenSessionCookie("token")
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: 2, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: 2, UserId: userID}
sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) {
return &models.UserToken{
@ -218,7 +219,7 @@ func TestMiddlewareContext(t *testing.T) {
const userID int64 = 12
sc.withTokenSessionCookie("token")
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: 2, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: 2, UserId: userID}
sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) {
return &models.UserToken{
@ -316,18 +317,18 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "When anonymous access is enabled", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedOrg = &models.Org{Id: 1, Name: sc.cfg.AnonymousOrgName}
org, err := sc.mockSQLStore.CreateOrgWithMember(sc.cfg.AnonymousOrgName, 1)
orga, err := sc.mockSQLStore.CreateOrgWithMember(sc.cfg.AnonymousOrgName, 1)
require.NoError(t, err)
sc.fakeReq("GET", "/").exec()
assert.Equal(t, int64(0), sc.context.UserId)
assert.Equal(t, org.Id, sc.context.OrgId)
assert.Equal(t, models.ROLE_EDITOR, sc.context.OrgRole)
assert.Equal(t, orga.Id, sc.context.OrgId)
assert.Equal(t, org.RoleEditor, sc.context.OrgRole)
assert.False(t, sc.context.IsSignedIn)
}, func(cfg *setting.Cfg) {
cfg.AnonymousEnabled = true
cfg.AnonymousOrgName = "test"
cfg.AnonymousOrgRole = string(models.ROLE_EDITOR)
cfg.AnonymousOrgRole = string(org.RoleEditor)
})
t.Run("auth_proxy", func(t *testing.T) {
@ -349,7 +350,7 @@ func TestMiddlewareContext(t *testing.T) {
const group = "grafana-core-team"
middlewareScenario(t, "Should not sync the user if it's in the cache", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: userID}
h, err := authproxy.HashCacheKey(hdrName + "-" + group)
require.NoError(t, err)
@ -389,7 +390,7 @@ func TestMiddlewareContext(t *testing.T) {
})
middlewareScenario(t, "Should create an user from a header", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
@ -406,10 +407,10 @@ func TestMiddlewareContext(t *testing.T) {
})
middlewareScenario(t, "Should assign role from header to default org", func(t *testing.T, sc *scenarioContext) {
var storedRoleInfo map[int64]models.RoleType = nil
var storedRoleInfo map[int64]org.RoleType = nil
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *user.User {
storedRoleInfo = cmd.ExternalUser.OrgRoles
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: defaultOrgId, UserId: userID, OrgRole: storedRoleInfo[defaultOrgId]}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: defaultOrgId, UserId: userID, OrgRole: storedRoleInfo[defaultOrgId]}
return &user.User{ID: userID}
}
@ -429,10 +430,10 @@ func TestMiddlewareContext(t *testing.T) {
})
middlewareScenario(t, "Should NOT assign role from header to non-default org", func(t *testing.T, sc *scenarioContext) {
var storedRoleInfo map[int64]models.RoleType = nil
var storedRoleInfo map[int64]org.RoleType = nil
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *user.User {
storedRoleInfo = cmd.ExternalUser.OrgRoles
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID, OrgRole: storedRoleInfo[orgID]}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: userID, OrgRole: storedRoleInfo[orgID]}
return &user.User{ID: userID}
}
@ -456,7 +457,7 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should use organisation specified by targetOrgId parameter", func(t *testing.T, sc *scenarioContext) {
var targetOrgID int64 = 123
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: targetOrgID, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: targetOrgID, UserId: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", fmt.Sprintf("/?targetOrgId=%d", targetOrgID))
@ -530,7 +531,7 @@ func TestMiddlewareContext(t *testing.T) {
const userID int64 = 12
const orgID int64 = 2
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
@ -546,7 +547,7 @@ func TestMiddlewareContext(t *testing.T) {
})
middlewareScenario(t, "Should allow the request from whitelist IP", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@ -45,7 +46,7 @@ func TestOrgRedirectMiddleware(t *testing.T) {
for _, tc := range testCases {
middlewareScenario(t, tc.desc, func(t *testing.T, sc *scenarioContext) {
sc.withTokenSessionCookie("token")
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: 1, UserId: 12}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: 1, UserId: 12}
sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) {
return &models.UserToken{
UserId: 0,
@ -64,7 +65,7 @@ func TestOrgRedirectMiddleware(t *testing.T) {
middlewareScenario(t, "when setting an invalid org for user", func(t *testing.T, sc *scenarioContext) {
sc.withTokenSessionCookie("token")
sc.mockSQLStore.ExpectedSetUsingOrgError = fmt.Errorf("")
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: 1, UserId: 12}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{OrgId: 1, UserId: 12}
sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) {
return &models.UserToken{

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -60,7 +61,7 @@ func TestMiddlewareQuota(t *testing.T) {
const quotaUsed = 4
setUp := func(sc *scenarioContext) {
sc.withTokenSessionCookie("token")
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: 12}
sc.mockSQLStore.ExpectedSignedInUser = &user.SignedInUser{UserId: 12}
sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) {
return &models.UserToken{
UserId: 12,

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/user"
)
type AlertStateType string
@ -159,7 +160,7 @@ type GetAlertsQuery struct {
PanelId int64
Limit int64
Query string
User *SignedInUser
User *user.SignedInUser
Result []*AlertListItemDTO
}

View File

@ -5,6 +5,8 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"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"
"github.com/prometheus/client_golang/prometheus"
@ -12,7 +14,7 @@ import (
type ReqContext struct {
*web.Context
*SignedInUser
*user.SignedInUser
UserToken *UserToken
IsSignedIn bool
@ -77,11 +79,11 @@ func (ctx *ReqContext) JsonApiErr(status int, message string, err error) {
ctx.JSON(status, resp)
}
func (ctx *ReqContext) HasUserRole(role RoleType) bool {
func (ctx *ReqContext) HasUserRole(role org.RoleType) bool {
return ctx.OrgRole.Includes(role)
}
func (ctx *ReqContext) HasHelpFlag(flag HelpFlags1) bool {
func (ctx *ReqContext) HasHelpFlag(flag user.HelpFlags1) bool {
return ctx.HelpFlags1.HasFlag(flag)
}

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/org"
)
type PermissionType int
@ -39,9 +41,9 @@ type DashboardACL struct {
OrgID int64 `xorm:"org_id"`
DashboardID int64 `xorm:"dashboard_id"`
UserID int64 `xorm:"user_id"`
TeamID int64 `xorm:"team_id"`
Role *RoleType // pointer to be nullable
UserID int64 `xorm:"user_id"`
TeamID int64 `xorm:"team_id"`
Role *org.RoleType // pointer to be nullable
Permission PermissionType
Created time.Time
@ -64,7 +66,7 @@ type DashboardACLInfoDTO struct {
TeamEmail string `json:"teamEmail"`
TeamAvatarUrl string `json:"teamAvatarUrl"`
Team string `json:"team"`
Role *RoleType `json:"role,omitempty"`
Role *org.RoleType `json:"role,omitempty"`
Permission PermissionType `json:"permission"`
PermissionName string `json:"permissionName"`
Uid string `json:"uid"`

View File

@ -3,6 +3,8 @@ package models
import (
"strings"
"time"
"github.com/grafana/grafana/pkg/services/user"
)
type Folder struct {
@ -91,11 +93,11 @@ type UpdateFolderCommand struct {
//
type HasEditPermissionInFoldersQuery struct {
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
Result bool
}
type HasAdminPermissionInDashboardsOrFoldersQuery struct {
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
Result bool
}

View File

@ -1,16 +1,8 @@
package models
type HelpFlags1 uint64
const (
HelpFlagGettingStartedPanelDismissed HelpFlags1 = 1 << iota
HelpFlagDashboardHelp1
)
func (f HelpFlags1) HasFlag(flag HelpFlags1) bool { return f&flag != 0 }
func (f *HelpFlags1) AddFlag(flag HelpFlags1) { *f |= flag }
import "github.com/grafana/grafana/pkg/services/user"
type SetUserHelpFlagCommand struct {
HelpFlags1 HelpFlags1
HelpFlags1 user.HelpFlags1
UserId int64
}

View File

@ -6,6 +6,7 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/services/user"
)
// ChannelPublisher writes data into a channel. Note that permissions are not checked.
@ -52,10 +53,10 @@ type PublishReply struct {
// ChannelHandler defines the core channel behavior
type ChannelHandler interface {
// OnSubscribe is called when a client wants to subscribe to a channel
OnSubscribe(ctx context.Context, user *SignedInUser, e SubscribeEvent) (SubscribeReply, backend.SubscribeStreamStatus, error)
OnSubscribe(ctx context.Context, user *user.SignedInUser, e SubscribeEvent) (SubscribeReply, backend.SubscribeStreamStatus, error)
// OnPublish is called when a client writes a message to the channel websocket.
OnPublish(ctx context.Context, user *SignedInUser, e PublishEvent) (PublishReply, backend.PublishStreamStatus, error)
OnPublish(ctx context.Context, user *user.SignedInUser, e PublishEvent) (PublishReply, backend.PublishStreamStatus, error)
}
// ChannelHandlerFactory should be implemented by all core features.
@ -71,10 +72,10 @@ type DashboardActivityChannel interface {
// gitops workflow that knows if the value was saved to the local database or not
// in many cases all direct save requests will fail, but the request should be forwarded
// to any gitops observers
DashboardSaved(orgID int64, user *UserDisplayDTO, message string, dashboard *Dashboard, err error) error
DashboardSaved(orgID int64, user *user.UserDisplayDTO, message string, dashboard *Dashboard, err error) error
// Called when a dashboard is deleted
DashboardDeleted(orgID int64, user *UserDisplayDTO, uid string) error
DashboardDeleted(orgID int64, user *user.UserDisplayDTO, uid string) error
// Experimental! Indicate is GitOps is active. This really means
// someone is subscribed to the `grafana/dashboards/gitops` channel

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/org"
)
// Typed errors
@ -84,7 +86,7 @@ type OrgDetailsDTO struct {
}
type UserOrgDTO struct {
OrgId int64 `json:"orgId"`
Name string `json:"name"`
Role RoleType `json:"role"`
OrgId int64 `json:"orgId"`
Name string `json:"name"`
Role org.RoleType `json:"role"`
}

View File

@ -2,9 +2,10 @@ package models
import (
"errors"
"fmt"
"strings"
"time"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
// Typed errors
@ -14,74 +15,11 @@ var (
ErrOrgUserAlreadyAdded = errors.New("user is already added to organization")
)
// swagger:enum RoleType
type RoleType string
const (
ROLE_VIEWER RoleType = "Viewer"
ROLE_EDITOR RoleType = "Editor"
ROLE_ADMIN RoleType = "Admin"
)
func (r RoleType) IsValid() bool {
return r == ROLE_VIEWER || r == ROLE_ADMIN || r == ROLE_EDITOR
}
func (r RoleType) Includes(other RoleType) bool {
if r == ROLE_ADMIN {
return true
}
if r == ROLE_EDITOR {
return other != ROLE_ADMIN
}
return r == other
}
func (r RoleType) Children() []RoleType {
switch r {
case ROLE_ADMIN:
return []RoleType{ROLE_EDITOR, ROLE_VIEWER}
case ROLE_EDITOR:
return []RoleType{ROLE_VIEWER}
default:
return nil
}
}
func (r RoleType) Parents() []RoleType {
switch r {
case ROLE_EDITOR:
return []RoleType{ROLE_ADMIN}
case ROLE_VIEWER:
return []RoleType{ROLE_EDITOR, ROLE_ADMIN}
default:
return nil
}
}
func (r *RoleType) UnmarshalText(data []byte) error {
// make sure "viewer" and "Viewer" are both correct
str := strings.Title(string(data))
*r = RoleType(str)
if !r.IsValid() {
if (*r) != "" {
return fmt.Errorf("invalid role value: %s", *r)
}
*r = ROLE_VIEWER
}
return nil
}
type OrgUser struct {
Id int64
OrgId int64
UserId int64
Role RoleType
Role org.RoleType
Created time.Time
Updated time.Time
}
@ -97,8 +35,8 @@ type RemoveOrgUserCommand struct {
}
type AddOrgUserCommand struct {
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
Role RoleType `json:"role" binding:"Required"`
LoginOrEmail string `json:"loginOrEmail" binding:"Required"`
Role org.RoleType `json:"role" binding:"Required"`
OrgId int64 `json:"-"`
UserId int64 `json:"-"`
@ -108,7 +46,7 @@ type AddOrgUserCommand struct {
}
type UpdateOrgUserCommand struct {
Role RoleType `json:"role" binding:"Required"`
Role org.RoleType `json:"role" binding:"Required"`
OrgId int64 `json:"-"`
UserId int64 `json:"-"`
@ -125,7 +63,7 @@ type GetOrgUsersQuery struct {
// Flag used to allow oss edition to query users without access control
DontEnforceAccessControl bool
User *SignedInUser
User *user.SignedInUser
Result []*OrgUserDTO
}
@ -135,7 +73,7 @@ type SearchOrgUsersQuery struct {
Page int
Limit int
User *SignedInUser
User *user.SignedInUser
Result SearchOrgUsersQueryResult
}

View File

@ -4,6 +4,7 @@ import (
"strings"
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/services/user"
)
type SortOption struct {
@ -22,7 +23,7 @@ type SortOptionFilter interface {
type FindPersistedDashboardsQuery struct {
Title string
OrgId int64
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
IsStarred bool
DashboardIds []int64
DashboardUIDs []string

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/user"
)
// Typed errors
@ -52,7 +54,7 @@ type DeleteTeamCommand struct {
type GetTeamByIdQuery struct {
OrgId int64
Id int64
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
HiddenUsers map[string]struct{}
Result *TeamDTO
UserIdFilter int64
@ -65,7 +67,7 @@ type GetTeamsByUserQuery struct {
OrgId int64
UserId int64 `json:"userId"`
Result []*TeamDTO `json:"teams"`
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
}
type SearchTeamsQuery struct {
@ -75,7 +77,7 @@ type SearchTeamsQuery struct {
Page int
OrgId int64
UserIdFilter int64
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
HiddenUsers map[string]struct{}
Result SearchTeamQueryResult
@ -100,6 +102,6 @@ type SearchTeamQueryResult struct {
}
type IsAdminOfTeamsQuery struct {
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
Result bool
}

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/user"
)
// Typed errors
@ -55,7 +57,7 @@ type GetTeamMembersQuery struct {
TeamId int64
UserId int64
External bool
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
Result []*TeamMemberDTO
}

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/org"
)
// Typed errors
@ -27,7 +29,7 @@ type TempUser struct {
Version int
Email string
Name string
Role RoleType
Role org.RoleType
InvitedByUserId int64
Status TempUserStatus
@ -50,7 +52,7 @@ type CreateTempUserCommand struct {
InvitedByUserId int64
Status TempUserStatus
Code string
Role RoleType
Role org.RoleType
RemoteAddr string
Result *TempUser
@ -90,7 +92,7 @@ type TempUserDTO struct {
OrgId int64 `json:"orgId"`
Name string `json:"name"`
Email string `json:"email"`
Role RoleType `json:"role"`
Role org.RoleType `json:"role"`
InvitedByLogin string `json:"invitedByLogin"`
InvitedByEmail string `json:"invitedByEmail"`
InvitedByName string `json:"invitedByName"`

View File

@ -70,7 +70,7 @@ type GetSignedInUserQuery struct {
Login string
Email string
OrgId int64
Result *SignedInUser
Result *user.SignedInUser
}
type GetUserProfileQuery struct {
@ -79,7 +79,7 @@ type GetUserProfileQuery struct {
}
type SearchUsersQuery struct {
SignedInUser *SignedInUser
SignedInUser *user.SignedInUser
OrgId int64
Query string
Page int
@ -104,69 +104,10 @@ type GetUserOrgListQuery struct {
Result []*UserOrgDTO
}
// ------------------------
// DTO & Projections
type SignedInUser struct {
UserId int64
OrgId int64
OrgName string
OrgRole RoleType
ExternalAuthModule string
ExternalAuthId string
Login string
Name string
Email string
ApiKeyId int64
OrgCount int
IsGrafanaAdmin bool
IsAnonymous bool
IsDisabled bool
HelpFlags1 HelpFlags1
LastSeenAt time.Time
Teams []int64
// Permissions grouped by orgID and actions
Permissions map[int64]map[string][]string `json:"-"`
}
func (u *SignedInUser) ShouldUpdateLastSeenAt() bool {
return u.UserId > 0 && time.Since(u.LastSeenAt) > time.Minute*5
}
func (u *SignedInUser) NameOrFallback() string {
if u.Name != "" {
return u.Name
}
if u.Login != "" {
return u.Login
}
return u.Email
}
func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO {
return &UserDisplayDTO{
Id: u.UserId,
Login: u.Login,
Name: u.Name,
}
}
type UpdateUserLastSeenAtCommand struct {
UserId int64
}
func (u *SignedInUser) HasRole(role RoleType) bool {
if u.IsGrafanaAdmin {
return true
}
return u.OrgRole.Includes(role)
}
func (u *SignedInUser) IsRealUser() bool {
return u.UserId != 0
}
type UserProfileDTO struct {
Id int64 `json:"id"`
Email string `json:"email"`
@ -198,13 +139,6 @@ type UserSearchHitDTO struct {
AuthModule AuthModuleConversion `json:"-"`
}
type UserDisplayDTO struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Login string `json:"login,omitempty"`
AvatarUrl string `json:"avatarUrl"`
}
type UserIdDTO struct {
Id int64 `json:"id"`
Message string `json:"message"`

View File

@ -3,6 +3,7 @@ package models
import (
"time"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -31,7 +32,7 @@ type ExternalUserInfo struct {
Login string
Name string
Groups []string
OrgRoles map[int64]RoleType
OrgRoles map[int64]org.RoleType
IsGrafanaAdmin *bool // This is a pointer to know if we should sync this or not (nil = ignore sync)
IsDisabled bool
}

View File

@ -1,8 +1,8 @@
package plugins
import (
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
)
const (
@ -24,7 +24,7 @@ func DeclareRBACRoles(acService ac.AccessControl) error {
{Action: ActionAppAccess, Scope: ScopeProvider.GetResourceAllScope()},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
return acService.DeclareFixedRoles(AppPluginsReader)
}

View File

@ -7,8 +7,8 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/user"
)
// ModelToInstanceSettings converts a datasources.DataSource to a backend.DataSourceInstanceSettings.
@ -45,7 +45,7 @@ func ModelToInstanceSettings(ds *datasources.DataSource, decryptFn func(ds *data
// BackendUserFromSignedInUser converts Grafana's SignedInUser model
// to the backend plugin's model.
func BackendUserFromSignedInUser(su *models.SignedInUser) *backend.User {
func BackendUserFromSignedInUser(su *user.SignedInUser) *backend.User {
if su == nil {
return nil
}

View File

@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@ -225,7 +226,7 @@ func (l *Loader) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error)
for _, include := range plugin.Includes {
if include.Role == "" {
include.Role = models.ROLE_VIEWER
include.Role = org.RoleViewer
}
}

View File

@ -8,13 +8,13 @@ import (
"testing"
"github.com/grafana/grafana/pkg/infra/log/logtest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
@ -1064,10 +1064,10 @@ func TestLoader_readPluginJSON(t *testing.T) {
},
},
Includes: []*plugins.Includes{
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: models.ROLE_VIEWER},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: models.ROLE_VIEWER},
{Name: "Nginx Panel", Type: "panel", Role: models.ROLE_VIEWER},
{Name: "Nginx Datasource", Type: "datasource", Role: models.ROLE_VIEWER},
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: org.RoleViewer},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer},
{Name: "Nginx Panel", Type: "panel", Role: org.RoleViewer},
{Name: "Nginx Datasource", Type: "datasource", Role: org.RoleViewer},
},
Backend: false,
},

View File

@ -4,7 +4,7 @@ import (
"errors"
"fmt"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
)
const (
@ -83,16 +83,16 @@ type Dependencies struct {
}
type Includes struct {
Name string `json:"name"`
Path string `json:"path"`
Type string `json:"type"`
Component string `json:"component"`
Role models.RoleType `json:"role"`
AddToNav bool `json:"addToNav"`
DefaultNav bool `json:"defaultNav"`
Slug string `json:"slug"`
Icon string `json:"icon"`
UID string `json:"uid"`
Name string `json:"name"`
Path string `json:"path"`
Type string `json:"type"`
Component string `json:"component"`
Role org.RoleType `json:"role"`
AddToNav bool `json:"addToNav"`
DefaultNav bool `json:"defaultNav"`
Slug string `json:"slug"`
Icon string `json:"icon"`
UID string `json:"uid"`
ID string `json:"-"`
}

View File

@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/adapters"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/pluginsettings"
"github.com/grafana/grafana/pkg/services/user"
)
func ProvideService(cacheService *localcache.CacheService, pluginStore plugins.Store,
@ -43,13 +44,13 @@ type Provider struct {
// Get allows getting plugin context by its ID. If datasourceUID is not empty string
// then PluginContext.DataSourceInstanceSettings will be resolved and appended to
// returned context.
func (p *Provider) Get(ctx context.Context, pluginID string, user *models.SignedInUser) (backend.PluginContext, bool, error) {
func (p *Provider) Get(ctx context.Context, pluginID string, user *user.SignedInUser) (backend.PluginContext, bool, error) {
return p.pluginContext(ctx, pluginID, user)
}
// GetWithDataSource allows getting plugin context by its ID and PluginContext.DataSourceInstanceSettings will be
// resolved and appended to the returned context.
func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *models.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, bool, error) {
func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *user.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, bool, error) {
pCtx, exists, err := p.pluginContext(ctx, pluginID, user)
if err != nil {
return pCtx, exists, err
@ -67,7 +68,7 @@ func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user
const pluginSettingsCacheTTL = 5 * time.Second
const pluginSettingsCachePrefix = "plugin-setting-"
func (p *Provider) pluginContext(ctx context.Context, pluginID string, user *models.SignedInUser) (backend.PluginContext, bool, error) {
func (p *Provider) pluginContext(ctx context.Context, pluginID string, user *user.SignedInUser) (backend.PluginContext, bool, error) {
plugin, exists := p.pluginStore.Plugin(ctx, pluginID)
if !exists {
return backend.PluginContext{}, false, nil
@ -105,7 +106,7 @@ func (p *Provider) pluginContext(ctx context.Context, pluginID string, user *mod
}, true, nil
}
func (p *Provider) getCachedPluginSettings(ctx context.Context, pluginID string, user *models.SignedInUser) (*pluginsettings.DTO, error) {
func (p *Provider) getCachedPluginSettings(ctx context.Context, pluginID string, user *user.SignedInUser) (*pluginsettings.DTO, error) {
cacheKey := pluginSettingsCachePrefix + pluginID
if cached, found := p.cacheService.Get(cacheKey); found {

View File

@ -7,10 +7,10 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
"github.com/grafana/grafana/pkg/plugins/backendplugin/secretsmanagerplugin"
"github.com/grafana/grafana/pkg/services/org"
)
type Plugin struct {
@ -158,7 +158,7 @@ func (d JSONData) DashboardIncludes() []*Includes {
type Route struct {
Path string `json:"path"`
Method string `json:"method"`
ReqRole models.RoleType `json:"reqRole"`
ReqRole org.RoleType `json:"reqRole"`
URL string `json:"url"`
URLParams []URLParam `json:"urlParams"`
Headers []Header `json:"headers"`

View File

@ -7,6 +7,8 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -18,10 +20,10 @@ type AccessControl interface {
registry.ProvidesUsageStats
// Evaluate evaluates access to the given resources.
Evaluate(ctx context.Context, user *models.SignedInUser, evaluator Evaluator) (bool, error)
Evaluate(ctx context.Context, user *user.SignedInUser, evaluator Evaluator) (bool, error)
// GetUserPermissions returns user permissions with only action and scope fields set.
GetUserPermissions(ctx context.Context, user *models.SignedInUser, options Options) ([]Permission, error)
GetUserPermissions(ctx context.Context, user *user.SignedInUser, options Options) ([]Permission, error)
//IsDisabled returns if access control is enabled or not
IsDisabled() bool
@ -49,7 +51,7 @@ type PermissionsStore interface {
}
type TeamPermissionsService interface {
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]ResourcePermission, error)
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
}
@ -71,7 +73,7 @@ type ServiceAccountPermissionsService interface {
type PermissionsService interface {
// GetPermissions returns all permissions for given resourceID
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]ResourcePermission, error)
// SetUserPermission sets permission on resource for a user
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
// SetTeamPermission sets permission on resource for a team
@ -138,17 +140,17 @@ var ReqGrafanaAdmin = func(c *models.ReqContext) bool {
return c.IsGrafanaAdmin
}
// ReqViewer returns true if the current user has models.ROLE_VIEWER. Note: this can be anonymous user as well
// ReqViewer returns true if the current user has org.RoleViewer. Note: this can be anonymous user as well
var ReqViewer = func(c *models.ReqContext) bool {
return c.OrgRole.Includes(models.ROLE_VIEWER)
return c.OrgRole.Includes(org.RoleViewer)
}
var ReqOrgAdmin = func(c *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN
return c.OrgRole == org.RoleAdmin
}
var ReqOrgAdminOrEditor = func(c *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR
return c.OrgRole == org.RoleAdmin || c.OrgRole == org.RoleEditor
}
func BuildPermissionsMap(permissions []Permission) map[string]bool {
@ -268,7 +270,7 @@ func IsDisabled(cfg *setting.Cfg) bool {
}
// GetOrgRoles returns legacy org roles for a user
func GetOrgRoles(cfg *setting.Cfg, user *models.SignedInUser) []string {
func GetOrgRoles(cfg *setting.Cfg, user *user.SignedInUser) []string {
roles := []string{string(user.OrgRole)}
// With built-in role simplifying, inheritance is performed upon role registration.

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
@ -120,7 +121,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
}
var roles []string
role := models.RoleType(tt.role)
role := org.RoleType(tt.role)
if role.IsValid() {
roles = append(roles, string(role))

View File

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
@ -118,7 +119,7 @@ func (s *AccessControlStore) SetBuiltInResourcePermission(
cmd types.SetResourcePermissionCommand,
hook types.BuiltinResourceHookFunc,
) (*accesscontrol.ResourcePermission, error) {
if !models.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
if !org.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
return nil, fmt.Errorf("invalid role: %s", builtInRole)
}
@ -171,7 +172,7 @@ func (s *AccessControlStore) SetResourcePermissions(
p, err = s.setUserResourcePermission(sess, orgID, cmd.User, cmd.SetResourcePermissionCommand, hooks.User)
} else if cmd.TeamID != 0 {
p, err = s.setTeamResourcePermission(sess, orgID, cmd.TeamID, cmd.SetResourcePermissionCommand, hooks.Team)
} else if models.RoleType(cmd.BuiltinRole).IsValid() || cmd.BuiltinRole == accesscontrol.RoleGrafanaAdmin {
} else if org.RoleType(cmd.BuiltinRole).IsValid() || cmd.BuiltinRole == accesscontrol.RoleGrafanaAdmin {
p, err = s.setBuiltInResourcePermission(sess, orgID, cmd.BuiltinRole, cmd.SetResourcePermissionCommand, hooks.BuiltInRole)
}
if err != nil {

View File

@ -10,7 +10,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/datasources"
@ -58,7 +57,7 @@ func getDSPermissions(b *testing.B, store *AccessControlStore, dataSources []int
dsId := dataSources[0]
permissions, err := store.GetResourcePermissions(context.Background(), accesscontrol.GlobalOrgID, types.GetResourcePermissionsQuery{
User: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
User: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
Actions: []string{dsAction},
Resource: dsResource,
ResourceID: strconv.Itoa(int(dsId)),

View File

@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/sqlstore"
@ -338,7 +337,7 @@ func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
type getResourcePermissionsTest struct {
desc string
user *models.SignedInUser
user *user.SignedInUser
numUsers int
actions []string
resource string
@ -351,7 +350,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
tests := []getResourcePermissionsTest{
{
desc: "should return permissions for resource id",
user: &models.SignedInUser{
user: &user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},
@ -364,7 +363,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
},
{
desc: "should return manage permissions for all resource ids",
user: &models.SignedInUser{
user: &user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},

View File

@ -5,7 +5,7 @@ import (
"strconv"
"strings"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
var sqlIDAcceptList = map[string]struct{}{
@ -33,7 +33,7 @@ type SQLFilter struct {
// Filter creates a where clause to restrict the view of a query based on a users permissions
// Scopes that exists for all actions will be parsed and compared against the supplied sqlID
// Prefix parameter is the prefix of the scope that we support (e.g. "users:id:")
func Filter(user *models.SignedInUser, sqlID, prefix string, actions ...string) (SQLFilter, error) {
func Filter(user *user.SignedInUser, sqlID, prefix string, actions ...string) (SQLFilter, error) {
if _, ok := sqlIDAcceptList[sqlID]; !ok {
return denyQuery, errors.New("sqlID is not in the accept list")
}

View File

@ -8,10 +8,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
func BenchmarkFilter10_10(b *testing.B) { benchmarkFilter(b, 10, 10) }
@ -33,7 +33,7 @@ func benchmarkFilter(b *testing.B, numDs, numPermissions int) {
for i := 0; i < b.N; i++ {
baseSql := `SELECT data_source.* FROM data_source WHERE`
acFilter, err := accesscontrol.Filter(
&models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(permissions)}},
&user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(permissions)}},
"data_source.id",
"datasources:id:",
"datasources:read",

View File

@ -8,10 +8,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type filterDatasourcesTestCase struct {
@ -177,7 +177,7 @@ func TestFilter_Datasources(t *testing.T) {
baseSql := `SELECT data_source.* FROM data_source WHERE`
acFilter, err := accesscontrol.Filter(
&models.SignedInUser{
&user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{1: tt.permissions},
},

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -25,7 +26,7 @@ func Middleware(ac AccessControl) func(web.Handler, Evaluator) web.Handler {
}
}
func authorize(c *models.ReqContext, ac AccessControl, user *models.SignedInUser, evaluator Evaluator) {
func authorize(c *models.ReqContext, ac AccessControl, user *user.SignedInUser, evaluator Evaluator) {
injected, err := evaluator.MutateScopes(c.Req.Context(), ScopeInjector(ScopeParams{
OrgID: c.OrgId,
URLParams: web.Params(c.Req),

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web"
)
@ -87,7 +88,7 @@ func contextProvider() web.Handler {
reqCtx := &models.ReqContext{
Context: c,
Logger: log.New(""),
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
IsSignedIn: true,
SkipCache: true,
}

View File

@ -3,13 +3,13 @@ package mock
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type fullAccessControl interface {
accesscontrol.AccessControl
GetUserBuiltInRoles(user *models.SignedInUser) []string
GetUserBuiltInRoles(user *user.SignedInUser) []string
RegisterFixedRoles(context.Context) error
}
@ -36,11 +36,11 @@ type Mock struct {
Calls Calls
// Override functions
EvaluateFunc func(context.Context, *models.SignedInUser, accesscontrol.Evaluator) (bool, error)
GetUserPermissionsFunc func(context.Context, *models.SignedInUser, accesscontrol.Options) ([]accesscontrol.Permission, error)
EvaluateFunc func(context.Context, *user.SignedInUser, accesscontrol.Evaluator) (bool, error)
GetUserPermissionsFunc func(context.Context, *user.SignedInUser, accesscontrol.Options) ([]accesscontrol.Permission, error)
IsDisabledFunc func() bool
DeclareFixedRolesFunc func(...accesscontrol.RoleRegistration) error
GetUserBuiltInRolesFunc func(user *models.SignedInUser) []string
GetUserBuiltInRolesFunc func(user *user.SignedInUser) []string
RegisterFixedRolesFunc func() error
RegisterScopeAttributeResolverFunc func(string, accesscontrol.ScopeAttributeResolver)
DeleteUserPermissionsFunc func(context.Context, int64) error
@ -84,7 +84,7 @@ func (m Mock) WithBuiltInRoles(builtInRoles []string) *Mock {
// Evaluate evaluates access to the given resource.
// This mock uses GetUserPermissions to then call the evaluator Evaluate function.
func (m *Mock) Evaluate(ctx context.Context, user *models.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
func (m *Mock) Evaluate(ctx context.Context, user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
m.Calls.Evaluate = append(m.Calls.Evaluate, []interface{}{ctx, user, evaluator})
// Use override if provided
if m.EvaluateFunc != nil {
@ -114,7 +114,7 @@ func (m *Mock) Evaluate(ctx context.Context, user *models.SignedInUser, evaluato
// GetUserPermissions returns user permissions.
// This mock return m.permissions unless an override is provided.
func (m *Mock) GetUserPermissions(ctx context.Context, user *models.SignedInUser, opts accesscontrol.Options) ([]accesscontrol.Permission, error) {
func (m *Mock) GetUserPermissions(ctx context.Context, user *user.SignedInUser, opts accesscontrol.Options) ([]accesscontrol.Permission, error) {
m.Calls.GetUserPermissions = append(m.Calls.GetUserPermissions, []interface{}{ctx, user, opts})
// Use override if provided
if m.GetUserPermissionsFunc != nil {
@ -151,7 +151,7 @@ func (m *Mock) DeclareFixedRoles(registrations ...accesscontrol.RoleRegistration
// GetUserBuiltInRoles returns the list of organizational roles ("Viewer", "Editor", "Admin")
// or "Grafana Admin" associated to a user
// This mock returns m.builtInRoles unless an override is provided.
func (m *Mock) GetUserBuiltInRoles(user *models.SignedInUser) []string {
func (m *Mock) GetUserBuiltInRoles(user *user.SignedInUser) []string {
m.Calls.GetUserBuiltInRoles = append(m.Calls.GetUserBuiltInRoles, []interface{}{user})
// Use override if provided

View File

@ -5,8 +5,8 @@ import (
"github.com/stretchr/testify/mock"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
var _ accesscontrol.PermissionsService = new(MockPermissionsService)
@ -19,7 +19,7 @@ type MockPermissionsService struct {
mock.Mock
}
func (m *MockPermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (m *MockPermissionsService) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
mockedArgs := m.Called(ctx, user, resourceID)
return mockedArgs.Get(0).([]accesscontrol.ResourcePermission), mockedArgs.Error(1)
}

View File

@ -6,8 +6,8 @@ import (
"strings"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/org"
)
// RoleRegistration stores a role and its assignments to built-in roles
@ -410,7 +410,7 @@ func BuiltInRolesWithParents(builtInRoles []string) map[string]struct{} {
for _, br := range builtInRoles {
res[br] = struct{}{}
if br != RoleGrafanaAdmin {
for _, parent := range models.RoleType(br).Parents() {
for _, parent := range org.RoleType(br).Parents() {
res[string(parent)] = struct{}{}
}
}

View File

@ -6,10 +6,10 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/api"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus"
)
@ -77,7 +77,7 @@ func (ac *OSSAccessControlService) getUsageMetrics() interface{} {
}
// Evaluate evaluates access to the given resources
func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
timer := prometheus.NewTimer(metrics.MAccessEvaluationsSummary)
defer timer.ObserveDuration()
metrics.MAccessEvaluationCount.Inc()
@ -103,7 +103,7 @@ func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.Si
}
// GetUserPermissions returns user permissions based on built-in roles
func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
timer := prometheus.NewTimer(metrics.MAccessPermissionsSummary)
defer timer.ObserveDuration()
@ -132,7 +132,7 @@ func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user
return permissions, nil
}
func (ac *OSSAccessControlService) getFixedPermissions(ctx context.Context, user *models.SignedInUser) []accesscontrol.Permission {
func (ac *OSSAccessControlService) getFixedPermissions(ctx context.Context, user *user.SignedInUser) []accesscontrol.Permission {
permissions := make([]accesscontrol.Permission, 0)
for _, builtin := range accesscontrol.GetOrgRoles(ac.cfg, user) {

View File

@ -13,7 +13,9 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/database"
"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/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -52,7 +54,7 @@ type evaluatingPermissionsTestCase struct {
type userTestCase struct {
name string
orgRole models.RoleType
orgRole org.RoleType
isGrafanaAdmin bool
}
@ -66,7 +68,7 @@ func TestEvaluatingPermissions(t *testing.T) {
desc: "should successfully evaluate access to the endpoint",
user: userTestCase{
name: "testuser",
orgRole: models.ROLE_VIEWER,
orgRole: org.RoleViewer,
isGrafanaAdmin: true,
},
endpoints: []endpointTestCase{
@ -79,7 +81,7 @@ func TestEvaluatingPermissions(t *testing.T) {
desc: "should restrict access to the unauthorized endpoints",
user: userTestCase{
name: "testuser",
orgRole: models.ROLE_VIEWER,
orgRole: org.RoleViewer,
isGrafanaAdmin: false,
},
endpoints: []endpointTestCase{
@ -99,7 +101,7 @@ func TestEvaluatingPermissions(t *testing.T) {
errRegisterRoles := ac.RegisterFixedRoles(context.Background())
require.NoError(t, errRegisterRoles)
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: 1,
OrgId: 1,
Name: tc.user.name,
@ -357,11 +359,11 @@ func TestOSSAccessControlService_RegisterFixedRoles(t *testing.T) {
}
func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
testUser := models.SignedInUser{
testUser := user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",
@ -377,7 +379,7 @@ func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
}
tests := []struct {
name string
user models.SignedInUser
user user.SignedInUser
rawPerm accesscontrol.Permission
wantPerm accesscontrol.Permission
wantErr bool
@ -419,11 +421,11 @@ func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
}
func TestOSSAccessControlService_Evaluate(t *testing.T) {
testUser := models.SignedInUser{
testUser := user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",
@ -446,7 +448,7 @@ func TestOSSAccessControlService_Evaluate(t *testing.T) {
tests := []struct {
name string
user models.SignedInUser
user user.SignedInUser
rawPerm accesscontrol.Permission
evaluator accesscontrol.Evaluator
wantAccess bool

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -235,7 +236,7 @@ var _ accesscontrol.DatasourcePermissionsService = new(DatasourcePermissionsServ
type DatasourcePermissionsService struct{}
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}

View File

@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
const (
@ -60,7 +60,7 @@ func (s *ScopeResolvers) GetScopeAttributeMutator(orgID int64) ScopeAttributeMut
}
}
func (s *ScopeResolvers) GetScopeKeywordMutator(user *models.SignedInUser) ScopeKeywordMutator {
func (s *ScopeResolvers) GetScopeKeywordMutator(user *user.SignedInUser) ScopeKeywordMutator {
return func(ctx context.Context, scope string) (string, error) {
if resolver, ok := s.keywordResolvers[scope]; ok {
scopes, err := resolver.Resolve(ctx, user)
@ -103,13 +103,13 @@ type ScopeAttributeMutator func(context.Context, string) ([]string, error)
// ScopeKeywordResolver is used to resolve keywords in scopes e.g. "users:self" -> "user:id:1".
// These type of resolvers is used when fetching stored permissions
type ScopeKeywordResolver interface {
Resolve(ctx context.Context, user *models.SignedInUser) (string, error)
Resolve(ctx context.Context, user *user.SignedInUser) (string, error)
}
// ScopeKeywordResolverFunc is an adapter to allow functions to implement ScopeKeywordResolver interface
type ScopeKeywordResolverFunc func(ctx context.Context, user *models.SignedInUser) (string, error)
type ScopeKeywordResolverFunc func(ctx context.Context, user *user.SignedInUser) (string, error)
func (f ScopeKeywordResolverFunc) Resolve(ctx context.Context, user *models.SignedInUser) (string, error) {
func (f ScopeKeywordResolverFunc) Resolve(ctx context.Context, user *user.SignedInUser) (string, error) {
return f(ctx, user)
}
@ -135,6 +135,6 @@ func ScopeInjector(params ScopeParams) ScopeAttributeMutator {
}
}
var userSelfResolver = ScopeKeywordResolverFunc(func(ctx context.Context, user *models.SignedInUser) (string, error) {
var userSelfResolver = ScopeKeywordResolverFunc(func(ctx context.Context, user *user.SignedInUser) (string, error) {
return Scope("users", "id", fmt.Sprintf("%v", user.UserId)), nil
})

View File

@ -6,15 +6,16 @@ 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/datasources"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
func TestResolveKeywordScope(t *testing.T) {
tests := []struct {
name string
user *models.SignedInUser
user *user.SignedInUser
permission accesscontrol.Permission
want accesscontrol.Permission
wantErr bool
@ -50,11 +51,11 @@ func TestResolveKeywordScope(t *testing.T) {
}
}
var testUser = &models.SignedInUser{
var testUser = &user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"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/web"
)
@ -97,7 +98,7 @@ func (a *api) getPermissions(c *models.ReqContext) response.Response {
permissions = append(permissions, accesscontrol.ResourcePermission{
Actions: a.service.actions,
Scope: "*",
BuiltInRole: string(models.ROLE_ADMIN),
BuiltInRole: string(org.RoleAdmin),
})
}

View File

@ -113,7 +113,7 @@ func TestApi_getDescription(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, _ := setupTestEnvironment(t, tt.permissions, tt.options)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1}, service)
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/access-control/%s/description", tt.options.Resource), nil)
require.NoError(t, err)
@ -160,7 +160,7 @@ func TestApi_getPermissions(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
seedPermissions(t, tt.resourceID, sql, service)
@ -237,7 +237,7 @@ func TestApi_setBuiltinRolePermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, _ := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
recorder := setPermission(t, server, testOptions.Resource, tt.resourceID, tt.permission, "builtInRoles", tt.builtInRole)
assert.Equal(t, tt.expectedStatus, recorder.Code)
@ -315,7 +315,7 @@ func TestApi_setTeamPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed team
_, err := sql.CreateTeam("test", "test@test.com", 1)
@ -398,7 +398,7 @@ func TestApi_setUserPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed user
_, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "test", OrgID: 1})
@ -418,7 +418,7 @@ func TestApi_setUserPermission(t *testing.T) {
}
}
func setupTestServer(t *testing.T, user *models.SignedInUser, service *Service) *web.Mux {
func setupTestServer(t *testing.T, user *user.SignedInUser, service *Service) *web.Mux {
server := web.New()
server.UseMiddleware(web.Renderer(path.Join(setting.StaticRootPath, "views"), "[[", "]]"))
server.Use(contextProvider(&testContext{user}))
@ -427,7 +427,7 @@ func setupTestServer(t *testing.T, user *models.SignedInUser, service *Service)
}
type testContext struct {
user *models.SignedInUser
user *user.SignedInUser
}
func contextProvider(tc *testContext) web.Handler {

View File

@ -9,7 +9,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"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/setting"
)
@ -105,7 +107,7 @@ type Service struct {
sqlStore *sqlstore.SQLStore
}
func (s *Service) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (s *Service) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
var inheritedScopes []string
if s.options.InheritedScopesSolver != nil {
var err error
@ -318,7 +320,7 @@ func (s *Service) declareFixedRoles() error {
{Action: fmt.Sprintf("%s.permissions:read", s.options.Resource), Scope: scopeAll},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
writerRole := accesscontrol.RoleRegistration{
@ -330,7 +332,7 @@ func (s *Service) declareFixedRoles() error {
{Action: fmt.Sprintf("%s.permissions:write", s.options.Resource), Scope: scopeAll},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
return s.ac.DeclareFixedRoles(readerRole, writerRole)

View File

@ -1,8 +1,8 @@
package types
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type SetResourcePermissionCommand struct {
@ -28,5 +28,5 @@ type GetResourcePermissionsQuery struct {
ResourceAttribute string
OnlyManaged bool
InheritedScopes []string
User *models.SignedInUser
User *user.SignedInUser
}

Some files were not shown because too many files have changed in this diff Show More