From 6afad517618f01433e29d0ea4336fa47d2ab8859 Mon Sep 17 00:00:00 2001 From: idafurjes <36131195+idafurjes@users.noreply.github.com> Date: Wed, 10 Aug 2022 11:56:48 +0200 Subject: [PATCH] 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 --- pkg/api/accesscontrol.go | 35 ++++---- pkg/api/admin.go | 3 +- pkg/api/admin_users_test.go | 11 +-- pkg/api/annotations.go | 10 ++- pkg/api/annotations_test.go | 23 ++--- pkg/api/app_routes.go | 9 +- pkg/api/comments.go | 3 +- pkg/api/common_test.go | 19 ++-- pkg/api/dashboard.go | 7 +- pkg/api/dashboard_permission_test.go | 9 +- pkg/api/dashboard_snapshot_test.go | 27 +++--- pkg/api/dashboard_test.go | 54 +++++------ pkg/api/datasources.go | 3 +- pkg/api/datasources_test.go | 3 +- pkg/api/dtos/acl.go | 11 ++- pkg/api/dtos/apikey.go | 4 +- pkg/api/dtos/invite.go | 10 +-- pkg/api/dtos/models.go | 9 +- pkg/api/dtos/models_test.go | 14 +-- pkg/api/folder_permission_test.go | 11 +-- pkg/api/folder_test.go | 23 ++--- pkg/api/index.go | 11 +-- pkg/api/ldap_debug.go | 11 +-- pkg/api/ldap_debug_test.go | 17 ++-- pkg/api/login_oauth.go | 5 +- pkg/api/login_test.go | 4 +- pkg/api/metrics_test.go | 11 +-- pkg/api/org_invite_test.go | 12 +-- pkg/api/org_test.go | 2 +- pkg/api/org_users.go | 2 +- pkg/api/org_users_test.go | 61 ++++++------- pkg/api/playlist_play.go | 5 +- pkg/api/plugin_dashboards_test.go | 13 +-- pkg/api/pluginproxy/ds_proxy_test.go | 38 ++++---- pkg/api/pluginproxy/pluginproxy_test.go | 20 +++-- pkg/api/pluginproxy/utils.go | 4 +- pkg/api/plugins.go | 3 +- pkg/api/plugins_test.go | 6 +- pkg/api/search_test.go | 5 +- pkg/api/short_url_test.go | 11 +-- pkg/api/team.go | 7 +- pkg/api/team_members_test.go | 7 +- pkg/api/team_test.go | 12 +-- pkg/api/user.go | 4 +- pkg/api/user_token_test.go | 11 +-- pkg/infra/usagestats/service/api_test.go | 7 +- pkg/login/social/azuread_oauth.go | 21 ++--- pkg/login/social/generic_oauth.go | 3 +- pkg/login/social/okta_oauth.go | 3 +- pkg/login/social/social.go | 10 +-- pkg/middleware/auth.go | 11 +-- pkg/middleware/middleware.go | 5 +- pkg/middleware/middleware_basic_auth_test.go | 10 +-- pkg/middleware/middleware_jwt_auth_test.go | 6 +- pkg/middleware/middleware_test.go | 39 ++++---- pkg/middleware/org_redirect_test.go | 5 +- pkg/middleware/quota_test.go | 3 +- pkg/models/alert.go | 3 +- pkg/models/context.go | 8 +- pkg/models/dashboard_acl.go | 10 ++- pkg/models/folders.go | 6 +- pkg/models/helpflags.go | 12 +-- pkg/models/live.go | 9 +- pkg/models/org.go | 8 +- pkg/models/org_user.go | 80 ++--------------- pkg/models/search.go | 3 +- pkg/models/team.go | 10 ++- pkg/models/team_member.go | 4 +- pkg/models/temp_user.go | 8 +- pkg/models/user.go | 70 +-------------- pkg/models/user_auth.go | 3 +- pkg/plugins/accesscontrol.go | 4 +- pkg/plugins/adapters/adapters.go | 4 +- pkg/plugins/manager/loader/loader.go | 3 +- pkg/plugins/manager/loader/loader_test.go | 10 +-- pkg/plugins/models.go | 22 ++--- pkg/plugins/plugincontext/plugincontext.go | 9 +- pkg/plugins/plugins.go | 4 +- pkg/services/accesscontrol/accesscontrol.go | 20 +++-- .../accesscontrol/database/database_test.go | 3 +- .../database/resource_permissions.go | 5 +- .../resource_permissions_bench_test.go | 3 +- .../database/resource_permissions_test.go | 7 +- pkg/services/accesscontrol/filter.go | 4 +- .../accesscontrol/filter_bench_test.go | 4 +- pkg/services/accesscontrol/filter_test.go | 4 +- pkg/services/accesscontrol/middleware.go | 3 +- pkg/services/accesscontrol/middleware_test.go | 3 +- pkg/services/accesscontrol/mock/mock.go | 16 ++-- .../accesscontrol/mock/service_mock.go | 4 +- pkg/services/accesscontrol/models.go | 4 +- .../ossaccesscontrol/ossaccesscontrol.go | 8 +- .../ossaccesscontrol/ossaccesscontrol_test.go | 22 ++--- .../ossaccesscontrol/permissions_services.go | 3 +- pkg/services/accesscontrol/resolvers.go | 12 +-- pkg/services/accesscontrol/resolvers_test.go | 9 +- .../accesscontrol/resourcepermissions/api.go | 3 +- .../resourcepermissions/api_test.go | 14 +-- .../resourcepermissions/service.go | 8 +- .../resourcepermissions/types/models.go | 4 +- pkg/services/accesscontrol/roles.go | 20 ++--- pkg/services/alerting/models.go | 3 +- pkg/services/alerting/notifier.go | 3 +- pkg/services/alerting/store.go | 3 +- pkg/services/alerting/store_test.go | 18 ++-- pkg/services/alerting/test_rule.go | 3 +- pkg/services/annotations/annotations.go | 4 +- pkg/services/apikey/apikeyimpl/store_test.go | 12 +-- pkg/services/apikey/model.go | 19 ++-- .../comments/commentmodel/permissions.go | 5 +- pkg/services/comments/handlers.go | 5 +- .../contexthandler/auth_proxy_test.go | 2 +- .../contexthandler/authproxy/authproxy.go | 8 +- pkg/services/contexthandler/contexthandler.go | 19 ++-- pkg/services/dashboardimport/api/api_test.go | 11 +-- .../dashboardimport/dashboardimport.go | 4 +- .../dashboardimport/service/service_test.go | 18 ++-- pkg/services/dashboards/database/acl.go | 5 +- pkg/services/dashboards/database/acl_test.go | 19 ++-- .../database/database_folder_test.go | 51 +++++------ .../dashboards/database/database_test.go | 49 +++++----- pkg/services/dashboards/folder.go | 15 ++-- .../dashboards/folder_service_mock.go | 81 ++++++++--------- pkg/services/dashboards/models.go | 3 +- .../dashboards/service/dashboard_service.go | 18 ++-- .../dashboard_service_integration_test.go | 12 +-- .../service/dashboard_service_test.go | 15 ++-- .../dashboards/service/folder_service.go | 20 +++-- .../dashboards/service/folder_service_test.go | 29 +++--- .../dashboardsnapshots/database/database.go | 4 +- .../database/database_test.go | 15 ++-- pkg/services/dashboardsnapshots/models.go | 4 +- pkg/services/datasources/datasources.go | 6 +- .../datasources/fakes/fake_cache_service.go | 6 +- pkg/services/datasources/models.go | 8 +- .../permissions/datasource_permissions.go | 6 +- .../datasource_permissions_mocks.go | 4 +- .../datasources/service/cache_service.go | 6 +- .../guardian/accesscontrol_guardian.go | 10 ++- .../guardian/accesscontrol_guardian_test.go | 3 +- pkg/services/guardian/guardian.go | 18 ++-- pkg/services/guardian/guardian_test.go | 22 ++--- pkg/services/guardian/guardian_util_test.go | 12 +-- pkg/services/guardian/provider.go | 6 +- pkg/services/ldap/ldap.go | 3 +- pkg/services/ldap/ldap_private_test.go | 5 +- pkg/services/ldap/settings.go | 4 +- pkg/services/libraryelements/database.go | 30 ++++--- pkg/services/libraryelements/guard.go | 12 +-- .../libraryelements/libraryelements.go | 18 ++-- .../libraryelements_delete_test.go | 3 +- .../libraryelements_get_all_test.go | 3 +- .../libraryelements_get_test.go | 3 +- .../libraryelements_permissions_test.go | 89 ++++++++++--------- .../libraryelements/libraryelements_test.go | 13 +-- pkg/services/librarypanels/librarypanels.go | 11 +-- .../librarypanels/librarypanels_test.go | 13 +-- pkg/services/live/features/broadcast.go | 5 +- pkg/services/live/features/broadcast_test.go | 5 +- pkg/services/live/features/comment.go | 5 +- pkg/services/live/features/dashboard.go | 28 +++--- pkg/services/live/features/plugin.go | 7 +- pkg/services/live/features/plugin_mock.go | 4 +- pkg/services/live/live.go | 18 ++-- pkg/services/live/livecontext/context.go | 8 +- pkg/services/live/liveplugin/plugin.go | 4 +- pkg/services/live/managedstream/runner.go | 5 +- pkg/services/live/pipeline/auth.go | 11 +-- pkg/services/live/pipeline/config.go | 4 +- pkg/services/live/pipeline/pipeline.go | 7 +- .../live/pipeline/subscribe_builtin.go | 3 +- pkg/services/live/runstream/manager.go | 8 +- pkg/services/live/runstream/manager_test.go | 35 ++++---- pkg/services/live/runstream/mock.go | 4 +- .../login/loginservice/loginservice_test.go | 11 +-- pkg/services/ngalert/accesscontrol.go | 8 +- .../ngalert/api/api_alertmanager_test.go | 30 ++++--- pkg/services/ngalert/api/api_configuration.go | 7 +- .../ngalert/api/api_configuration_test.go | 4 +- .../ngalert/api/api_prometheus_test.go | 14 +-- .../ngalert/api/api_provisioning_test.go | 3 +- pkg/services/ngalert/api/api_ruler_test.go | 24 ++--- pkg/services/ngalert/api/api_testing_test.go | 9 +- pkg/services/ngalert/api/lotex_ruler_test.go | 5 +- pkg/services/ngalert/api/util.go | 5 +- pkg/services/ngalert/eval/eval.go | 7 +- pkg/services/ngalert/schedule/schedule.go | 7 +- pkg/services/ngalert/store/alert_rule.go | 13 +-- pkg/services/ngalert/store/testing.go | 7 +- pkg/services/oauthtoken/oauth_token.go | 4 +- pkg/services/org/model.go | 62 ++++++++++++- .../service/dashboard_updater.go | 4 +- .../service/dashboard_updater_test.go | 9 +- .../preference/prefimpl/store_test.go | 6 +- pkg/services/publicdashboards/api/api_test.go | 7 +- .../publicdashboards/api/common_test.go | 6 +- .../public_dashboard_service_mock.go | 9 +- .../publicdashboards/publicdashboard.go | 3 +- .../publicdashboards/service/service.go | 5 +- pkg/services/query/query.go | 13 +-- pkg/services/query/query_test.go | 8 +- pkg/services/queryhistory/database.go | 16 ++-- pkg/services/queryhistory/queryhistory.go | 30 +++---- .../queryhistory/queryhistory_test.go | 5 +- pkg/services/queryhistory/writers.go | 4 +- pkg/services/rendering/interface.go | 3 +- pkg/services/screenshot/screenshot.go | 3 +- pkg/services/screenshot/screenshot_test.go | 3 +- pkg/services/search/service.go | 3 +- pkg/services/search/service_test.go | 5 +- pkg/services/searchV2/allowed_actions.go | 8 +- pkg/services/searchV2/allowed_actions_test.go | 4 +- pkg/services/searchV2/auth.go | 7 +- pkg/services/searchV2/service.go | 34 +++---- pkg/services/serviceaccounts/api/api.go | 3 +- pkg/services/serviceaccounts/api/api_test.go | 48 +++++----- .../serviceaccounts/api/token_test.go | 22 ++--- .../serviceaccounts/database/database.go | 5 +- .../serviceaccounts/database/database_test.go | 34 +++---- .../serviceaccounts/database/token_store.go | 4 +- pkg/services/serviceaccounts/manager/roles.go | 8 +- pkg/services/serviceaccounts/models.go | 10 +-- .../serviceaccounts/serviceaccounts.go | 4 +- pkg/services/serviceaccounts/tests/common.go | 12 +-- pkg/services/shorturls/short_url_service.go | 9 +- .../shorturls/short_url_service_test.go | 3 +- pkg/services/sqlstore/annotation.go | 3 +- pkg/services/sqlstore/annotation_test.go | 5 +- .../managed_permission_migrator.go | 4 +- .../accesscontrol/team_membership.go | 3 +- .../migrations/accesscontrol/test/ac_test.go | 11 +-- .../sqlstore/migrations/ualert/permissions.go | 8 +- pkg/services/sqlstore/mockstore/mockstore.go | 2 +- pkg/services/sqlstore/org.go | 19 ++-- pkg/services/sqlstore/org_test.go | 25 +++--- pkg/services/sqlstore/org_users_test.go | 14 +-- .../sqlstore/permissions/dashboard.go | 14 +-- .../sqlstore/permissions/dashboard_test.go | 5 +- .../sqlstore/searchstore/search_test.go | 14 +-- pkg/services/sqlstore/sqlbuilder.go | 3 +- pkg/services/sqlstore/sqlbuilder_test.go | 35 ++++---- pkg/services/sqlstore/stats.go | 15 ++-- pkg/services/sqlstore/stats_test.go | 17 ++-- pkg/services/sqlstore/team.go | 3 +- pkg/services/sqlstore/team_test.go | 22 ++--- pkg/services/sqlstore/user.go | 15 ++-- pkg/services/sqlstore/user_test.go | 9 +- pkg/services/store/file_guardian.go | 6 +- pkg/services/store/sanitize.go | 6 +- pkg/services/store/service.go | 42 ++++----- pkg/services/store/service_test.go | 8 +- pkg/services/store/static_auth.go | 6 +- pkg/services/store/storage_git.go | 12 +-- pkg/services/store/types.go | 4 +- pkg/services/store/validate.go | 8 +- pkg/services/teamguardian/manager/service.go | 6 +- .../teamguardian/manager/service_mock.go | 4 +- .../teamguardian/manager/service_test.go | 10 ++- pkg/services/teamguardian/team.go | 3 +- pkg/services/thumbs/crawler_auth.go | 11 +-- pkg/services/user/model.go | 75 ++++++++++++++++ pkg/services/user/userimpl/user.go | 2 +- .../alerting/api_admin_configuration_test.go | 6 +- .../api_alertmanager_configuration_test.go | 8 +- .../api/alerting/api_alertmanager_test.go | 25 +++--- .../alerting/api_available_channel_test.go | 4 +- .../alerting/api_notification_channel_test.go | 19 ++-- pkg/tests/api/alerting/api_prometheus_test.go | 18 ++-- .../api/alerting/api_provisioning_test.go | 8 +- pkg/tests/api/alerting/api_ruler_test.go | 16 ++-- .../correlations/correlations_create_test.go | 6 +- .../correlations/correlations_delete_test.go | 6 +- .../correlations/correlations_update_test.go | 6 +- .../api/dashboards/api_dashboards_test.go | 5 +- pkg/tests/testinfra/testinfra.go | 4 +- pkg/tsdb/legacydata/contracts.go | 4 +- pkg/web/webtest/webtest.go | 3 +- pkg/web/webtest/webtest_test.go | 9 +- 278 files changed, 1758 insertions(+), 1543 deletions(-) diff --git a/pkg/api/accesscontrol.go b/pkg/api/accesscontrol.go index 18ccf9f0c09..d1cbbc74b6d 100644 --- a/pkg/api/accesscontrol.go +++ b/pkg/api/accesscontrol.go @@ -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{ diff --git a/pkg/api/admin.go b/pkg/api/admin.go index c837733301c..d569e658db2 100644 --- a/pkg/api/admin.go +++ b/pkg/api/admin.go @@ -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 } diff --git a/pkg/api/admin_users_test.go b/pkg/api/admin_users_test.go index 282f4e73504..93c65ee6ab6 100644 --- a/pkg/api/admin_users_test.go +++ b/pkg/api/admin_users_test.go @@ -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) }) diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index 0e1a5d1075c..dac4b6a09c9 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -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 } } } diff --git a/pkg/api/annotations_test.go b/pkg/api/annotations_test.go index eb85b7b7843..f38ac7647ff 100644 --- a/pkg/api/annotations_test.go +++ b/pkg/api/annotations_test.go @@ -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{} diff --git a/pkg/api/app_routes.go b/pkg/api/app_routes.go index 03d30848d72..5883a14d39c 100644 --- a/pkg/api/app_routes.go +++ b/pkg/api/app_routes.go @@ -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)) } } diff --git a/pkg/api/comments.go b/pkg/api/comments.go index 7f32d64ac08..bb7c9c3dded 100644 --- a/pkg/api/comments.go +++ b/pkg/api/comments.go @@ -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) diff --git a/pkg/api/common_test.go b/pkg/api/common_test.go index 855fa2ccd15..5ce4f8cb87c 100644 --- a/pkg/api/common_test.go +++ b/pkg/api/common_test.go @@ -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 { diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index e86e1018d85..f1e3c68a0f8 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -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 } diff --git a/pkg/api/dashboard_permission_test.go b/pkg/api/dashboard_permission_test.go index 96ae39ed472..104fe5a35ce 100644 --- a/pkg/api/dashboard_permission_test.go +++ b/pkg/api/dashboard_permission_test.go @@ -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, diff --git a/pkg/api/dashboard_snapshot_test.go b/pkg/api/dashboard_snapshot_test.go index 10f09f9d409..720964a84c3 100644 --- a/pkg/api/dashboard_snapshot_test.go +++ b/pkg/api/dashboard_snapshot_test.go @@ -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 diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index bf6d3ed5711..b945132816c 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -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 } diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index 3b9bd651e68..f44be65cbf8 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -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, diff --git a/pkg/api/datasources_test.go b/pkg/api/datasources_test.go index bcbc9e33809..6f0cbd2ce0a 100644 --- a/pkg/api/datasources_test.go +++ b/pkg/api/datasources_test.go @@ -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) diff --git a/pkg/api/dtos/acl.go b/pkg/api/dtos/acl.go index 4d5aee81c1a..ae0f8e9f266 100644 --- a/pkg/api/dtos/acl.go +++ b/pkg/api/dtos/acl.go @@ -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 diff --git a/pkg/api/dtos/apikey.go b/pkg/api/dtos/apikey.go index 6353deccd60..353742e0ac9 100644 --- a/pkg/api/dtos/apikey.go +++ b/pkg/api/dtos/apikey.go @@ -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"` } diff --git a/pkg/api/dtos/invite.go b/pkg/api/dtos/invite.go index 99003ef1baa..9586ba95cbd 100644 --- a/pkg/api/dtos/invite.go +++ b/pkg/api/dtos/invite.go @@ -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 { diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index 343b5f6c1b2..84019d53539 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -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 } diff --git a/pkg/api/dtos/models_test.go b/pkg/api/dtos/models_test.go index 522ea8ba944..b25008e1551 100644 --- a/pkg/api/dtos/models_test.go +++ b/pkg/api/dtos/models_test.go @@ -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", }, diff --git a/pkg/api/folder_permission_test.go b/pkg/api/folder_permission_test.go index 7c3b85a3f01..8bf13f5b3bc 100644 --- a/pkg/api/folder_permission_test.go +++ b/pkg/api/folder_permission_test.go @@ -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) diff --git a/pkg/api/folder_test.go b/pkg/api/folder_test.go index af6ccb91c49..42225ec17f7 100644 --- a/pkg/api/folder_test.go +++ b/pkg/api/folder_test.go @@ -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 } diff --git a/pkg/api/index.go b/pkg/api/index.go index c11ceb20f62..bc310030dfb 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -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", diff --git a/pkg/api/ldap_debug.go b/pkg/api/ldap_debug.go index 788db803193..7542b583874 100644 --- a/pkg/api/ldap_debug.go +++ b/pkg/api/ldap_debug.go @@ -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] != "" { diff --git a/pkg/api/ldap_debug_test.go b/pkg/api/ldap_debug_test.go index fa4d5586d39..5a082cafc91 100644 --- a/pkg/api/ldap_debug_test.go +++ b/pkg/api/ldap_debug_test.go @@ -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, }, }, } diff --git a/pkg/api/login_oauth.go b/pkg/api/login_oauth.go index 1ca8690d94b..a6161252eee 100644 --- a/pkg/api/login_oauth.go +++ b/pkg/api/login_oauth.go @@ -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 diff --git a/pkg/api/login_test.go b/pkg/api/login_test.go index 22b5acc7600..678a25fcbcd 100644 --- a/pkg/api/login_test.go +++ b/pkg/api/login_test.go @@ -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) diff --git a/pkg/api/metrics_test.go b/pkg/api/metrics_test.go index 95c6fb8040d..373727bf7b9 100644 --- a/pkg/api/metrics_test.go +++ b/pkg/api/metrics_test.go @@ -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) diff --git a/pkg/api/org_invite_test.go b/pkg/api/org_invite_test.go index 31bc21ea818..91d27243155 100644 --- a/pkg/api/org_invite_test.go +++ b/pkg/api/org_invite_test.go @@ -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) + `"}`, }, } diff --git a/pkg/api/org_test.go b/pkg/api/org_test.go index 3c44b823644..7b5405c4236 100644 --- a/pkg/api/org_test.go +++ b/pkg/api/org_test.go @@ -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}) diff --git a/pkg/api/org_users.go b/pkg/api/org_users.go index 2edbccdb903..54b5910656b 100644 --- a/pkg/api/org_users.go +++ b/pkg/api/org_users.go @@ -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 } diff --git a/pkg/api/org_users_test.go b/pkg/api/org_users_test.go index 2cbedc2a0e7..c81b0aaf4d1 100644 --- a/pkg/api/org_users_test.go +++ b/pkg/api/org_users_test.go @@ -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}}}, }, diff --git a/pkg/api/playlist_play.go b/pkg/api/playlist_play.go index 035c4d402f4..0e447440bff 100644 --- a/pkg/api/playlist_play.go +++ b/pkg/api/playlist_play.go @@ -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) diff --git a/pkg/api/plugin_dashboards_test.go b/pkg/api/plugin_dashboards_test.go index 07e595bc528..ae375adc17e 100644 --- a/pkg/api/plugin_dashboards_test.go +++ b/pkg/api/plugin_dashboards_test.go @@ -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)) diff --git a/pkg/api/pluginproxy/ds_proxy_test.go b/pkg/api/pluginproxy/ds_proxy_test.go index 965e2d01f05..ee7d1ac2181 100644 --- a/pkg/api/pluginproxy/ds_proxy_test.go +++ b/pkg/api/pluginproxy/ds_proxy_test.go @@ -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 } diff --git a/pkg/api/pluginproxy/pluginproxy_test.go b/pkg/api/pluginproxy/pluginproxy_test.go index 28512cbd9c3..71bf9fe92db 100644 --- a/pkg/api/pluginproxy/pluginproxy_test.go +++ b/pkg/api/pluginproxy/pluginproxy_test.go @@ -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) diff --git a/pkg/api/pluginproxy/utils.go b/pkg/api/pluginproxy/utils.go index 9ce875d8558..27f237a5ca4 100644 --- a/pkg/api/pluginproxy/utils.go +++ b/pkg/api/pluginproxy/utils.go @@ -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) diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index ffe3101a016..0f669caa3cc 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -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" } diff --git a/pkg/api/plugins_test.go b/pkg/api/plugins_test.go index 65105220756..d36261b7edd 100644 --- a/pkg/api/plugins_test.go +++ b/pkg/api/plugins_test.go @@ -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) diff --git a/pkg/api/search_test.go b/pkg/api/search_test.go index 0c46caf77aa..eb9187ec689 100644 --- a/pkg/api/search_test.go +++ b/pkg/api/search_test.go @@ -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"}, diff --git a/pkg/api/short_url_test.go b/pkg/api/short_url_test.go index bb592a9d30a..f881529d45a 100644 --- a/pkg/api/short_url_test.go +++ b/pkg/api/short_url_test.go @@ -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) } diff --git a/pkg/api/team.go b/pkg/api/team.go index baf057f3fd2..19e74d42d2f 100644 --- a/pkg/api/team.go +++ b/pkg/api/team.go @@ -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 diff --git a/pkg/api/team_members_test.go b/pkg/api/team_members_test.go index 94434f00490..f30bdf7e748 100644 --- a/pkg/api/team_members_test.go +++ b/pkg/api/team_members_test.go @@ -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 diff --git a/pkg/api/team_test.go b/pkg/api/team_test.go index ee4170d8adf..b62b876da32 100644 --- a/pkg/api/team_test.go +++ b/pkg/api/team_test.go @@ -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) diff --git a/pkg/api/user.go b/pkg/api/user.go index 81eab06c98e..ac55c87e88a 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -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 { diff --git a/pkg/api/user_token_test.go b/pkg/api/user_token_test.go index c52874e1c71..ef8c525f4e9 100644 --- a/pkg/api/user_token_test.go +++ b/pkg/api/user_token_test.go @@ -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) diff --git a/pkg/infra/usagestats/service/api_test.go b/pkg/infra/usagestats/service/api_test.go index 7817658182c..fd172164d94 100644 --- a/pkg/infra/usagestats/service/api_test.go +++ b/pkg/infra/usagestats/service/api_test.go @@ -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 { diff --git a/pkg/login/social/azuread_oauth.go b/pkg/login/social/azuread_oauth.go index ecf4c70b793..4fee59d4a49 100644 --- a/pkg/login/social/azuread_oauth.go +++ b/pkg/login/social/azuread_oauth.go @@ -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 diff --git a/pkg/login/social/generic_oauth.go b/pkg/login/social/generic_oauth.go index 40701df138b..8fa7ab43d40 100644 --- a/pkg/login/social/generic_oauth.go +++ b/pkg/login/social/generic_oauth.go @@ -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") } diff --git a/pkg/login/social/okta_oauth.go b/pkg/login/social/okta_oauth.go index e8e4bfe1186..ab5ec9a9e5d 100644 --- a/pkg/login/social/okta_oauth.go +++ b/pkg/login/social/okta_oauth.go @@ -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") } diff --git a/pkg/login/social/social.go b/pkg/login/social/social.go index d172c362a5a..9c1f6396425 100644 --- a/pkg/login/social/social.go +++ b/pkg/login/social/social.go @@ -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 } } diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index a4d903ef73b..d3a73f152b8 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -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 } diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 7cd7b958e81..22225cecd75 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -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) { diff --git a/pkg/middleware/middleware_basic_auth_test.go b/pkg/middleware/middleware_basic_auth_test.go index 3a9d07c108e..c2c51007871 100644 --- a/pkg/middleware/middleware_basic_auth_test.go +++ b/pkg/middleware/middleware_basic_auth_test.go @@ -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) diff --git a/pkg/middleware/middleware_jwt_auth_test.go b/pkg/middleware/middleware_jwt_auth_test.go index c94f4698f78..59cd26f61ea 100644 --- a/pkg/middleware/middleware_jwt_auth_test.go +++ b/pkg/middleware/middleware_jwt_auth_test.go @@ -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) diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index 77641c717cb..db8944b409c 100644 --- a/pkg/middleware/middleware_test.go +++ b/pkg/middleware/middleware_test.go @@ -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", "/") diff --git a/pkg/middleware/org_redirect_test.go b/pkg/middleware/org_redirect_test.go index f943d12bd0a..f20fb74c6f5 100644 --- a/pkg/middleware/org_redirect_test.go +++ b/pkg/middleware/org_redirect_test.go @@ -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{ diff --git a/pkg/middleware/quota_test.go b/pkg/middleware/quota_test.go index 28378e9f7ea..a8540e3fba0 100644 --- a/pkg/middleware/quota_test.go +++ b/pkg/middleware/quota_test.go @@ -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, diff --git a/pkg/models/alert.go b/pkg/models/alert.go index 898f343dcb5..30c6badbb03 100644 --- a/pkg/models/alert.go +++ b/pkg/models/alert.go @@ -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 } diff --git a/pkg/models/context.go b/pkg/models/context.go index 3907dcb3942..dd07b7236b8 100644 --- a/pkg/models/context.go +++ b/pkg/models/context.go @@ -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) } diff --git a/pkg/models/dashboard_acl.go b/pkg/models/dashboard_acl.go index 7ce20b4476a..83b1e6a68bc 100644 --- a/pkg/models/dashboard_acl.go +++ b/pkg/models/dashboard_acl.go @@ -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"` diff --git a/pkg/models/folders.go b/pkg/models/folders.go index a2f98f4cd16..dc2bf1e1c70 100644 --- a/pkg/models/folders.go +++ b/pkg/models/folders.go @@ -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 } diff --git a/pkg/models/helpflags.go b/pkg/models/helpflags.go index 25064d28b37..48b35954aa0 100644 --- a/pkg/models/helpflags.go +++ b/pkg/models/helpflags.go @@ -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 } diff --git a/pkg/models/live.go b/pkg/models/live.go index 47b4d56ce27..32ac9c68d09 100644 --- a/pkg/models/live.go +++ b/pkg/models/live.go @@ -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 diff --git a/pkg/models/org.go b/pkg/models/org.go index 6417cc334a6..65f4b3ea1d2 100644 --- a/pkg/models/org.go +++ b/pkg/models/org.go @@ -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"` } diff --git a/pkg/models/org_user.go b/pkg/models/org_user.go index b92a165dc78..55e271a3d1e 100644 --- a/pkg/models/org_user.go +++ b/pkg/models/org_user.go @@ -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 } diff --git a/pkg/models/search.go b/pkg/models/search.go index db6f9090c2a..6629620b99a 100644 --- a/pkg/models/search.go +++ b/pkg/models/search.go @@ -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 diff --git a/pkg/models/team.go b/pkg/models/team.go index 2f3852765d0..a3182806ae8 100644 --- a/pkg/models/team.go +++ b/pkg/models/team.go @@ -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 } diff --git a/pkg/models/team_member.go b/pkg/models/team_member.go index aee5d343414..1aea6c5fcdf 100644 --- a/pkg/models/team_member.go +++ b/pkg/models/team_member.go @@ -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 } diff --git a/pkg/models/temp_user.go b/pkg/models/temp_user.go index 35ace952539..116e37cd754 100644 --- a/pkg/models/temp_user.go +++ b/pkg/models/temp_user.go @@ -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"` diff --git a/pkg/models/user.go b/pkg/models/user.go index 7b6905bd9d8..61e3efc3d6b 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -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"` diff --git a/pkg/models/user_auth.go b/pkg/models/user_auth.go index aca8aa8a601..8029d7f321b 100644 --- a/pkg/models/user_auth.go +++ b/pkg/models/user_auth.go @@ -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 } diff --git a/pkg/plugins/accesscontrol.go b/pkg/plugins/accesscontrol.go index be402538dc8..c382200d79e 100644 --- a/pkg/plugins/accesscontrol.go +++ b/pkg/plugins/accesscontrol.go @@ -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) } diff --git a/pkg/plugins/adapters/adapters.go b/pkg/plugins/adapters/adapters.go index 6843254b2f7..3bad28ae3ee 100644 --- a/pkg/plugins/adapters/adapters.go +++ b/pkg/plugins/adapters/adapters.go @@ -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 } diff --git a/pkg/plugins/manager/loader/loader.go b/pkg/plugins/manager/loader/loader.go index dd940bf4e02..b8b451d8baa 100644 --- a/pkg/plugins/manager/loader/loader.go +++ b/pkg/plugins/manager/loader/loader.go @@ -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 } } diff --git a/pkg/plugins/manager/loader/loader_test.go b/pkg/plugins/manager/loader/loader_test.go index e000c471d29..6fe821063f6 100644 --- a/pkg/plugins/manager/loader/loader_test.go +++ b/pkg/plugins/manager/loader/loader_test.go @@ -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, }, diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index f3ba3e3900b..0a3702f48a2 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -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:"-"` } diff --git a/pkg/plugins/plugincontext/plugincontext.go b/pkg/plugins/plugincontext/plugincontext.go index 9e09a477236..ce10822c0e2 100644 --- a/pkg/plugins/plugincontext/plugincontext.go +++ b/pkg/plugins/plugincontext/plugincontext.go @@ -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 { diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 7ae0208d69b..d04a11ceefb 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -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"` diff --git a/pkg/services/accesscontrol/accesscontrol.go b/pkg/services/accesscontrol/accesscontrol.go index 45dcafc01d6..20e8107d95f 100644 --- a/pkg/services/accesscontrol/accesscontrol.go +++ b/pkg/services/accesscontrol/accesscontrol.go @@ -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. diff --git a/pkg/services/accesscontrol/database/database_test.go b/pkg/services/accesscontrol/database/database_test.go index de26f5b851c..0840c31e0d0 100644 --- a/pkg/services/accesscontrol/database/database_test.go +++ b/pkg/services/accesscontrol/database/database_test.go @@ -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)) diff --git a/pkg/services/accesscontrol/database/resource_permissions.go b/pkg/services/accesscontrol/database/resource_permissions.go index 69034277678..f8017177cfe 100644 --- a/pkg/services/accesscontrol/database/resource_permissions.go +++ b/pkg/services/accesscontrol/database/resource_permissions.go @@ -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 { diff --git a/pkg/services/accesscontrol/database/resource_permissions_bench_test.go b/pkg/services/accesscontrol/database/resource_permissions_bench_test.go index 56ddb86d51d..a8c867fcf1e 100644 --- a/pkg/services/accesscontrol/database/resource_permissions_bench_test.go +++ b/pkg/services/accesscontrol/database/resource_permissions_bench_test.go @@ -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)), diff --git a/pkg/services/accesscontrol/database/resource_permissions_test.go b/pkg/services/accesscontrol/database/resource_permissions_test.go index fd7fc73a4cf..400fcf13d37 100644 --- a/pkg/services/accesscontrol/database/resource_permissions_test.go +++ b/pkg/services/accesscontrol/database/resource_permissions_test.go @@ -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}}, diff --git a/pkg/services/accesscontrol/filter.go b/pkg/services/accesscontrol/filter.go index 8aec1d186f5..efa30db2e83 100644 --- a/pkg/services/accesscontrol/filter.go +++ b/pkg/services/accesscontrol/filter.go @@ -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") } diff --git a/pkg/services/accesscontrol/filter_bench_test.go b/pkg/services/accesscontrol/filter_bench_test.go index 952de70047b..f13d37e2751 100644 --- a/pkg/services/accesscontrol/filter_bench_test.go +++ b/pkg/services/accesscontrol/filter_bench_test.go @@ -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", diff --git a/pkg/services/accesscontrol/filter_test.go b/pkg/services/accesscontrol/filter_test.go index 48baacdff9d..9f044a2c2e2 100644 --- a/pkg/services/accesscontrol/filter_test.go +++ b/pkg/services/accesscontrol/filter_test.go @@ -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}, }, diff --git a/pkg/services/accesscontrol/middleware.go b/pkg/services/accesscontrol/middleware.go index 6e732cf57c9..bc05239ebaa 100644 --- a/pkg/services/accesscontrol/middleware.go +++ b/pkg/services/accesscontrol/middleware.go @@ -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), diff --git a/pkg/services/accesscontrol/middleware_test.go b/pkg/services/accesscontrol/middleware_test.go index 013e3d98876..8f5596193de 100644 --- a/pkg/services/accesscontrol/middleware_test.go +++ b/pkg/services/accesscontrol/middleware_test.go @@ -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, } diff --git a/pkg/services/accesscontrol/mock/mock.go b/pkg/services/accesscontrol/mock/mock.go index 82ab38692b8..527047a6609 100644 --- a/pkg/services/accesscontrol/mock/mock.go +++ b/pkg/services/accesscontrol/mock/mock.go @@ -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 diff --git a/pkg/services/accesscontrol/mock/service_mock.go b/pkg/services/accesscontrol/mock/service_mock.go index b57797b6f92..e6550f23655 100644 --- a/pkg/services/accesscontrol/mock/service_mock.go +++ b/pkg/services/accesscontrol/mock/service_mock.go @@ -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) } diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index 0317ea73b52..2227f0e598f 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -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{}{} } } diff --git a/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol.go b/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol.go index 410fc2994e2..cba229bac94 100644 --- a/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol.go +++ b/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol.go @@ -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) { diff --git a/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol_test.go b/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol_test.go index eadffb873cb..b3384d46a5b 100644 --- a/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol_test.go +++ b/pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol_test.go @@ -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 diff --git a/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go b/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go index d33ab1a4c39..62644aa2833 100644 --- a/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go +++ b/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go @@ -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 } diff --git a/pkg/services/accesscontrol/resolvers.go b/pkg/services/accesscontrol/resolvers.go index ae123ec62d8..6f8050474ee 100644 --- a/pkg/services/accesscontrol/resolvers.go +++ b/pkg/services/accesscontrol/resolvers.go @@ -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 }) diff --git a/pkg/services/accesscontrol/resolvers_test.go b/pkg/services/accesscontrol/resolvers_test.go index 913b4477dd6..8640e5451c8 100644 --- a/pkg/services/accesscontrol/resolvers_test.go +++ b/pkg/services/accesscontrol/resolvers_test.go @@ -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", diff --git a/pkg/services/accesscontrol/resourcepermissions/api.go b/pkg/services/accesscontrol/resourcepermissions/api.go index a1892130cfd..e352c8a23cf 100644 --- a/pkg/services/accesscontrol/resourcepermissions/api.go +++ b/pkg/services/accesscontrol/resourcepermissions/api.go @@ -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), }) } diff --git a/pkg/services/accesscontrol/resourcepermissions/api_test.go b/pkg/services/accesscontrol/resourcepermissions/api_test.go index 2f32ae41b81..0920c956c1f 100644 --- a/pkg/services/accesscontrol/resourcepermissions/api_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/api_test.go @@ -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 { diff --git a/pkg/services/accesscontrol/resourcepermissions/service.go b/pkg/services/accesscontrol/resourcepermissions/service.go index d8ae4903963..76938cfd63e 100644 --- a/pkg/services/accesscontrol/resourcepermissions/service.go +++ b/pkg/services/accesscontrol/resourcepermissions/service.go @@ -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) diff --git a/pkg/services/accesscontrol/resourcepermissions/types/models.go b/pkg/services/accesscontrol/resourcepermissions/types/models.go index 7733f2394d3..668c23efa2f 100644 --- a/pkg/services/accesscontrol/resourcepermissions/types/models.go +++ b/pkg/services/accesscontrol/resourcepermissions/types/models.go @@ -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 } diff --git a/pkg/services/accesscontrol/roles.go b/pkg/services/accesscontrol/roles.go index f5dcae6dfbc..d8ea695aab8 100644 --- a/pkg/services/accesscontrol/roles.go +++ b/pkg/services/accesscontrol/roles.go @@ -5,7 +5,7 @@ import ( "strings" "sync" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" ) // Roles definition @@ -181,11 +181,11 @@ func DeclareFixedRoles(ac AccessControl) error { } orgUsersReader := RoleRegistration{ Role: orgUsersReaderRole, - Grants: []string{RoleGrafanaAdmin, string(models.ROLE_ADMIN)}, + Grants: []string{RoleGrafanaAdmin, string(org.RoleAdmin)}, } orgUsersWriter := RoleRegistration{ Role: orgUsersWriterRole, - Grants: []string{RoleGrafanaAdmin, string(models.ROLE_ADMIN)}, + Grants: []string{RoleGrafanaAdmin, string(org.RoleAdmin)}, } settingsReader := RoleRegistration{ Role: SettingsReaderRole, @@ -232,7 +232,7 @@ func ValidateFixedRole(role RoleDTO) error { // ValidateBuiltInRoles errors when a built-in role does not match expected pattern func ValidateBuiltInRoles(builtInRoles []string) error { for _, br := range builtInRoles { - if !models.RoleType(br).IsValid() && br != RoleGrafanaAdmin { + if !org.RoleType(br).IsValid() && br != RoleGrafanaAdmin { return fmt.Errorf("'%s' %w", br, ErrInvalidBuiltinRole) } } @@ -262,34 +262,34 @@ func (m *RegistrationList) Range(f func(registration RoleRegistration) bool) { func BuildBasicRoleDefinitions() map[string]*RoleDTO { return map[string]*RoleDTO{ - string(models.ROLE_ADMIN): { + string(org.RoleAdmin): { Name: BasicRolePrefix + "admin", UID: BasicRoleUIDPrefix + "admin", OrgID: GlobalOrgID, Version: 1, - DisplayName: string(models.ROLE_ADMIN), + DisplayName: string(org.RoleAdmin), Description: "Admin role", Group: "Basic", Permissions: []Permission{}, Hidden: true, }, - string(models.ROLE_EDITOR): { + string(org.RoleEditor): { Name: BasicRolePrefix + "editor", UID: BasicRoleUIDPrefix + "editor", OrgID: GlobalOrgID, Version: 1, - DisplayName: string(models.ROLE_EDITOR), + DisplayName: string(org.RoleEditor), Description: "Editor role", Group: "Basic", Permissions: []Permission{}, Hidden: true, }, - string(models.ROLE_VIEWER): { + string(org.RoleViewer): { Name: BasicRolePrefix + "viewer", UID: BasicRoleUIDPrefix + "viewer", OrgID: GlobalOrgID, Version: 1, - DisplayName: string(models.ROLE_VIEWER), + DisplayName: string(org.RoleViewer), Description: "Viewer role", Group: "Basic", Permissions: []Permission{}, diff --git a/pkg/services/alerting/models.go b/pkg/services/alerting/models.go index d4cb0bf84b5..c484c10a23a 100644 --- a/pkg/services/alerting/models.go +++ b/pkg/services/alerting/models.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // Job holds state about when the alert rule should be evaluated. @@ -45,7 +46,7 @@ type EvalMatch struct { } type DashAlertInfo struct { - User *models.SignedInUser + User *user.SignedInUser Dash *models.Dashboard OrgID int64 } diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index 3df0c8abfef..817d41e898d 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/notifications" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/setting" ) @@ -210,7 +211,7 @@ func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout }, AuthOpts: rendering.AuthOpts{ OrgID: evalCtx.Rule.OrgID, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, Width: 1000, Height: 500, diff --git a/pkg/services/alerting/store.go b/pkg/services/alerting/store.go index c1131ef0cfe..0fbf0eb5971 100644 --- a/pkg/services/alerting/store.go +++ b/pkg/services/alerting/store.go @@ -9,6 +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/org" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/db" "github.com/grafana/grafana/pkg/setting" @@ -154,7 +155,7 @@ func (ss *sqlStore) HandleAlertsQuery(ctx context.Context, query *models.GetAler builder.Write(")") } - if query.User.OrgRole != models.ROLE_ADMIN { + if query.User.OrgRole != org.RoleAdmin { builder.WriteDashboardPermissionFilter(query.User, models.PERMISSION_VIEW) } diff --git a/pkg/services/alerting/store_test.go b/pkg/services/alerting/store_test.go index 2a78a017f42..e2621ea434b 100644 --- a/pkg/services/alerting/store_test.go +++ b/pkg/services/alerting/store_test.go @@ -10,8 +10,10 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/db" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -74,7 +76,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { setup(t) // Get alert so we can use its ID in tests - alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &alertQuery) require.Nil(t, err2) @@ -131,7 +133,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { t.Run("Can read properties", func(t *testing.T) { setup(t) - alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &alertQuery) alert := alertQuery.Result[0] @@ -152,7 +154,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { t.Run("Viewer can read alerts", func(t *testing.T) { setup(t) - viewerUser := &models.SignedInUser{OrgRole: models.ROLE_VIEWER, OrgId: 1} + viewerUser := &user.SignedInUser{OrgRole: org.RoleViewer, OrgId: 1} alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: viewerUser} err2 := store.HandleAlertsQuery(context.Background(), &alertQuery) @@ -172,7 +174,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { }) t.Run("Alerts should be updated", func(t *testing.T) { - query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &query) require.Nil(t, err2) @@ -221,7 +223,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { t.Run("Should save 3 dashboards", func(t *testing.T) { require.Nil(t, err) - queryForDashboard := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + queryForDashboard := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &queryForDashboard) require.Nil(t, err2) @@ -234,7 +236,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { err = store.SaveAlerts(context.Background(), testDash.Id, missingOneAlert) t.Run("should delete the missing alert", func(t *testing.T) { - query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &query) require.Nil(t, err2) require.Equal(t, 2, len(query.Result)) @@ -264,7 +266,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) { require.Nil(t, err) t.Run("Alerts should be removed", func(t *testing.T) { - query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := store.HandleAlertsQuery(context.Background(), &query) require.Nil(t, err2) @@ -291,7 +293,7 @@ func TestIntegrationPausingAlerts(t *testing.T) { stateDateAfterPause := stateDateBeforePause // Get alert so we can use its ID in tests - alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}} + alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}} err2 := sqlStore.HandleAlertsQuery(context.Background(), &alertQuery) require.Nil(t, err2) diff --git a/pkg/services/alerting/test_rule.go b/pkg/services/alerting/test_rule.go index acb1db2a960..cce5128c015 100644 --- a/pkg/services/alerting/test_rule.go +++ b/pkg/services/alerting/test_rule.go @@ -6,10 +6,11 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // AlertTest makes a test alert. -func (e *AlertEngine) AlertTest(orgID int64, dashboard *simplejson.Json, panelID int64, user *models.SignedInUser) (*EvalContext, error) { +func (e *AlertEngine) AlertTest(orgID int64, dashboard *simplejson.Json, panelID int64, user *user.SignedInUser) (*EvalContext, error) { dash := models.NewDashboardFromJson(dashboard) dashInfo := DashAlertInfo{ User: user, diff --git a/pkg/services/annotations/annotations.go b/pkg/services/annotations/annotations.go index 4e1f07f2d75..7c40c18e7da 100644 --- a/pkg/services/annotations/annotations.go +++ b/pkg/services/annotations/annotations.go @@ -5,7 +5,7 @@ import ( "errors" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -39,7 +39,7 @@ type ItemQuery struct { Tags []string `json:"tags"` Type string `json:"type"` MatchAny bool `json:"matchAny"` - SignedInUser *models.SignedInUser + SignedInUser *user.SignedInUser Limit int64 `json:"limit"` } diff --git a/pkg/services/apikey/apikeyimpl/store_test.go b/pkg/services/apikey/apikeyimpl/store_test.go index 23cc044b60f..00e9cf71495 100644 --- a/pkg/services/apikey/apikeyimpl/store_test.go +++ b/pkg/services/apikey/apikeyimpl/store_test.go @@ -9,10 +9,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/apikey" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) func mockTimeNow() { @@ -141,7 +141,7 @@ func TestIntegrationApiKeyDataAccess(t *testing.T) { // advance mocked getTime by 1s timeNow() - testUser := &models.SignedInUser{ + testUser := &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{ 1: {accesscontrol.ActionAPIKeyRead: []string{accesscontrol.ScopeAPIKeysAll}}, @@ -208,7 +208,7 @@ func TestIntegrationApiKeyErrors(t *testing.T) { type getApiKeysTestCase struct { desc string - user *models.SignedInUser + user *user.SignedInUser expectedNumKeys int } @@ -219,21 +219,21 @@ func TestIntegrationSQLStore_GetAPIKeys(t *testing.T) { tests := []getApiKeysTestCase{ { desc: "expect all keys for wildcard scope", - user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ + user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ 1: {"apikeys:read": {"apikeys:*"}}, }}, expectedNumKeys: 10, }, { desc: "expect only api keys that user have scopes for", - user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ + user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ 1: {"apikeys:read": {"apikeys:id:1", "apikeys:id:3"}}, }}, expectedNumKeys: 2, }, { desc: "expect no keys when user have no scopes", - user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ + user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{ 1: {"apikeys:read": {}}, }}, expectedNumKeys: 0, diff --git a/pkg/services/apikey/model.go b/pkg/services/apikey/model.go index 4d5fcc30d73..22fbc8ad2a4 100644 --- a/pkg/services/apikey/model.go +++ b/pkg/services/apikey/model.go @@ -4,7 +4,8 @@ import ( "errors" "time" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/services/user" ) var ( @@ -19,7 +20,7 @@ type APIKey struct { OrgId int64 Name string Key string - Role models.RoleType + Role org.RoleType Created time.Time Updated time.Time LastUsedAt *time.Time `xorm:"last_used_at"` @@ -31,12 +32,12 @@ func (k APIKey) TableName() string { return "api_key" } // swagger:model type AddCommand struct { - Name string `json:"name" binding:"Required"` - Role models.RoleType `json:"role" binding:"Required"` - OrgId int64 `json:"-"` - Key string `json:"-"` - SecondsToLive int64 `json:"secondsToLive"` - Result *APIKey `json:"-"` + Name string `json:"name" binding:"Required"` + Role org.RoleType `json:"role" binding:"Required"` + OrgId int64 `json:"-"` + Key string `json:"-"` + SecondsToLive int64 `json:"secondsToLive"` + Result *APIKey `json:"-"` } type DeleteCommand struct { @@ -47,7 +48,7 @@ type DeleteCommand struct { type GetApiKeysQuery struct { OrgId int64 IncludeExpired bool - User *models.SignedInUser + User *user.SignedInUser Result []*APIKey } type GetByNameQuery struct { diff --git a/pkg/services/comments/commentmodel/permissions.go b/pkg/services/comments/commentmodel/permissions.go index 8b0ea7af4b0..d8a5f009d98 100644 --- a/pkg/services/comments/commentmodel/permissions.go +++ b/pkg/services/comments/commentmodel/permissions.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) type PermissionChecker struct { @@ -42,7 +43,7 @@ func (c *PermissionChecker) getDashboardById(ctx context.Context, orgID int64, i return query.Result, nil } -func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int64, signedInUser *models.SignedInUser, objectType string, objectID string) (bool, error) { +func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int64, signedInUser *user.SignedInUser, objectType string, objectID string) (bool, error) { switch objectType { case ObjectTypeOrg: return false, nil @@ -89,7 +90,7 @@ func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int6 return true, nil } -func (c *PermissionChecker) CheckWritePermissions(ctx context.Context, orgId int64, signedInUser *models.SignedInUser, objectType string, objectID string) (bool, error) { +func (c *PermissionChecker) CheckWritePermissions(ctx context.Context, orgId int64, signedInUser *user.SignedInUser, objectType string, objectID string) (bool, error) { switch objectType { case ObjectTypeOrg: return false, nil diff --git a/pkg/services/comments/handlers.go b/pkg/services/comments/handlers.go index c98fd691944..6a7db7be3c6 100644 --- a/pkg/services/comments/handlers.go +++ b/pkg/services/comments/handlers.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/comments/commentmodel" + "github.com/grafana/grafana/pkg/services/user" ) func commentsToDto(items []*commentmodel.Comment, userMap map[int64]*commentmodel.CommentUser) []*commentmodel.CommentDto { @@ -86,7 +87,7 @@ type CreateCmd struct { var ErrPermissionDenied = errors.New("permission denied") -func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, cmd CreateCmd) (*commentmodel.CommentDto, error) { +func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, cmd CreateCmd) (*commentmodel.CommentDto, error) { ok, err := s.permissions.CheckWritePermissions(ctx, orgID, signedInUser, cmd.ObjectType, cmd.ObjectID) if err != nil { return nil, err @@ -120,7 +121,7 @@ func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *models. return mDto, nil } -func (s *Service) Get(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, cmd GetCmd) ([]*commentmodel.CommentDto, error) { +func (s *Service) Get(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, cmd GetCmd) ([]*commentmodel.CommentDto, error) { ok, err := s.permissions.CheckReadPermissions(ctx, orgID, signedInUser, cmd.ObjectType, cmd.ObjectID) if err != nil { return nil, err diff --git a/pkg/services/contexthandler/auth_proxy_test.go b/pkg/services/contexthandler/auth_proxy_test.go index 324bc7a42b0..033f9d34a00 100644 --- a/pkg/services/contexthandler/auth_proxy_test.go +++ b/pkg/services/contexthandler/auth_proxy_test.go @@ -99,7 +99,7 @@ func (f *FakeGetSignUserStore) GetSignedInUser(ctx context.Context, query *model return user.ErrUserNotFound } - query.Result = &models.SignedInUser{ + query.Result = &user.SignedInUser{ UserId: userID, OrgId: orgID, } diff --git a/pkg/services/contexthandler/authproxy/authproxy.go b/pkg/services/contexthandler/authproxy/authproxy.go index 8b03e8f2171..184c12ab234 100644 --- a/pkg/services/contexthandler/authproxy/authproxy.go +++ b/pkg/services/contexthandler/authproxy/authproxy.go @@ -19,7 +19,9 @@ 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/setting" "github.com/grafana/grafana/pkg/util" ) @@ -284,9 +286,9 @@ func (auth *AuthProxy) loginViaHeader(reqCtx *models.ReqContext) (int64, error) case "Role": // If Role header is specified, we update the user role of the default org if header != "" { - rt := models.RoleType(header) + rt := org.RoleType(header) if rt.IsValid() { - extUser.OrgRoles = map[int64]models.RoleType{} + extUser.OrgRoles = map[int64]org.RoleType{} orgID := int64(1) if setting.AutoAssignOrg && setting.AutoAssignOrgId > 0 { orgID = int64(setting.AutoAssignOrgId) @@ -344,7 +346,7 @@ func (auth *AuthProxy) headersIterator(reqCtx *models.ReqContext, fn func(field } // GetSignedInUser gets full signed in user info. -func (auth *AuthProxy) GetSignedInUser(userID int64, orgID int64) (*models.SignedInUser, error) { +func (auth *AuthProxy) GetSignedInUser(userID int64, orgID int64) (*user.SignedInUser, error) { query := &models.GetSignedInUserQuery{ OrgId: orgID, UserId: userID, diff --git a/pkg/services/contexthandler/contexthandler.go b/pkg/services/contexthandler/contexthandler.go index 71a99ea83e4..4b6fbfded02 100644 --- a/pkg/services/contexthandler/contexthandler.go +++ b/pkg/services/contexthandler/contexthandler.go @@ -23,6 +23,7 @@ import ( "github.com/grafana/grafana/pkg/services/contexthandler/authproxy" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" @@ -96,7 +97,7 @@ func (h *ContextHandler) Middleware(mContext *web.Context) { reqContext := &models.ReqContext{ Context: mContext, - SignedInUser: &models.SignedInUser{}, + SignedInUser: &user.SignedInUser{}, IsSignedIn: false, AllowAnonymous: false, SkipCache: false, @@ -177,7 +178,7 @@ func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqCont _, span := h.tracer.Start(reqContext.Req.Context(), "initContextWithAnonymousUser") defer span.End() - org, err := h.SQLStore.GetOrgByName(h.Cfg.AnonymousOrgName) + orga, err := h.SQLStore.GetOrgByName(h.Cfg.AnonymousOrgName) if err != nil { reqContext.Logger.Error("Anonymous access organization error.", "org_name", h.Cfg.AnonymousOrgName, "error", err) return false @@ -185,10 +186,10 @@ func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqCont reqContext.IsSignedIn = false reqContext.AllowAnonymous = true - reqContext.SignedInUser = &models.SignedInUser{IsAnonymous: true} - reqContext.OrgRole = models.RoleType(h.Cfg.AnonymousOrgRole) - reqContext.OrgId = org.Id - reqContext.OrgName = org.Name + reqContext.SignedInUser = &user.SignedInUser{IsAnonymous: true} + reqContext.OrgRole = org.RoleType(h.Cfg.AnonymousOrgRole) + reqContext.OrgId = orga.Id + reqContext.OrgName = orga.Name return true } @@ -288,7 +289,7 @@ func (h *ContextHandler) initContextWithAPIKey(reqContext *models.ReqContext) bo if apikey.ServiceAccountId == nil || *apikey.ServiceAccountId < 1 { //There is no service account attached to the apikey //Use the old APIkey method. This provides backwards compatibility. - reqContext.SignedInUser = &models.SignedInUser{} + reqContext.SignedInUser = &user.SignedInUser{} reqContext.OrgRole = apikey.Role reqContext.ApiKeyId = apikey.Id reqContext.OrgId = apikey.OrgId @@ -466,10 +467,10 @@ func (h *ContextHandler) initContextWithRenderAuth(reqContext *models.ReqContext return true } - reqContext.SignedInUser = &models.SignedInUser{ + reqContext.SignedInUser = &user.SignedInUser{ OrgId: renderUser.OrgID, UserId: renderUser.UserID, - OrgRole: models.RoleType(renderUser.OrgRole), + OrgRole: org.RoleType(renderUser.OrgRole), } // UserID can be 0 for background tasks and, in this case, there is no user info to retrieve diff --git a/pkg/services/dashboardimport/api/api_test.go b/pkg/services/dashboardimport/api/api_test.go index 935f0ef59b3..9fd5f0f162e 100644 --- a/pkg/services/dashboardimport/api/api_test.go +++ b/pkg/services/dashboardimport/api/api_test.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/models" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/dashboardimport" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web/webtest" "github.com/stretchr/testify/require" ) @@ -50,7 +51,7 @@ func TestImportDashboardAPI(t *testing.T) { jsonBytes, err := json.Marshal(cmd) require.NoError(t, err) req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes)) - webtest.RequestWithSignedInUser(req, &models.SignedInUser{ + webtest.RequestWithSignedInUser(req, &user.SignedInUser{ UserId: 1, }) resp, err := s.SendJSON(req) @@ -66,7 +67,7 @@ func TestImportDashboardAPI(t *testing.T) { jsonBytes, err := json.Marshal(cmd) require.NoError(t, err) req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes)) - webtest.RequestWithSignedInUser(req, &models.SignedInUser{ + webtest.RequestWithSignedInUser(req, &user.SignedInUser{ UserId: 1, }) resp, err := s.SendJSON(req) @@ -83,7 +84,7 @@ func TestImportDashboardAPI(t *testing.T) { jsonBytes, err := json.Marshal(cmd) require.NoError(t, err) req := s.NewPostRequest("/api/dashboards/import?trimdefaults=true", bytes.NewReader(jsonBytes)) - webtest.RequestWithSignedInUser(req, &models.SignedInUser{ + webtest.RequestWithSignedInUser(req, &user.SignedInUser{ UserId: 1, }) resp, err := s.SendJSON(req) @@ -115,7 +116,7 @@ func TestImportDashboardAPI(t *testing.T) { jsonBytes, err := json.Marshal(cmd) require.NoError(t, err) req := s.NewPostRequest("/api/dashboards/import?trimdefaults=true", bytes.NewReader(jsonBytes)) - webtest.RequestWithSignedInUser(req, &models.SignedInUser{ + webtest.RequestWithSignedInUser(req, &user.SignedInUser{ UserId: 1, }) resp, err := s.SendJSON(req) @@ -141,7 +142,7 @@ func TestImportDashboardAPI(t *testing.T) { jsonBytes, err := json.Marshal(cmd) require.NoError(t, err) req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes)) - webtest.RequestWithSignedInUser(req, &models.SignedInUser{ + webtest.RequestWithSignedInUser(req, &user.SignedInUser{ UserId: 1, }) resp, err := s.SendJSON(req) diff --git a/pkg/services/dashboardimport/dashboardimport.go b/pkg/services/dashboardimport/dashboardimport.go index 86d80064a15..5f270d50366 100644 --- a/pkg/services/dashboardimport/dashboardimport.go +++ b/pkg/services/dashboardimport/dashboardimport.go @@ -4,7 +4,7 @@ import ( "context" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // ImportDashboardInput definition of input parameters when importing a dashboard. @@ -25,7 +25,7 @@ type ImportDashboardRequest struct { FolderId int64 `json:"folderId"` FolderUid string `json:"folderUid"` - User *models.SignedInUser `json:"-"` + User *user.SignedInUser `json:"-"` } // ImportDashboardResponse response object returned when importing a dashboard. diff --git a/pkg/services/dashboardimport/service/service_test.go b/pkg/services/dashboardimport/service/service_test.go index 1211f4e5b87..39f15f329a0 100644 --- a/pkg/services/dashboardimport/service/service_test.go +++ b/pkg/services/dashboardimport/service/service_test.go @@ -11,7 +11,9 @@ import ( "github.com/grafana/grafana/pkg/services/dashboardimport" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/librarypanels" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/plugindashboards" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -42,11 +44,11 @@ func TestImportDashboardService(t *testing.T) { importLibraryPanelsForDashboard := false connectLibraryPanelsForDashboardCalled := false libraryPanelService := &libraryPanelServiceMock{ - importLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { + importLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { importLibraryPanelsForDashboard = true return nil }, - connectLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error { + connectLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error { connectLibraryPanelsForDashboardCalled = true return nil }, @@ -63,7 +65,7 @@ func TestImportDashboardService(t *testing.T) { Inputs: []dashboardimport.ImportDashboardInput{ {Name: "*", Type: "datasource", Value: "prom"}, }, - User: &models.SignedInUser{UserId: 2, OrgRole: models.ROLE_ADMIN, OrgId: 3}, + User: &user.SignedInUser{UserId: 2, OrgRole: org.RoleAdmin, OrgId: 3}, FolderId: 5, } resp, err := s.ImportDashboard(context.Background(), req) @@ -120,7 +122,7 @@ func TestImportDashboardService(t *testing.T) { Inputs: []dashboardimport.ImportDashboardInput{ {Name: "*", Type: "datasource", Value: "prom"}, }, - User: &models.SignedInUser{UserId: 2, OrgRole: models.ROLE_ADMIN, OrgId: 3}, + User: &user.SignedInUser{UserId: 2, OrgRole: org.RoleAdmin, OrgId: 3}, FolderId: 5, } resp, err := s.ImportDashboard(context.Background(), req) @@ -185,11 +187,11 @@ func (s *dashboardServiceMock) ImportDashboard(ctx context.Context, dto *dashboa type libraryPanelServiceMock struct { librarypanels.Service - connectLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error - importLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error + connectLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error + importLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error } -func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error { +func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error { if s.connectLibraryPanelsForDashboardFunc != nil { return s.connectLibraryPanelsForDashboardFunc(ctx, signedInUser, dash) } @@ -197,7 +199,7 @@ func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.C return nil } -func (s *libraryPanelServiceMock) ImportLibraryPanelsForDashboard(ctx context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { +func (s *libraryPanelServiceMock) ImportLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { if s.importLibraryPanelsForDashboardFunc != nil { return s.importLibraryPanelsForDashboardFunc(ctx, signedInUser, libraryPanels, panels, folderID) } diff --git a/pkg/services/dashboards/database/acl.go b/pkg/services/dashboards/database/acl.go index 2ac86a8aa31..702b705bf47 100644 --- a/pkg/services/dashboards/database/acl.go +++ b/pkg/services/dashboards/database/acl.go @@ -4,6 +4,7 @@ import ( "context" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" ) @@ -97,7 +98,7 @@ func (d *DashboardStore) GetDashboardACLInfoList(ctx context.Context, query *mod // HasEditPermissionInFolders validates that an user have access to a certain folder func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error { return d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error { - if query.SignedInUser.HasRole(models.ROLE_EDITOR) { + if query.SignedInUser.HasRole(org.RoleEditor) { query.Result = true return nil } @@ -125,7 +126,7 @@ func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query * func (d *DashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error { return d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error { - if query.SignedInUser.HasRole(models.ROLE_ADMIN) { + if query.SignedInUser.HasRole(org.RoleAdmin) { query.Result = true return nil } diff --git a/pkg/services/dashboards/database/acl_test.go b/pkg/services/dashboards/database/acl_test.go index 31a861d3845..81ad636de7e 100644 --- a/pkg/services/dashboards/database/acl_test.go +++ b/pkg/services/dashboards/database/acl_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" @@ -47,10 +48,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) { require.Equal(t, 2, len(query.Result)) defaultPermissionsId := int64(-1) require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId) - require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role) + require.Equal(t, org.RoleViewer, *query.Result[0].Role) require.False(t, query.Result[0].Inherited) require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId) - require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role) + require.Equal(t, org.RoleEditor, *query.Result[1].Role) require.False(t, query.Result[1].Inherited) }) @@ -64,10 +65,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) { require.Equal(t, 2, len(query.Result)) defaultPermissionsId := int64(-1) require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId) - require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role) + require.Equal(t, org.RoleViewer, *query.Result[0].Role) require.True(t, query.Result[0].Inherited) require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId) - require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role) + require.Equal(t, org.RoleEditor, *query.Result[1].Role) require.True(t, query.Result[1].Inherited) }) @@ -146,10 +147,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) { defaultPermissionsId := int64(-1) require.Equal(t, 3, len(query.Result)) require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId) - require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role) + require.Equal(t, org.RoleViewer, *query.Result[0].Role) require.True(t, query.Result[0].Inherited) require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId) - require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role) + require.Equal(t, org.RoleEditor, *query.Result[1].Role) require.True(t, query.Result[1].Inherited) require.Equal(t, childDash.Id, query.Result[2].DashboardId) require.False(t, query.Result[2].Inherited) @@ -241,10 +242,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) { require.Equal(t, 2, len(query.Result)) defaultPermissionsId := int64(-1) require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId) - require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role) + require.Equal(t, org.RoleViewer, *query.Result[0].Role) require.False(t, query.Result[0].Inherited) require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId) - require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role) + require.Equal(t, org.RoleEditor, *query.Result[1].Role) require.False(t, query.Result[1].Inherited) }) @@ -266,6 +267,6 @@ func createUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role str q1 := models.GetUserOrgListQuery{UserId: currentUser.ID} err = sqlStore.GetUserOrgList(context.Background(), &q1) require.NoError(t, err) - require.Equal(t, models.RoleType(role), q1.Result[0].Role) + require.Equal(t, org.RoleType(role), q1.Result[0].Role) return *currentUser } diff --git a/pkg/services/dashboards/database/database_folder_test.go b/pkg/services/dashboards/database/database_folder_test.go index 15e6ff2d7ee..cbd5e202f0d 100644 --- a/pkg/services/dashboards/database/database_folder_test.go +++ b/pkg/services/dashboards/database/database_folder_test.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" "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" ) @@ -43,7 +44,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("and no acls are set", func(t *testing.T) { t.Run("should return all dashboards", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id}, } @@ -67,7 +68,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should not return folder", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id}, } err := testSearchDashboards(dashboardStore, query) @@ -85,7 +86,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should be able to access folder", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id}, } @@ -100,10 +101,10 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("when the user is an admin", func(t *testing.T) { t.Run("should be able to access folder", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ UserId: currentUser.ID, OrgId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id}, @@ -128,7 +129,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should not return folder or child", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}, } err := testSearchDashboards(dashboardStore, query) require.NoError(t, err) @@ -143,7 +144,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { require.NoError(t, err) t.Run("should be able to search for child dashboard but not folder", func(t *testing.T) { - query := &models.FindPersistedDashboardsQuery{SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}} + query := &models.FindPersistedDashboardsQuery{SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}} err := testSearchDashboards(dashboardStore, query) require.NoError(t, err) require.Equal(t, len(query.Result), 2) @@ -155,10 +156,10 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("when the user is an admin", func(t *testing.T) { t.Run("should be able to search for child dash and folder", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ UserId: currentUser.ID, OrgId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id, childDash.Id}, @@ -197,8 +198,8 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should return dashboards in root and expanded folder", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ FolderIds: []int64{ - rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.ID, - OrgId: 1, OrgRole: models.ROLE_VIEWER, + rootFolderId, folder1.Id}, SignedInUser: &user.SignedInUser{UserId: currentUser.ID, + OrgId: 1, OrgRole: org.RoleViewer, }, OrgId: 1, } @@ -224,7 +225,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should not return folder with acl or its children", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder1.Id, childDash1.Id, childDash2.Id, dashInRoot.Id}, } @@ -240,7 +241,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should return folder without acl and its children", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id}, } @@ -264,7 +265,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should return folder without acl but not the dashboard with acl", func(t *testing.T) { query := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id}, } @@ -302,7 +303,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("Should have write access to all dashboard folders in their org", func(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgRole: models.ROLE_ADMIN, OrgId: 1}, + SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgRole: org.RoleAdmin, OrgId: 1}, Permission: models.PERMISSION_VIEW, Type: "dash-folder", } @@ -317,7 +318,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should have edit permission in folders", func(t *testing.T) { query := &models.HasEditPermissionInFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN}, + SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleAdmin}, } err := dashboardStore.HasEditPermissionInFolders(context.Background(), query) require.NoError(t, err) @@ -326,7 +327,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should have admin permission in folders", func(t *testing.T) { query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN}, + SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleAdmin}, } err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query) require.NoError(t, err) @@ -337,7 +338,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("Editor users", func(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgRole: models.ROLE_EDITOR, OrgId: 1}, + SignedInUser: &user.SignedInUser{UserId: editorUser.ID, OrgRole: org.RoleEditor, OrgId: 1}, Permission: models.PERMISSION_EDIT, } @@ -365,7 +366,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should have edit permission in folders", func(t *testing.T) { query := &models.HasEditPermissionInFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR}, + SignedInUser: &user.SignedInUser{UserId: editorUser.ID, OrgId: 1, OrgRole: org.RoleEditor}, } err := dashboardStore.HasEditPermissionInFolders(context.Background(), query) go require.NoError(t, err) @@ -374,7 +375,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should not have admin permission in folders", func(t *testing.T) { query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR}, + SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleEditor}, } err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query) require.NoError(t, err) @@ -385,7 +386,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("Viewer users", func(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgRole: models.ROLE_VIEWER, OrgId: 1}, + SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgRole: org.RoleViewer, OrgId: 1}, Permission: models.PERMISSION_EDIT, } @@ -413,7 +414,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { setup3() query := &models.HasEditPermissionInFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, } err := dashboardStore.HasEditPermissionInFolders(context.Background(), query) go require.NoError(t, err) @@ -422,7 +423,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should not have admin permission in folders", func(t *testing.T) { query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, } err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query) require.NoError(t, err) @@ -437,7 +438,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should have edit permission in folders", func(t *testing.T) { query := &models.HasEditPermissionInFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, } err := dashboardStore.HasEditPermissionInFolders(context.Background(), query) go require.NoError(t, err) @@ -453,7 +454,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("should have edit permission in folders", func(t *testing.T) { query := &models.HasEditPermissionInFoldersQuery{ - SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, + SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, } err := dashboardStore.HasEditPermissionInFolders(context.Background(), query) go require.NoError(t, err) diff --git a/pkg/services/dashboards/database/database_test.go b/pkg/services/dashboards/database/database_test.go index f9fecec199d..ea641ac75b0 100644 --- a/pkg/services/dashboards/database/database_test.go +++ b/pkg/services/dashboards/database/database_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "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/services/sqlstore/searchstore" "github.com/grafana/grafana/pkg/services/star" @@ -239,7 +240,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, FolderIds: []int64{savedFolder.Id}, - SignedInUser: &models.SignedInUser{}, + SignedInUser: &user.SignedInUser{}, } res, err := dashboardStore.FindDashboards(context.Background(), &query) @@ -306,9 +307,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { query := models.FindPersistedDashboardsQuery{ Title: "1 test dash folder", OrgId: 1, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionFoldersRead: []string{dashboards.ScopeFoldersAll}}, }, @@ -330,9 +331,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, Limit: 1, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionFoldersRead: []string{dashboards.ScopeFoldersAll}}, }, @@ -352,9 +353,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { OrgId: 1, Limit: 1, Page: 2, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: { dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}, @@ -377,9 +378,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { OrgId: 1, Type: "dash-db", Tags: []string{"prod"}, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -398,9 +399,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { query := models.FindPersistedDashboardsQuery{ OrgId: 1, FolderIds: []int64{savedFolder.Id}, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -424,9 +425,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { setup() query := models.FindPersistedDashboardsQuery{ DashboardIds: []int64{savedDash.Id, savedDash2.Id}, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -461,10 +462,10 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { require.NoError(t, err) query := models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ UserId: 10, OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -513,10 +514,10 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) { assert.NotZero(t, dashA.Id) assert.Less(t, dashB.Id, dashA.Id) qNoSort := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -529,10 +530,10 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) { assert.Equal(t, dashB.Id, results[1].ID) qSort := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -559,10 +560,10 @@ func TestIntegrationDashboard_Filter(t *testing.T) { insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false) dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false) qNoFilter := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -573,10 +574,10 @@ func TestIntegrationDashboard_Filter(t *testing.T) { require.Len(t, results, 2) qFilter := &models.FindPersistedDashboardsQuery{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{ 1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}}, }, @@ -678,7 +679,7 @@ func CreateUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role str q1 := models.GetUserOrgListQuery{UserId: currentUser.ID} err = sqlStore.GetUserOrgList(context.Background(), &q1) require.NoError(t, err) - require.Equal(t, models.RoleType(role), q1.Result[0].Role) + require.Equal(t, org.RoleType(role), q1.Result[0].Role) return *currentUser } diff --git a/pkg/services/dashboards/folder.go b/pkg/services/dashboards/folder.go index 42660db3f76..df95bb01c16 100644 --- a/pkg/services/dashboards/folder.go +++ b/pkg/services/dashboards/folder.go @@ -4,17 +4,18 @@ import ( "context" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) //go:generate mockery --name FolderService --structname FakeFolderService --inpackage --filename folder_service_mock.go // FolderService is a service for operating on folders. type FolderService interface { - GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) - GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) - GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) - GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error) - CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) - UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error - DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) + GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) + GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) + GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) + GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) + CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) + UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error + DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error } diff --git a/pkg/services/dashboards/folder_service_mock.go b/pkg/services/dashboards/folder_service_mock.go index 17f830cf8a9..aaa0499a496 100644 --- a/pkg/services/dashboards/folder_service_mock.go +++ b/pkg/services/dashboards/folder_service_mock.go @@ -6,6 +6,7 @@ import ( context "context" models "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" mock "github.com/stretchr/testify/mock" testing "testing" @@ -17,12 +18,12 @@ type FakeFolderService struct { } // CreateFolder provides a mock function with given fields: ctx, user, orgID, title, uid -func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title string, uid string) (*models.Folder, error) { - ret := _m.Called(ctx, user, orgID, title, uid) +func (_m *FakeFolderService) CreateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, title string, uid string) (*models.Folder, error) { + ret := _m.Called(ctx, usr, orgID, title, uid) var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, string) *models.Folder); ok { - r0 = rf(ctx, user, orgID, title, uid) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, string) *models.Folder); ok { + r0 = rf(ctx, usr, orgID, title, uid) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*models.Folder) @@ -30,8 +31,8 @@ func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.Sign } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string, string) error); ok { - r1 = rf(ctx, user, orgID, title, uid) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, string) error); ok { + r1 = rf(ctx, usr, orgID, title, uid) } else { r1 = ret.Error(1) } @@ -40,12 +41,12 @@ func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.Sign } // DeleteFolder provides a mock function with given fields: ctx, user, orgID, uid, forceDeleteRules -func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { - ret := _m.Called(ctx, user, orgID, uid, forceDeleteRules) +func (_m *FakeFolderService) DeleteFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { + ret := _m.Called(ctx, usr, orgID, uid, forceDeleteRules) var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, bool) *models.Folder); ok { - r0 = rf(ctx, user, orgID, uid, forceDeleteRules) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, bool) *models.Folder); ok { + r0 = rf(ctx, usr, orgID, uid, forceDeleteRules) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*models.Folder) @@ -53,8 +54,8 @@ func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.Sign } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string, bool) error); ok { - r1 = rf(ctx, user, orgID, uid, forceDeleteRules) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, bool) error); ok { + r1 = rf(ctx, usr, orgID, uid, forceDeleteRules) } else { r1 = ret.Error(1) } @@ -63,12 +64,12 @@ func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.Sign } // GetFolderByID provides a mock function with given fields: ctx, user, id, orgID -func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) { - ret := _m.Called(ctx, user, id, orgID) +func (_m *FakeFolderService) GetFolderByID(ctx context.Context, usr *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { + ret := _m.Called(ctx, usr, id, orgID) var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, int64) *models.Folder); ok { - r0 = rf(ctx, user, id, orgID) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64) *models.Folder); ok { + r0 = rf(ctx, usr, id, orgID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*models.Folder) @@ -76,8 +77,8 @@ func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.Sig } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, int64) error); ok { - r1 = rf(ctx, user, id, orgID) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64) error); ok { + r1 = rf(ctx, usr, id, orgID) } else { r1 = ret.Error(1) } @@ -86,12 +87,12 @@ func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.Sig } // GetFolderByTitle provides a mock function with given fields: ctx, user, orgID, title -func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error) { - ret := _m.Called(ctx, user, orgID, title) +func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, usr *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { + ret := _m.Called(ctx, usr, orgID, title) var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string) *models.Folder); ok { - r0 = rf(ctx, user, orgID, title) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok { + r0 = rf(ctx, usr, orgID, title) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*models.Folder) @@ -99,8 +100,8 @@ func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models. } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string) error); ok { - r1 = rf(ctx, user, orgID, title) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok { + r1 = rf(ctx, usr, orgID, title) } else { r1 = ret.Error(1) } @@ -109,12 +110,12 @@ func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models. } // GetFolderByUID provides a mock function with given fields: ctx, user, orgID, uid -func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) { - ret := _m.Called(ctx, user, orgID, uid) +func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { + ret := _m.Called(ctx, usr, orgID, uid) var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string) *models.Folder); ok { - r0 = rf(ctx, user, orgID, uid) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok { + r0 = rf(ctx, usr, orgID, uid) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*models.Folder) @@ -122,8 +123,8 @@ func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.Si } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string) error); ok { - r1 = rf(ctx, user, orgID, uid) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok { + r1 = rf(ctx, usr, orgID, uid) } else { r1 = ret.Error(1) } @@ -132,12 +133,12 @@ func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.Si } // GetFolders provides a mock function with given fields: ctx, user, orgID, limit, page -func (_m *FakeFolderService) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { - ret := _m.Called(ctx, user, orgID, limit, page) +func (_m *FakeFolderService) GetFolders(ctx context.Context, usr *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { + ret := _m.Called(ctx, usr, orgID, limit, page) var r0 []*models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, int64, int64) []*models.Folder); ok { - r0 = rf(ctx, user, orgID, limit, page) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64, int64) []*models.Folder); ok { + r0 = rf(ctx, usr, orgID, limit, page) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*models.Folder) @@ -145,8 +146,8 @@ func (_m *FakeFolderService) GetFolders(ctx context.Context, user *models.Signed } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, int64, int64) error); ok { - r1 = rf(ctx, user, orgID, limit, page) + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64, int64) error); ok { + r1 = rf(ctx, usr, orgID, limit, page) } else { r1 = ret.Error(1) } @@ -169,12 +170,12 @@ func (_m *FakeFolderService) MakeUserAdmin(ctx context.Context, orgID int64, use } // UpdateFolder provides a mock function with given fields: ctx, user, orgID, existingUid, cmd -func (_m *FakeFolderService) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { - ret := _m.Called(ctx, user, orgID, existingUid, cmd) +func (_m *FakeFolderService) UpdateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { + ret := _m.Called(ctx, usr, orgID, existingUid, cmd) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, *models.UpdateFolderCommand) error); ok { - r0 = rf(ctx, user, orgID, existingUid, cmd) + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, *models.UpdateFolderCommand) error); ok { + r0 = rf(ctx, usr, orgID, existingUid, cmd) } else { r0 = ret.Error(0) } diff --git a/pkg/services/dashboards/models.go b/pkg/services/dashboards/models.go index f2f3db9c2ac..5b2b08e2a3e 100644 --- a/pkg/services/dashboards/models.go +++ b/pkg/services/dashboards/models.go @@ -4,12 +4,13 @@ import ( "time" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) type SaveDashboardDTO struct { OrgId int64 UpdatedAt time.Time - User *models.SignedInUser + User *user.SignedInUser Message string Overwrite bool Dashboard *models.Dashboard diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index 1f896772e0b..9bec4a8fe22 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -15,6 +15,8 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" "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/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) @@ -216,9 +218,9 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt dto.Dashboard.Data.Set("refresh", setting.MinRefreshInterval) } - dto.User = &models.SignedInUser{ + dto.User = &user.SignedInUser{ UserId: 0, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, OrgId: dto.OrgId, Permissions: map[int64]map[string][]string{ dto.OrgId: provisionerPermissions, @@ -266,9 +268,9 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt } func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) { - dto.User = &models.SignedInUser{ + dto.User = &user.SignedInUser{ UserId: 0, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{dto.OrgId: provisionerPermissions}, } cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, false, false) @@ -368,8 +370,8 @@ func (dr *DashboardServiceImpl) GetDashboardByPublicUid(ctx context.Context, das } func (dr *DashboardServiceImpl) MakeUserAdmin(ctx context.Context, orgID int64, userID int64, dashboardID int64, setViewAndEditPermissions bool) error { - rtEditor := models.ROLE_EDITOR - rtViewer := models.ROLE_VIEWER + rtEditor := org.RoleEditor + rtViewer := org.RoleViewer items := []*models.DashboardACL{ { @@ -478,8 +480,8 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto * if !inFolder { permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ - {BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()}, - {BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()}, + {BuiltinRole: string(org.RoleEditor), Permission: models.PERMISSION_EDIT.String()}, + {BuiltinRole: string(org.RoleViewer), Permission: models.PERMISSION_VIEW.String()}, }...) } diff --git a/pkg/services/dashboards/service/dashboard_service_integration_test.go b/pkg/services/dashboards/service/dashboard_service_integration_test.go index 0e7e3a6fc01..912ea23f326 100644 --- a/pkg/services/dashboards/service/dashboard_service_integration_test.go +++ b/pkg/services/dashboards/service/dashboard_service_integration_test.go @@ -15,7 +15,9 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards/database" "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" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -916,9 +918,9 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto dto := dashboards.SaveDashboardDTO{ OrgId: orgID, Dashboard: cmd.GetDashboardModel(), - User: &models.SignedInUser{ + User: &user.SignedInUser{ UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, } @@ -953,9 +955,9 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore. dto := dashboards.SaveDashboardDTO{ OrgId: orgID, Dashboard: cmd.GetDashboardModel(), - User: &models.SignedInUser{ + User: &user.SignedInUser{ UserId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, } @@ -982,7 +984,7 @@ func toSaveDashboardDto(cmd models.SaveDashboardCommand) dashboards.SaveDashboar Dashboard: dash, Message: cmd.Message, OrgId: cmd.OrgId, - User: &models.SignedInUser{UserId: cmd.UserId}, + User: &user.SignedInUser{UserId: cmd.UserId}, Overwrite: cmd.Overwrite, } } diff --git a/pkg/services/dashboards/service/dashboard_service_test.go b/pkg/services/dashboards/service/dashboard_service_test.go index 0b730c5f53f..3b808eae961 100644 --- a/pkg/services/dashboards/service/dashboard_service_test.go +++ b/pkg/services/dashboards/service/dashboard_service_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/guardian" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -76,7 +77,7 @@ func TestDashboardService(t *testing.T) { for _, tc := range testCases { dto.Dashboard = models.NewDashboard("title") dto.Dashboard.SetUid(tc.Uid) - dto.User = &models.SignedInUser{} + dto.User = &user.SignedInUser{} if tc.Error == nil { fakeStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything).Return(true, nil).Once() @@ -92,7 +93,7 @@ func TestDashboardService(t *testing.T) { dto.Dashboard = models.NewDashboard("Dash") dto.Dashboard.SetId(3) - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} _, err := service.SaveDashboard(context.Background(), dto, false) require.Equal(t, err, dashboards.ErrDashboardCannotSaveProvisionedDashboard) }) @@ -103,7 +104,7 @@ func TestDashboardService(t *testing.T) { dto.Dashboard = models.NewDashboard("Dash") dto.Dashboard.SetId(3) - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} _, err := service.SaveDashboard(context.Background(), dto, true) require.NoError(t, err) }) @@ -129,7 +130,7 @@ func TestDashboardService(t *testing.T) { fakeStore.On("SaveAlerts", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("alert validation error")).Once() dto.Dashboard = models.NewDashboard("Dash") - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} _, err := service.SaveDashboard(context.Background(), dto, false) require.Error(t, err) require.Equal(t, err.Error(), "alert validation error") @@ -145,7 +146,7 @@ func TestDashboardService(t *testing.T) { dto.Dashboard = models.NewDashboard("Dash") dto.Dashboard.SetId(3) - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} _, err := service.SaveProvisionedDashboard(context.Background(), dto, nil) require.NoError(t, err) }) @@ -160,7 +161,7 @@ func TestDashboardService(t *testing.T) { dto.Dashboard = models.NewDashboard("Dash") dto.Dashboard.SetId(3) - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} dto.Dashboard.Data.Set("refresh", "1s") _, err := service.SaveProvisionedDashboard(context.Background(), dto, nil) require.NoError(t, err) @@ -177,7 +178,7 @@ func TestDashboardService(t *testing.T) { dto.Dashboard = models.NewDashboard("Dash") dto.Dashboard.SetId(3) - dto.User = &models.SignedInUser{UserId: 1} + dto.User = &user.SignedInUser{UserId: 1} _, err := service.ImportDashboard(context.Background(), dto) require.Equal(t, err, dashboards.ErrDashboardCannotSaveProvisionedDashboard) }) diff --git a/pkg/services/dashboards/service/folder_service.go b/pkg/services/dashboards/service/folder_service.go index e90adab6c24..f7160c5dc62 100644 --- a/pkg/services/dashboards/service/folder_service.go +++ b/pkg/services/dashboards/service/folder_service.go @@ -13,7 +13,9 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" "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/search" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -50,7 +52,7 @@ func ProvideFolderService( } } -func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { +func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { searchQuery := search.Query{ SignedInUser: user, DashboardIds: make([]int64, 0), @@ -79,7 +81,7 @@ func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *models.SignedI return folders, nil } -func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) { +func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { if id == 0 { return &models.Folder{Id: id, Title: "General"}, nil } @@ -99,7 +101,7 @@ func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *models.Sign return dashFolder, nil } -func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) { +func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid) if err != nil { return nil, err @@ -116,7 +118,7 @@ func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *models.Sig return dashFolder, nil } -func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error) { +func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { dashFolder, err := f.dashboardStore.GetFolderByTitle(ctx, orgID, title) if err != nil { return nil, err @@ -133,7 +135,7 @@ func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *models.S return dashFolder, nil } -func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) { +func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) { dashFolder := models.NewDashboardFolder(title) dashFolder.OrgId = orgID @@ -183,8 +185,8 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe } permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ - {BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()}, - {BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()}, + {BuiltinRole: string(org.RoleEditor), Permission: models.PERMISSION_EDIT.String()}, + {BuiltinRole: string(org.RoleViewer), Permission: models.PERMISSION_VIEW.String()}, }...) _, permissionErr = f.permissions.SetPermissions(ctx, orgID, folder.Uid, permissions...) @@ -199,7 +201,7 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe return folder, nil } -func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { +func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid} if _, err := f.dashboardStore.GetDashboard(ctx, &query); err != nil { return toFolderError(err) @@ -253,7 +255,7 @@ func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *models.Signe return nil } -func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { +func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid) if err != nil { return nil, err diff --git a/pkg/services/dashboards/service/folder_service_test.go b/pkg/services/dashboards/service/folder_service_test.go index 46c03f6830f..ef62b183663 100644 --- a/pkg/services/dashboards/service/folder_service_test.go +++ b/pkg/services/dashboards/service/folder_service_test.go @@ -16,12 +16,13 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) var orgID = int64(1) -var user = &models.SignedInUser{UserId: 1} +var usr = &user.SignedInUser{UserId: 1} func TestIntegrationProvideFolderService(t *testing.T) { if testing.Short() { @@ -76,24 +77,24 @@ func TestIntegrationFolderService(t *testing.T) { store.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(folder, nil) t.Run("When get folder by id should return access denied error", func(t *testing.T) { - _, err := service.GetFolderByID(context.Background(), user, folderId, orgID) + _, err := service.GetFolderByID(context.Background(), usr, folderId, orgID) require.Equal(t, err, dashboards.ErrFolderAccessDenied) }) t.Run("When get folder by id, with id = 0 should return default folder", func(t *testing.T) { - folder, err := service.GetFolderByID(context.Background(), user, 0, orgID) + folder, err := service.GetFolderByID(context.Background(), usr, 0, orgID) require.NoError(t, err) require.Equal(t, folder, &models.Folder{Id: 0, Title: "General"}) }) t.Run("When get folder by uid should return access denied error", func(t *testing.T) { - _, err := service.GetFolderByUID(context.Background(), user, orgID, folderUID) + _, err := service.GetFolderByUID(context.Background(), usr, orgID, folderUID) require.Equal(t, err, dashboards.ErrFolderAccessDenied) }) t.Run("When creating folder should return access denied error", func(t *testing.T) { store.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything).Return(true, nil).Times(2) - _, err := service.CreateFolder(context.Background(), user, orgID, folder.Title, folderUID) + _, err := service.CreateFolder(context.Background(), usr, orgID, folder.Title, folderUID) require.Equal(t, err, dashboards.ErrFolderAccessDenied) }) @@ -103,7 +104,7 @@ func TestIntegrationFolderService(t *testing.T) { folder.Result = models.NewDashboard("dashboard-test") folder.Result.IsFolder = true }).Return(&models.Dashboard{}, nil) - err := service.UpdateFolder(context.Background(), user, orgID, folderUID, &models.UpdateFolderCommand{ + err := service.UpdateFolder(context.Background(), usr, orgID, folderUID, &models.UpdateFolderCommand{ Uid: folderUID, Title: "Folder-TEST", }) @@ -111,7 +112,7 @@ func TestIntegrationFolderService(t *testing.T) { }) t.Run("When deleting folder by uid should return access denied error", func(t *testing.T) { - _, err := service.DeleteFolder(context.Background(), user, orgID, folderUID, false) + _, err := service.DeleteFolder(context.Background(), usr, orgID, folderUID, false) require.Error(t, err) require.Equal(t, err, dashboards.ErrFolderAccessDenied) }) @@ -134,7 +135,7 @@ func TestIntegrationFolderService(t *testing.T) { store.On("SaveDashboard", mock.Anything).Return(dash, nil).Once() store.On("GetFolderByID", mock.Anything, orgID, dash.Id).Return(f, nil) - actualFolder, err := service.CreateFolder(context.Background(), user, orgID, dash.Title, "") + actualFolder, err := service.CreateFolder(context.Background(), usr, orgID, dash.Title, "") require.NoError(t, err) require.Equal(t, f, actualFolder) }) @@ -143,7 +144,7 @@ func TestIntegrationFolderService(t *testing.T) { dash := models.NewDashboardFolder("Test-Folder") dash.Id = rand.Int63() - _, err := service.CreateFolder(context.Background(), user, orgID, dash.Title, "general") + _, err := service.CreateFolder(context.Background(), usr, orgID, dash.Title, "general") require.ErrorIs(t, err, dashboards.ErrFolderInvalidUID) }) @@ -162,7 +163,7 @@ func TestIntegrationFolderService(t *testing.T) { Title: "TEST-Folder", } - err := service.UpdateFolder(context.Background(), user, orgID, dashboardFolder.Uid, req) + err := service.UpdateFolder(context.Background(), usr, orgID, dashboardFolder.Uid, req) require.NoError(t, err) require.Equal(t, f, req.Result) }) @@ -179,7 +180,7 @@ func TestIntegrationFolderService(t *testing.T) { }).Return(nil).Once() expectedForceDeleteRules := rand.Int63()%2 == 0 - _, err := service.DeleteFolder(context.Background(), user, orgID, f.Uid, expectedForceDeleteRules) + _, err := service.DeleteFolder(context.Background(), usr, orgID, f.Uid, expectedForceDeleteRules) require.NoError(t, err) require.NotNil(t, actualCmd) require.Equal(t, f.Id, actualCmd.Id) @@ -202,7 +203,7 @@ func TestIntegrationFolderService(t *testing.T) { store.On("GetFolderByID", mock.Anything, orgID, expected.Id).Return(expected, nil) - actual, err := service.GetFolderByID(context.Background(), user, expected.Id, orgID) + actual, err := service.GetFolderByID(context.Background(), usr, expected.Id, orgID) require.Equal(t, expected, actual) require.NoError(t, err) }) @@ -213,7 +214,7 @@ func TestIntegrationFolderService(t *testing.T) { store.On("GetFolderByUID", mock.Anything, orgID, expected.Uid).Return(expected, nil) - actual, err := service.GetFolderByUID(context.Background(), user, orgID, expected.Uid) + actual, err := service.GetFolderByUID(context.Background(), usr, orgID, expected.Uid) require.Equal(t, expected, actual) require.NoError(t, err) }) @@ -223,7 +224,7 @@ func TestIntegrationFolderService(t *testing.T) { store.On("GetFolderByTitle", mock.Anything, orgID, expected.Title).Return(expected, nil) - actual, err := service.GetFolderByTitle(context.Background(), user, orgID, expected.Title) + actual, err := service.GetFolderByTitle(context.Background(), usr, orgID, expected.Title) require.Equal(t, expected, actual) require.NoError(t, err) }) diff --git a/pkg/services/dashboardsnapshots/database/database.go b/pkg/services/dashboardsnapshots/database/database.go index e4b00edf0db..ed794c9e632 100644 --- a/pkg/services/dashboardsnapshots/database/database.go +++ b/pkg/services/dashboardsnapshots/database/database.go @@ -6,8 +6,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/dashboardsnapshots" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/db" "github.com/grafana/grafana/pkg/setting" @@ -115,7 +115,7 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q // admins can see all snapshots, everyone else can only see their own snapshots switch { - case query.SignedInUser.OrgRole == models.ROLE_ADMIN: + case query.SignedInUser.OrgRole == org.RoleAdmin: sess.Where("org_id = ?", query.OrgId) case !query.SignedInUser.IsAnonymous: sess.Where("org_id = ? AND user_id = ?", query.OrgId, query.SignedInUser.UserId) diff --git a/pkg/services/dashboardsnapshots/database/database_test.go b/pkg/services/dashboardsnapshots/database/database_test.go index bf1af16a1a5..6b526327c8c 100644 --- a/pkg/services/dashboardsnapshots/database/database_test.go +++ b/pkg/services/dashboardsnapshots/database/database_test.go @@ -9,11 +9,12 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboardsnapshots" + "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/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -71,7 +72,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { t.Run("And the user has the admin role", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) @@ -85,7 +86,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { t.Run("And the user has the editor role and has created a snapshot", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, UserId: 1000}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserId: 1000}, } err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) @@ -99,7 +100,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { t.Run("And the user has the editor role and has not created any snapshot", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, UserId: 2}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserId: 2}, } err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) @@ -126,7 +127,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { t.Run("Should not return any snapshots", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, IsAnonymous: true, UserId: 0}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, IsAnonymous: true, UserId: 0}, } err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) @@ -167,7 +168,7 @@ func TestIntegrationDeleteExpiredSnapshots(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } err = dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) @@ -180,7 +181,7 @@ func TestIntegrationDeleteExpiredSnapshots(t *testing.T) { query = dashboardsnapshots.GetDashboardSnapshotsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}, + SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } err = dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) diff --git a/pkg/services/dashboardsnapshots/models.go b/pkg/services/dashboardsnapshots/models.go index 4feb21596ce..b527c6dcfc0 100644 --- a/pkg/services/dashboardsnapshots/models.go +++ b/pkg/services/dashboardsnapshots/models.go @@ -4,7 +4,7 @@ import ( "time" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // DashboardSnapshot model @@ -102,7 +102,7 @@ type GetDashboardSnapshotsQuery struct { Name string Limit int OrgId int64 - SignedInUser *models.SignedInUser + SignedInUser *user.SignedInUser Result DashboardSnapshotsList } diff --git a/pkg/services/datasources/datasources.go b/pkg/services/datasources/datasources.go index 1fb4695b2d3..03a55615a9e 100644 --- a/pkg/services/datasources/datasources.go +++ b/pkg/services/datasources/datasources.go @@ -7,7 +7,7 @@ import ( sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana/pkg/infra/httpclient" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // DataSourceService interface for interacting with datasources. @@ -59,8 +59,8 @@ type DataSourceService interface { // CacheService interface for retrieving a cached datasource. type CacheService interface { // GetDatasource gets a datasource identified by datasource numeric identifier. - GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*DataSource, error) + GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*DataSource, error) // GetDatasourceByUID gets a datasource identified by datasource unique identifier (UID). - GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*DataSource, error) + GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*DataSource, error) } diff --git a/pkg/services/datasources/fakes/fake_cache_service.go b/pkg/services/datasources/fakes/fake_cache_service.go index e09919158ad..ec5152e411d 100644 --- a/pkg/services/datasources/fakes/fake_cache_service.go +++ b/pkg/services/datasources/fakes/fake_cache_service.go @@ -3,8 +3,8 @@ package datasources import ( "context" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) type FakeCacheService struct { @@ -13,7 +13,7 @@ type FakeCacheService struct { var _ datasources.CacheService = &FakeCacheService{} -func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) { +func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { for _, datasource := range c.DataSources { if datasource.Id == datasourceID { return datasource, nil @@ -22,7 +22,7 @@ func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64 return nil, datasources.ErrDataSourceNotFound } -func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) { +func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { for _, datasource := range c.DataSources { if datasource.Uid == datasourceUID { return datasource, nil diff --git a/pkg/services/datasources/models.go b/pkg/services/datasources/models.go index 0afe05381f8..fd0f421cdf6 100644 --- a/pkg/services/datasources/models.go +++ b/pkg/services/datasources/models.go @@ -4,7 +4,7 @@ import ( "time" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) const ( @@ -156,7 +156,7 @@ type UpdateSecretFn func() error type GetDataSourcesQuery struct { OrgId int64 DataSourceLimit int - User *models.SignedInUser + User *user.SignedInUser Result []*DataSource } @@ -172,7 +172,7 @@ type GetDataSourcesByTypeQuery struct { type GetDefaultDataSourceQuery struct { OrgId int64 - User *models.SignedInUser + User *user.SignedInUser Result *DataSource } @@ -214,7 +214,7 @@ func (p DsPermissionType) String() string { } type DatasourcesPermissionFilterQuery struct { - User *models.SignedInUser + User *user.SignedInUser Datasources []*DataSource Result []*DataSource } diff --git a/pkg/services/datasources/permissions/datasource_permissions.go b/pkg/services/datasources/permissions/datasource_permissions.go index 428a1b2e6dd..6981392db1d 100644 --- a/pkg/services/datasources/permissions/datasource_permissions.go +++ b/pkg/services/datasources/permissions/datasource_permissions.go @@ -4,15 +4,15 @@ import ( "context" "errors" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) var ErrNotImplemented = errors.New("not implemented") type DatasourcePermissionsService interface { FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *datasources.DatasourcesPermissionFilterQuery) error - FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error) + FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error) } // dummy method @@ -20,7 +20,7 @@ func (hs *OSSDatasourcePermissionsService) FilterDatasourcesBasedOnQueryPermissi return ErrNotImplemented } -func (hs *OSSDatasourcePermissionsService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error) { +func (hs *OSSDatasourcePermissionsService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error) { return nil, ErrNotImplemented } diff --git a/pkg/services/datasources/permissions/datasource_permissions_mocks.go b/pkg/services/datasources/permissions/datasource_permissions_mocks.go index ef98a6dd1b7..ee122020eb4 100644 --- a/pkg/services/datasources/permissions/datasource_permissions_mocks.go +++ b/pkg/services/datasources/permissions/datasource_permissions_mocks.go @@ -3,8 +3,8 @@ package permissions import ( "context" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) type mockDatasourcePermissionService struct { @@ -13,7 +13,7 @@ type mockDatasourcePermissionService struct { ErrResult error } -func (m *mockDatasourcePermissionService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error) { +func (m *mockDatasourcePermissionService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error) { return m.DsUidResult, m.ErrResult } diff --git a/pkg/services/datasources/service/cache_service.go b/pkg/services/datasources/service/cache_service.go index 38327f7127f..690c3a19e4f 100644 --- a/pkg/services/datasources/service/cache_service.go +++ b/pkg/services/datasources/service/cache_service.go @@ -7,9 +7,9 @@ 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/datasources" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) const ( @@ -35,7 +35,7 @@ type CacheServiceImpl struct { func (dc *CacheServiceImpl) GetDatasource( ctx context.Context, datasourceID int64, - user *models.SignedInUser, + user *user.SignedInUser, skipCache bool, ) (*datasources.DataSource, error) { cacheKey := idKey(datasourceID) @@ -69,7 +69,7 @@ func (dc *CacheServiceImpl) GetDatasource( func (dc *CacheServiceImpl) GetDatasourceByUID( ctx context.Context, datasourceUID string, - user *models.SignedInUser, + user *user.SignedInUser, skipCache bool, ) (*datasources.DataSource, error) { if datasourceUID == "" { diff --git a/pkg/services/guardian/accesscontrol_guardian.go b/pkg/services/guardian/accesscontrol_guardian.go index db7f5d9ad75..87ff3f7be7e 100644 --- a/pkg/services/guardian/accesscontrol_guardian.go +++ b/pkg/services/guardian/accesscontrol_guardian.go @@ -7,7 +7,9 @@ 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/org" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -20,7 +22,7 @@ var permissionMap = map[string]models.PermissionType{ var _ DashboardGuardian = new(AccessControlDashboardGuardian) func NewAccessControlDashboardGuardian( - ctx context.Context, dashboardId int64, user *models.SignedInUser, + ctx context.Context, dashboardId int64, user *user.SignedInUser, store sqlstore.Store, ac accesscontrol.AccessControl, folderPermissionsService accesscontrol.FolderPermissionsService, dashboardPermissionsService accesscontrol.DashboardPermissionsService, @@ -44,7 +46,7 @@ type AccessControlDashboardGuardian struct { log log.Logger dashboardID int64 dashboard *models.Dashboard - user *models.SignedInUser + user *user.SignedInUser store sqlstore.Store ac accesscontrol.AccessControl folderPermissionsService accesscontrol.FolderPermissionsService @@ -182,9 +184,9 @@ func (a *AccessControlDashboardGuardian) GetACL() ([]*models.DashboardACLInfoDTO continue } - var role *models.RoleType + var role *org.RoleType if p.BuiltInRole != "" { - tmp := models.RoleType(p.BuiltInRole) + tmp := org.RoleType(p.BuiltInRole) role = &tmp } diff --git a/pkg/services/guardian/accesscontrol_guardian_test.go b/pkg/services/guardian/accesscontrol_guardian_test.go index 72b610d2074..9c48338ac78 100644 --- a/pkg/services/guardian/accesscontrol_guardian_test.go +++ b/pkg/services/guardian/accesscontrol_guardian_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -610,7 +611,7 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce if dashboardSvc == nil { dashboardSvc = &dashboards.FakeDashboardService{} } - return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, dashboardSvc), dash + return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &user.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, dashboardSvc), dash } func testDashSvc(t *testing.T) dashboards.DashboardService { diff --git a/pkg/services/guardian/guardian.go b/pkg/services/guardian/guardian.go index 5c9af681ecb..cfb4d2a14c9 100644 --- a/pkg/services/guardian/guardian.go +++ b/pkg/services/guardian/guardian.go @@ -7,7 +7,9 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "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/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -37,7 +39,7 @@ type DashboardGuardian interface { } type dashboardGuardianImpl struct { - user *models.SignedInUser + user *user.SignedInUser dashId int64 orgId int64 acl []*models.DashboardACLInfoDTO @@ -50,11 +52,11 @@ type dashboardGuardianImpl struct { // New factory for creating a new dashboard guardian instance // When using access control this function is replaced on startup and the AccessControlDashboardGuardian is returned -var New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian { +var New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian { panic("no guardian factory implementation provided") } -func newDashboardGuardian(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser, store sqlstore.Store, dashSvc dashboards.DashboardService) *dashboardGuardianImpl { +func newDashboardGuardian(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser, store sqlstore.Store, dashSvc dashboards.DashboardService) *dashboardGuardianImpl { return &dashboardGuardianImpl{ user: user, dashId: dashId, @@ -97,7 +99,7 @@ func (g *dashboardGuardianImpl) CanCreate(_ int64, _ bool) (bool, error) { } func (g *dashboardGuardianImpl) HasPermission(permission models.PermissionType) (bool, error) { - if g.user.OrgRole == models.ROLE_ADMIN { + if g.user.OrgRole == org.RoleAdmin { return g.logHasPermissionResult(permission, true, nil) } @@ -174,7 +176,7 @@ func (g *dashboardGuardianImpl) checkACL(permission models.PermissionType, acl [ func (g *dashboardGuardianImpl) CheckPermissionBeforeUpdate(permission models.PermissionType, updatePermissions []*models.DashboardACL) (bool, error) { acl := []*models.DashboardACLInfoDTO{} - adminRole := models.ROLE_ADMIN + adminRole := org.RoleAdmin everyoneWithAdminRole := &models.DashboardACLInfoDTO{DashboardId: g.dashId, UserId: 0, TeamId: 0, Role: &adminRole, Permission: models.PERMISSION_ADMIN} // validate that duplicate permissions don't exists @@ -211,7 +213,7 @@ func (g *dashboardGuardianImpl) CheckPermissionBeforeUpdate(permission models.Pe } } - if g.user.OrgRole == models.ROLE_ADMIN { + if g.user.OrgRole == org.RoleAdmin { return true, nil } @@ -316,7 +318,7 @@ func (g *dashboardGuardianImpl) GetHiddenACL(cfg *setting.Cfg) ([]*models.Dashbo type FakeDashboardGuardian struct { DashId int64 OrgId int64 - User *models.SignedInUser + User *user.SignedInUser CanSaveValue bool CanEditValue bool CanViewValue bool @@ -374,7 +376,7 @@ func (g *FakeDashboardGuardian) GetHiddenACL(cfg *setting.Cfg) ([]*models.Dashbo // nolint:unused func MockDashboardGuardian(mock *FakeDashboardGuardian) { - New = func(_ context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian { + New = func(_ context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian { mock.OrgId = orgId mock.DashId = dashId mock.User = user diff --git a/pkg/services/guardian/guardian_test.go b/pkg/services/guardian/guardian_test.go index 07e864848bc..7833bf5de6a 100644 --- a/pkg/services/guardian/guardian_test.go +++ b/pkg/services/guardian/guardian_test.go @@ -12,7 +12,9 @@ import ( "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/mockstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -29,13 +31,13 @@ const ( ) var ( - adminRole = models.ROLE_ADMIN - editorRole = models.ROLE_EDITOR - viewerRole = models.ROLE_VIEWER + adminRole = org.RoleAdmin + editorRole = org.RoleEditor + viewerRole = org.RoleViewer ) func TestGuardianAdmin(t *testing.T) { - orgRoleScenario("Given user has admin org role", t, models.ROLE_ADMIN, func(sc *scenarioContext) { + orgRoleScenario("Given user has admin org role", t, org.RoleAdmin, func(sc *scenarioContext) { // dashboard has default permissions sc.defaultPermissionScenario(USER, FULL_ACCESS) @@ -82,7 +84,7 @@ func TestGuardianAdmin(t *testing.T) { } func TestGuardianEditor(t *testing.T) { - orgRoleScenario("Given user has editor org role", t, models.ROLE_EDITOR, func(sc *scenarioContext) { + orgRoleScenario("Given user has editor org role", t, org.RoleEditor, func(sc *scenarioContext) { // dashboard has default permissions sc.defaultPermissionScenario(USER, EDITOR_ACCESS) @@ -129,7 +131,7 @@ func TestGuardianEditor(t *testing.T) { } func TestGuardianViewer(t *testing.T) { - orgRoleScenario("Given user has viewer org role", t, models.ROLE_VIEWER, func(sc *scenarioContext) { + orgRoleScenario("Given user has viewer org role", t, org.RoleViewer, func(sc *scenarioContext) { // dashboard has default permissions sc.defaultPermissionScenario(USER, VIEWER_ACCESS) @@ -174,7 +176,7 @@ func TestGuardianViewer(t *testing.T) { sc.parentFolderPermissionScenario(VIEWER, models.PERMISSION_VIEW, VIEWER_ACCESS) }) - apiKeyScenario("Given api key with viewer role", t, models.ROLE_VIEWER, func(sc *scenarioContext) { + apiKeyScenario("Given api key with viewer role", t, org.RoleViewer, func(sc *scenarioContext) { // dashboard has default permissions sc.defaultPermissionScenario(VIEWER, VIEWER_ACCESS) }) @@ -699,7 +701,7 @@ func TestGuardianGetHiddenACL(t *testing.T) { cfg.HiddenUsers = map[string]struct{}{"user2": {}} t.Run("Should get hidden acl", func(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ OrgId: orgID, UserId: 1, Login: "user1", @@ -714,7 +716,7 @@ func TestGuardianGetHiddenACL(t *testing.T) { }) t.Run("Grafana admin should not get hidden acl", func(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ OrgId: orgID, UserId: 1, Login: "user1", @@ -749,7 +751,7 @@ func TestGuardianGetACLWithoutDuplicates(t *testing.T) { }).Return(nil) t.Run("Should get acl without duplicates", func(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ OrgId: orgID, UserId: 1, Login: "user1", diff --git a/pkg/services/guardian/guardian_util_test.go b/pkg/services/guardian/guardian_util_test.go index 6dad9430c2b..f28cf031211 100644 --- a/pkg/services/guardian/guardian_util_test.go +++ b/pkg/services/guardian/guardian_util_test.go @@ -12,7 +12,9 @@ import ( "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/mockstore" + "github.com/grafana/grafana/pkg/services/user" ) type scenarioContext struct { @@ -20,7 +22,7 @@ type scenarioContext struct { orgRoleScenario string permissionScenario string g DashboardGuardian - givenUser *models.SignedInUser + givenUser *user.SignedInUser givenDashboardID int64 givenPermissions []*models.DashboardACLInfoDTO givenTeams []*models.TeamDTO @@ -32,9 +34,9 @@ type scenarioContext struct { type scenarioFunc func(c *scenarioContext) -func orgRoleScenario(desc string, t *testing.T, role models.RoleType, fn scenarioFunc) { +func orgRoleScenario(desc string, t *testing.T, role org.RoleType, fn scenarioFunc) { t.Run(desc, func(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: userID, OrgId: orgID, OrgRole: role, @@ -53,9 +55,9 @@ func orgRoleScenario(desc string, t *testing.T, role models.RoleType, fn scenari }) } -func apiKeyScenario(desc string, t *testing.T, role models.RoleType, fn scenarioFunc) { +func apiKeyScenario(desc string, t *testing.T, role org.RoleType, fn scenarioFunc) { t.Run(desc, func(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 0, OrgId: orgID, OrgRole: role, diff --git a/pkg/services/guardian/provider.go b/pkg/services/guardian/provider.go index a26d1f1078e..d0a95c0f63c 100644 --- a/pkg/services/guardian/provider.go +++ b/pkg/services/guardian/provider.go @@ -3,10 +3,10 @@ package guardian import ( "context" - "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/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) type Provider struct{} @@ -26,7 +26,7 @@ func ProvideService( } func InitLegacyGuardian(store sqlstore.Store, dashSvc dashboards.DashboardService) { - New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian { + New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian { return newDashboardGuardian(ctx, dashId, orgId, user, store, dashSvc) } } @@ -35,7 +35,7 @@ func InitAccessControlGuardian( store sqlstore.Store, ac accesscontrol.AccessControl, folderPermissionsService accesscontrol.FolderPermissionsService, dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardService dashboards.DashboardService, ) { - New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian { + New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian { return NewAccessControlDashboardGuardian(ctx, dashId, user, store, ac, folderPermissionsService, dashboardPermissionsService, dashboardService) } } diff --git a/pkg/services/ldap/ldap.go b/pkg/services/ldap/ldap.go index d3dda7add62..03cfa9b09d1 100644 --- a/pkg/services/ldap/ldap.go +++ b/pkg/services/ldap/ldap.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/org" ) // IConnection is interface for LDAP connection manipulation @@ -442,7 +443,7 @@ func (server *Server) buildGrafanaUser(user *ldap.Entry) (*models.ExternalUserIn Login: getAttribute(attrs.Username, user), Email: getAttribute(attrs.Email, user), Groups: memberOf, - OrgRoles: map[int64]models.RoleType{}, + OrgRoles: map[int64]org.RoleType{}, } for _, group := range server.Config.Groups { diff --git a/pkg/services/ldap/ldap_private_test.go b/pkg/services/ldap/ldap_private_test.go index d4d0f1c238d..b7846f58f6c 100644 --- a/pkg/services/ldap/ldap_private_test.go +++ b/pkg/services/ldap/ldap_private_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" ) func TestServer_getSearchRequest(t *testing.T) { @@ -126,7 +127,7 @@ func TestSerializeUsers(t *testing.T) { Groups: []*GroupToOrgRole{{ GroupDN: "foo", OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, }}, }, Connection: &MockConnection{}, @@ -180,7 +181,7 @@ func TestServer_validateGrafanaUser(t *testing.T) { user := &models.ExternalUserInfo{ Login: "markelog", - OrgRoles: map[int64]models.RoleType{ + OrgRoles: map[int64]org.RoleType{ 1: "test", }, } diff --git a/pkg/services/ldap/settings.go b/pkg/services/ldap/settings.go index 54afa4bb544..5449dd892f1 100644 --- a/pkg/services/ldap/settings.go +++ b/pkg/services/ldap/settings.go @@ -8,7 +8,7 @@ import ( "github.com/BurntSushi/toml" "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" ) @@ -62,7 +62,7 @@ type GroupToOrgRole struct { // This pointer specifies if setting was set (for backwards compatibility) IsGrafanaAdmin *bool `toml:"grafana_admin"` - OrgRole models.RoleType `toml:"org_role"` + OrgRole org.RoleType `toml:"org_role"` } // logger for all LDAP stuff diff --git a/pkg/services/libraryelements/database.go b/pkg/services/libraryelements/database.go index b2596650442..cf1bb5ab1c9 100644 --- a/pkg/services/libraryelements/database.go +++ b/pkg/services/libraryelements/database.go @@ -11,9 +11,11 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "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/search" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -98,7 +100,7 @@ func getLibraryElement(dialect migrator.Dialect, session *sqlstore.DBSession, ui } // createLibraryElement adds a library element. -func (l *LibraryElementService) createLibraryElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) { +func (l *LibraryElementService) createLibraryElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) { if err := l.requireSupportedElementKind(cmd.Kind); err != nil { return LibraryElementDTO{}, err } @@ -177,7 +179,7 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn } // deleteLibraryElement deletes a library element. -func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedInUser *models.SignedInUser, uid string) (int64, error) { +func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedInUser *user.SignedInUser, uid string) (int64, error) { var elementID int64 err := l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error { element, err := getLibraryElement(l.SQLStore.Dialect, session, uid, signedInUser.OrgId) @@ -220,7 +222,7 @@ func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedIn } // getLibraryElements gets a Library Element where param == value -func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUser *models.SignedInUser, params []Pair) ([]LibraryElementDTO, error) { +func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUser *user.SignedInUser, params []Pair) ([]LibraryElementDTO, error) { libraryElements := make([]LibraryElementWithMeta, 0) err := store.WithDbSession(c, func(session *sqlstore.DBSession) error { builder := sqlstore.NewSqlBuilder(store.Cfg) @@ -236,7 +238,7 @@ func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUse builder.Write(getFromLibraryElementDTOWithMeta(store.Dialect)) builder.Write(" INNER JOIN dashboard AS dashboard on le.folder_id = dashboard.id AND le.folder_id <> 0") writeParamSelectorSQL(&builder, params...) - if signedInUser.OrgRole != models.ROLE_ADMIN { + if signedInUser.OrgRole != org.RoleAdmin { builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW) } builder.Write(` OR dashboard.id=0`) @@ -291,7 +293,7 @@ func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUse } // getLibraryElementByUid gets a Library Element by uid. -func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error) { +func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error) { libraryElements, err := getLibraryElements(c, l.SQLStore, signedInUser, []Pair{{key: "org_id", value: signedInUser.OrgId}, {key: "uid", value: UID}}) if err != nil { return LibraryElementDTO{}, err @@ -304,12 +306,12 @@ func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signed } // getLibraryElementByName gets a Library Element by name. -func (l *LibraryElementService) getLibraryElementsByName(c context.Context, signedInUser *models.SignedInUser, name string) ([]LibraryElementDTO, error) { +func (l *LibraryElementService) getLibraryElementsByName(c context.Context, signedInUser *user.SignedInUser, name string) ([]LibraryElementDTO, error) { return getLibraryElements(c, l.SQLStore, signedInUser, []Pair{{"org_id", signedInUser.OrgId}, {"name", name}}) } // getAllLibraryElements gets all Library Elements. -func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedInUser *models.SignedInUser, query searchLibraryElementsQuery) (LibraryElementSearchResult, error) { +func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedInUser *user.SignedInUser, query searchLibraryElementsQuery) (LibraryElementSearchResult, error) { elements := make([]LibraryElementWithMeta, 0) result := LibraryElementSearchResult{} if query.perPage <= 0 { @@ -353,7 +355,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI if err := folderFilter.writeFolderFilterSQL(false, &builder); err != nil { return err } - if signedInUser.OrgRole != models.ROLE_ADMIN { + if signedInUser.OrgRole != org.RoleAdmin { builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW) } if query.sortDirection == search.SortAlphaDesc.Name { @@ -428,7 +430,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI return result, err } -func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *models.SignedInUser) error { +func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *user.SignedInUser) error { // FolderID was not provided in the PATCH request if toFolderID == -1 { toFolderID = fromFolderID @@ -452,7 +454,7 @@ func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, eleme } // patchLibraryElement updates a Library Element. -func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInUser *models.SignedInUser, cmd PatchLibraryElementCommand, uid string) (LibraryElementDTO, error) { +func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInUser *user.SignedInUser, cmd PatchLibraryElementCommand, uid string) (LibraryElementDTO, error) { var dto LibraryElementDTO if err := l.requireSupportedElementKind(cmd.Kind); err != nil { return LibraryElementDTO{}, err @@ -553,7 +555,7 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU } // getConnections gets all connections for a Library Element. -func (l *LibraryElementService) getConnections(c context.Context, signedInUser *models.SignedInUser, uid string) ([]LibraryElementConnectionDTO, error) { +func (l *LibraryElementService) getConnections(c context.Context, signedInUser *user.SignedInUser, uid string) ([]LibraryElementConnectionDTO, error) { connections := make([]LibraryElementConnectionDTO, 0) err := l.SQLStore.WithDbSession(c, func(session *sqlstore.DBSession) error { element, err := getLibraryElement(l.SQLStore.Dialect, session, uid, signedInUser.OrgId) @@ -567,7 +569,7 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser * builder.Write(" LEFT JOIN " + l.SQLStore.Dialect.Quote("user") + " AS u1 ON lec.created_by = u1.id") builder.Write(" INNER JOIN dashboard AS dashboard on lec.connection_id = dashboard.id") builder.Write(` WHERE lec.element_id=?`, element.ID) - if signedInUser.OrgRole != models.ROLE_ADMIN { + if signedInUser.OrgRole != org.RoleAdmin { builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW) } if err := session.SQL(builder.GetSQLString(), builder.GetParams()...).Find(&libraryElementConnections); err != nil { @@ -652,7 +654,7 @@ func (l *LibraryElementService) getElementsForDashboardID(c context.Context, das } // connectElementsToDashboardID adds connections for all elements Library Elements in a Dashboard. -func (l *LibraryElementService) connectElementsToDashboardID(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error { +func (l *LibraryElementService) connectElementsToDashboardID(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error { err := l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error { _, err := session.Exec("DELETE FROM "+models.LibraryElementConnectionTableName+" WHERE kind=1 AND connection_id=?", dashboardID) if err != nil { @@ -699,7 +701,7 @@ func (l *LibraryElementService) disconnectElementsFromDashboardID(c context.Cont } // deleteLibraryElementsInFolderUID deletes all Library Elements in a folder. -func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c context.Context, signedInUser *models.SignedInUser, folderUID string) error { +func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c context.Context, signedInUser *user.SignedInUser, folderUID string) error { return l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error { var folderUIDs []struct { ID int64 `xorm:"id"` diff --git a/pkg/services/libraryelements/guard.go b/pkg/services/libraryelements/guard.go index 01ba36cf1fe..2055787ef4f 100644 --- a/pkg/services/libraryelements/guard.go +++ b/pkg/services/libraryelements/guard.go @@ -6,6 +6,8 @@ import ( "github.com/grafana/grafana/pkg/models" "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" ) func isGeneralFolder(folderID int64) bool { @@ -24,12 +26,12 @@ func (l *LibraryElementService) requireSupportedElementKind(kindAsInt int64) err } } -func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Context, user *models.SignedInUser, folderID int64) error { - if isGeneralFolder(folderID) && user.HasRole(models.ROLE_EDITOR) { +func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Context, user *user.SignedInUser, folderID int64) error { + if isGeneralFolder(folderID) && user.HasRole(org.RoleEditor) { return nil } - if isGeneralFolder(folderID) && user.HasRole(models.ROLE_VIEWER) { + if isGeneralFolder(folderID) && user.HasRole(org.RoleViewer) { return dashboards.ErrFolderAccessDenied } folder, err := l.folderService.GetFolderByID(ctx, user, folderID, user.OrgId) @@ -50,8 +52,8 @@ func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Conte return nil } -func (l *LibraryElementService) requireViewPermissionsOnFolder(ctx context.Context, user *models.SignedInUser, folderID int64) error { - if isGeneralFolder(folderID) && user.HasRole(models.ROLE_VIEWER) { +func (l *LibraryElementService) requireViewPermissionsOnFolder(ctx context.Context, user *user.SignedInUser, folderID int64) error { + if isGeneralFolder(folderID) && user.HasRole(org.RoleViewer) { return nil } diff --git a/pkg/services/libraryelements/libraryelements.go b/pkg/services/libraryelements/libraryelements.go index 50229a71b68..5cdfc76023f 100644 --- a/pkg/services/libraryelements/libraryelements.go +++ b/pkg/services/libraryelements/libraryelements.go @@ -5,9 +5,9 @@ import ( "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -25,12 +25,12 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister // Service is a service for operating on library elements. type Service interface { - CreateElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) - GetElement(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error) + CreateElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) + GetElement(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error) GetElementsForDashboard(c context.Context, dashboardID int64) (map[string]LibraryElementDTO, error) - ConnectElementsToDashboard(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error + ConnectElementsToDashboard(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error DisconnectElementsFromDashboard(c context.Context, dashboardID int64) error - DeleteLibraryElementsInFolder(c context.Context, signedInUser *models.SignedInUser, folderUID string) error + DeleteLibraryElementsInFolder(c context.Context, signedInUser *user.SignedInUser, folderUID string) error } // LibraryElementService is the service for the Library Element feature. @@ -43,12 +43,12 @@ type LibraryElementService struct { } // CreateElement creates a Library Element. -func (l *LibraryElementService) CreateElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) { +func (l *LibraryElementService) CreateElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) { return l.createLibraryElement(c, signedInUser, cmd) } // GetElement gets an element from a UID. -func (l *LibraryElementService) GetElement(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error) { +func (l *LibraryElementService) GetElement(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error) { return l.getLibraryElementByUid(c, signedInUser, UID) } @@ -58,7 +58,7 @@ func (l *LibraryElementService) GetElementsForDashboard(c context.Context, dashb } // ConnectElementsToDashboard connects elements to a specific dashboard. -func (l *LibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error { +func (l *LibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error { return l.connectElementsToDashboardID(c, signedInUser, elementUIDs, dashboardID) } @@ -68,6 +68,6 @@ func (l *LibraryElementService) DisconnectElementsFromDashboard(c context.Contex } // DeleteLibraryElementsInFolder deletes all elements for a specific folder. -func (l *LibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *models.SignedInUser, folderUID string) error { +func (l *LibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *user.SignedInUser, folderUID string) error { return l.deleteLibraryElementsInFolderUID(c, signedInUser, folderUID) } diff --git a/pkg/services/libraryelements/libraryelements_delete_test.go b/pkg/services/libraryelements/libraryelements_delete_test.go index 2a1aa9b592a..51869438f77 100644 --- a/pkg/services/libraryelements/libraryelements_delete_test.go +++ b/pkg/services/libraryelements/libraryelements_delete_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/require" @@ -35,7 +36,7 @@ func TestDeleteLibraryElement(t *testing.T) { func(t *testing.T, sc scenarioContext) { sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID}) sc.reqContext.SignedInUser.OrgId = 2 - sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN + sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin resp := sc.service.deleteHandler(sc.reqContext) require.Equal(t, 404, resp.Status()) }) diff --git a/pkg/services/libraryelements/libraryelements_get_all_test.go b/pkg/services/libraryelements/libraryelements_get_all_test.go index e927c6fc976..0ede220f5c8 100644 --- a/pkg/services/libraryelements/libraryelements_get_all_test.go +++ b/pkg/services/libraryelements/libraryelements_get_all_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/search" ) @@ -1240,7 +1241,7 @@ func TestGetAllLibraryElements(t *testing.T) { require.Equal(t, "Text - Library Panel", result.Result.Elements[0].Name) sc.reqContext.SignedInUser.OrgId = 2 - sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN + sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin resp = sc.service.getAllHandler(sc.reqContext) require.Equal(t, 200, resp.Status()) diff --git a/pkg/services/libraryelements/libraryelements_get_test.go b/pkg/services/libraryelements/libraryelements_get_test.go index 0f20a27535e..3c2eae8757d 100644 --- a/pkg/services/libraryelements/libraryelements_get_test.go +++ b/pkg/services/libraryelements/libraryelements_get_test.go @@ -5,6 +5,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/require" @@ -183,7 +184,7 @@ func TestGetLibraryElement(t *testing.T) { scenarioWithPanel(t, "When an admin tries to get a library panel that exists in an other org, it should fail", func(t *testing.T, sc scenarioContext) { sc.reqContext.SignedInUser.OrgId = 2 - sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN + sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin // by uid sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID}) diff --git a/pkg/services/libraryelements/libraryelements_permissions_test.go b/pkg/services/libraryelements/libraryelements_permissions_test.go index 6375cf8a78f..22b3eb9ab74 100644 --- a/pkg/services/libraryelements/libraryelements_permissions_test.go +++ b/pkg/services/libraryelements/libraryelements_permissions_test.go @@ -7,18 +7,19 @@ import ( "github.com/google/go-cmp/cmp" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/require" ) func TestLibraryElementPermissions(t *testing.T) { var defaultPermissions = []folderACLItem{} - var adminOnlyPermissions = []folderACLItem{{models.ROLE_ADMIN, models.PERMISSION_EDIT}} - var editorOnlyPermissions = []folderACLItem{{models.ROLE_EDITOR, models.PERMISSION_EDIT}} - var editorAndViewerPermissions = []folderACLItem{{models.ROLE_EDITOR, models.PERMISSION_EDIT}, {models.ROLE_VIEWER, models.PERMISSION_EDIT}} - var viewerOnlyPermissions = []folderACLItem{{models.ROLE_VIEWER, models.PERMISSION_EDIT}} - var everyonePermissions = []folderACLItem{{models.ROLE_ADMIN, models.PERMISSION_EDIT}, {models.ROLE_EDITOR, models.PERMISSION_EDIT}, {models.ROLE_VIEWER, models.PERMISSION_EDIT}} - var noPermissions = []folderACLItem{{models.ROLE_VIEWER, models.PERMISSION_VIEW}} + var adminOnlyPermissions = []folderACLItem{{org.RoleAdmin, models.PERMISSION_EDIT}} + var editorOnlyPermissions = []folderACLItem{{org.RoleEditor, models.PERMISSION_EDIT}} + var editorAndViewerPermissions = []folderACLItem{{org.RoleEditor, models.PERMISSION_EDIT}, {org.RoleViewer, models.PERMISSION_EDIT}} + var viewerOnlyPermissions = []folderACLItem{{org.RoleViewer, models.PERMISSION_EDIT}} + var everyonePermissions = []folderACLItem{{org.RoleAdmin, models.PERMISSION_EDIT}, {org.RoleEditor, models.PERMISSION_EDIT}, {org.RoleViewer, models.PERMISSION_EDIT}} + var noPermissions = []folderACLItem{{org.RoleViewer, models.PERMISSION_VIEW}} var folderCases = [][]folderACLItem{ defaultPermissions, adminOnlyPermissions, @@ -36,34 +37,34 @@ func TestLibraryElementPermissions(t *testing.T) { var everyoneDesc = "everyone has editor permissions" var noDesc = "everyone has view permissions" var accessCases = []struct { - role models.RoleType + role org.RoleType items []folderACLItem desc string status int }{ - {models.ROLE_ADMIN, defaultPermissions, defaultDesc, 200}, - {models.ROLE_ADMIN, adminOnlyPermissions, adminOnlyDesc, 200}, - {models.ROLE_ADMIN, editorOnlyPermissions, editorOnlyDesc, 200}, - {models.ROLE_ADMIN, editorAndViewerPermissions, editorAndViewerDesc, 200}, - {models.ROLE_ADMIN, viewerOnlyPermissions, viewerOnlyDesc, 200}, - {models.ROLE_ADMIN, everyonePermissions, everyoneDesc, 200}, - {models.ROLE_ADMIN, noPermissions, noDesc, 200}, + {org.RoleAdmin, defaultPermissions, defaultDesc, 200}, + {org.RoleAdmin, adminOnlyPermissions, adminOnlyDesc, 200}, + {org.RoleAdmin, editorOnlyPermissions, editorOnlyDesc, 200}, + {org.RoleAdmin, editorAndViewerPermissions, editorAndViewerDesc, 200}, + {org.RoleAdmin, viewerOnlyPermissions, viewerOnlyDesc, 200}, + {org.RoleAdmin, everyonePermissions, everyoneDesc, 200}, + {org.RoleAdmin, noPermissions, noDesc, 200}, - {models.ROLE_EDITOR, defaultPermissions, defaultDesc, 200}, - {models.ROLE_EDITOR, adminOnlyPermissions, adminOnlyDesc, 403}, - {models.ROLE_EDITOR, editorOnlyPermissions, editorOnlyDesc, 200}, - {models.ROLE_EDITOR, editorAndViewerPermissions, editorAndViewerDesc, 200}, - {models.ROLE_EDITOR, viewerOnlyPermissions, viewerOnlyDesc, 403}, - {models.ROLE_EDITOR, everyonePermissions, everyoneDesc, 200}, - {models.ROLE_EDITOR, noPermissions, noDesc, 403}, + {org.RoleEditor, defaultPermissions, defaultDesc, 200}, + {org.RoleEditor, adminOnlyPermissions, adminOnlyDesc, 403}, + {org.RoleEditor, editorOnlyPermissions, editorOnlyDesc, 200}, + {org.RoleEditor, editorAndViewerPermissions, editorAndViewerDesc, 200}, + {org.RoleEditor, viewerOnlyPermissions, viewerOnlyDesc, 403}, + {org.RoleEditor, everyonePermissions, everyoneDesc, 200}, + {org.RoleEditor, noPermissions, noDesc, 403}, - {models.ROLE_VIEWER, defaultPermissions, defaultDesc, 403}, - {models.ROLE_VIEWER, adminOnlyPermissions, adminOnlyDesc, 403}, - {models.ROLE_VIEWER, editorOnlyPermissions, editorOnlyDesc, 403}, - {models.ROLE_VIEWER, editorAndViewerPermissions, editorAndViewerDesc, 200}, - {models.ROLE_VIEWER, viewerOnlyPermissions, viewerOnlyDesc, 200}, - {models.ROLE_VIEWER, everyonePermissions, everyoneDesc, 200}, - {models.ROLE_VIEWER, noPermissions, noDesc, 403}, + {org.RoleViewer, defaultPermissions, defaultDesc, 403}, + {org.RoleViewer, adminOnlyPermissions, adminOnlyDesc, 403}, + {org.RoleViewer, editorOnlyPermissions, editorOnlyDesc, 403}, + {org.RoleViewer, editorAndViewerPermissions, editorAndViewerDesc, 200}, + {org.RoleViewer, viewerOnlyPermissions, viewerOnlyDesc, 200}, + {org.RoleViewer, everyonePermissions, everyoneDesc, 200}, + {org.RoleViewer, noPermissions, noDesc, 403}, } for _, testCase := range accessCases { @@ -128,12 +129,12 @@ func TestLibraryElementPermissions(t *testing.T) { } var generalFolderCases = []struct { - role models.RoleType + role org.RoleType status int }{ - {models.ROLE_ADMIN, 200}, - {models.ROLE_EDITOR, 200}, - {models.ROLE_VIEWER, 403}, + {org.RoleAdmin, 200}, + {org.RoleEditor, 200}, + {org.RoleViewer, 403}, } for _, testCase := range generalFolderCases { @@ -194,11 +195,11 @@ func TestLibraryElementPermissions(t *testing.T) { } var missingFolderCases = []struct { - role models.RoleType + role org.RoleType }{ - {models.ROLE_ADMIN}, - {models.ROLE_EDITOR}, - {models.ROLE_VIEWER}, + {org.RoleAdmin}, + {org.RoleEditor}, + {org.RoleViewer}, } for _, testCase := range missingFolderCases { @@ -230,12 +231,12 @@ func TestLibraryElementPermissions(t *testing.T) { } var getCases = []struct { - role models.RoleType + role org.RoleType statuses []int }{ - {models.ROLE_ADMIN, []int{200, 200, 200, 200, 200, 200, 200}}, - {models.ROLE_EDITOR, []int{200, 404, 200, 200, 200, 200, 200}}, - {models.ROLE_VIEWER, []int{200, 404, 404, 200, 200, 200, 200}}, + {org.RoleAdmin, []int{200, 200, 200, 200, 200, 200, 200}}, + {org.RoleEditor, []int{200, 404, 200, 200, 200, 200, 200}}, + {org.RoleViewer, []int{200, 404, 404, 200, 200, 200, 200}}, } for _, testCase := range getCases { @@ -292,13 +293,13 @@ func TestLibraryElementPermissions(t *testing.T) { } var getAllCases = []struct { - role models.RoleType + role org.RoleType panels int folderIndexes []int }{ - {models.ROLE_ADMIN, 7, []int{0, 1, 2, 3, 4, 5, 6}}, - {models.ROLE_EDITOR, 6, []int{0, 2, 3, 4, 5, 6}}, - {models.ROLE_VIEWER, 5, []int{0, 3, 4, 5, 6}}, + {org.RoleAdmin, 7, []int{0, 1, 2, 3, 4, 5, 6}}, + {org.RoleEditor, 6, []int{0, 2, 3, 4, 5, 6}}, + {org.RoleViewer, 5, []int{0, 3, 4, 5, 6}}, } for _, testCase := range getAllCases { diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index dbc1a40bd12..a11ba55b196 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -23,6 +23,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" "github.com/grafana/grafana/pkg/services/sqlstore/mockstore" "github.com/grafana/grafana/pkg/services/user" @@ -248,18 +249,18 @@ type scenarioContext struct { ctx *web.Context service *LibraryElementService reqContext *models.ReqContext - user models.SignedInUser + user user.SignedInUser folder *models.Folder initialResult libraryElementResult sqlStore *sqlstore.SQLStore } type folderACLItem struct { - roleType models.RoleType + roleType org.RoleType permission models.PermissionType } -func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard { +func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user user.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard { dash.FolderId = folderID dashItem := &dashboards.SaveDashboardDTO{ Dashboard: dash, @@ -287,7 +288,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign return dashboard } -func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user models.SignedInUser, +func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user user.SignedInUser, items []folderACLItem) *models.Folder { t.Helper() @@ -399,7 +400,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo }, }} orgID := int64(1) - role := models.ROLE_ADMIN + role := org.RoleAdmin sqlStore := sqlstore.InitTestDB(t) dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) features := featuremgmt.WithFeatures() @@ -422,7 +423,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo ), } - usr := models.SignedInUser{ + usr := user.SignedInUser{ UserId: 1, Name: "Signed In User", Login: "signed_in_user", diff --git a/pkg/services/librarypanels/librarypanels.go b/pkg/services/librarypanels/librarypanels.go index e720778ca43..3066f86ea8f 100644 --- a/pkg/services/librarypanels/librarypanels.go +++ b/pkg/services/librarypanels/librarypanels.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/libraryelements" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -30,8 +31,8 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister type Service interface { LoadLibraryPanelsForDashboard(c context.Context, dash *models.Dashboard) error CleanLibraryPanelsForDashboard(dash *models.Dashboard) error - ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error - ImportLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error + ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error + ImportLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error } type LibraryInfo struct { @@ -203,7 +204,7 @@ func cleanLibraryPanelsRecursively(parent *simplejson.Json) error { } // ConnectLibraryPanelsForDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard. -func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error { +func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error { panels := dash.Data.Get("panels").MustArray() libraryPanels := make(map[string]string) err := connectLibraryPanelsRecursively(c, panels, libraryPanels) @@ -257,11 +258,11 @@ func connectLibraryPanelsRecursively(c context.Context, panels []interface{}, li } // ImportLibraryPanelsForDashboard loops through all panels in dashboard JSON and creates any missing library panels in the database. -func (lps *LibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { +func (lps *LibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { return importLibraryPanelsRecursively(c, lps.LibraryElementService, signedInUser, libraryPanels, panels, folderID) } -func importLibraryPanelsRecursively(c context.Context, service libraryelements.Service, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { +func importLibraryPanelsRecursively(c context.Context, service libraryelements.Service, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error { for _, panel := range panels { panelAsJSON := simplejson.NewFromAny(panel) libraryPanel := panelAsJSON.Get("libraryPanel") diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index 50a699107c5..d31f1991dcd 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -21,6 +21,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/libraryelements" + "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" @@ -1279,14 +1280,14 @@ type scenarioContext struct { ctx context.Context service Service elementService libraryelements.Service - user *models.SignedInUser + user *user.SignedInUser folder *models.Folder initialResult libraryPanelResult sqlStore *sqlstore.SQLStore } type folderACLItem struct { - roleType models.RoleType + roleType org.RoleType permission models.PermissionType } @@ -1364,7 +1365,7 @@ func getExpected(t *testing.T, res libraryelements.LibraryElementDTO, UID string } } -func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard { +func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *user.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard { dash.FolderId = folderID dashItem := &dashboards.SaveDashboardDTO{ Dashboard: dash, @@ -1389,7 +1390,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig return dashboard } -func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user *models.SignedInUser, +func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user *user.SignedInUser, items []folderACLItem) *models.Folder { t.Helper() @@ -1489,7 +1490,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo t.Run(desc, func(t *testing.T) { cfg := setting.NewCfg() orgID := int64(1) - role := models.ROLE_ADMIN + role := org.RoleAdmin sqlStore := sqlstore.InitTestDB(t) dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) @@ -1514,7 +1515,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo LibraryElementService: elementService, } - usr := &models.SignedInUser{ + usr := &user.SignedInUser{ UserId: 1, Name: "Signed In User", Login: "signed_in_user", diff --git a/pkg/services/live/features/broadcast.go b/pkg/services/live/features/broadcast.go index 0c246bcdcdb..00731de2e90 100644 --- a/pkg/services/live/features/broadcast.go +++ b/pkg/services/live/features/broadcast.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" ) @@ -36,7 +37,7 @@ func (b *BroadcastRunner) GetHandlerForPath(_ string) (models.ChannelHandler, er } // OnSubscribe will let anyone connect to the path -func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { reply := models.SubscribeReply{ Presence: true, JoinLeave: true, @@ -56,7 +57,7 @@ func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *models.SignedInUser, } // OnPublish is called when a client wants to broadcast on the websocket -func (b *BroadcastRunner) OnPublish(_ context.Context, u *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { +func (b *BroadcastRunner) OnPublish(_ context.Context, u *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { query := &models.SaveLiveMessageQuery{ OrgId: u.OrgId, Channel: e.Channel, diff --git a/pkg/services/live/features/broadcast_test.go b/pkg/services/live/features/broadcast_test.go index afc5b350541..ca2f2cffe3c 100644 --- a/pkg/services/live/features/broadcast_test.go +++ b/pkg/services/live/features/broadcast_test.go @@ -8,6 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -42,7 +43,7 @@ func TestBroadcastRunner_OnSubscribe(t *testing.T) { require.NoError(t, err) reply, status, err := handler.OnSubscribe( context.Background(), - &models.SignedInUser{OrgId: 1, UserId: 2}, + &user.SignedInUser{OrgId: 1, UserId: 2}, models.SubscribeEvent{Channel: channel, Path: "test"}, ) require.NoError(t, err) @@ -76,7 +77,7 @@ func TestBroadcastRunner_OnPublish(t *testing.T) { require.NoError(t, err) reply, status, err := handler.OnPublish( context.Background(), - &models.SignedInUser{OrgId: 1, UserId: 2}, + &user.SignedInUser{OrgId: 1, UserId: 2}, models.PublishEvent{Channel: channel, Path: "test", Data: data}, ) require.NoError(t, err) diff --git a/pkg/services/live/features/comment.go b/pkg/services/live/features/comment.go index 98b30867830..be1337270b5 100644 --- a/pkg/services/live/features/comment.go +++ b/pkg/services/live/features/comment.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/comments/commentmodel" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" ) @@ -25,7 +26,7 @@ func (h *CommentHandler) GetHandlerForPath(_ string) (models.ChannelHandler, err } // OnSubscribe handles subscription to comment group channel. -func (h *CommentHandler) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (h *CommentHandler) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { parts := strings.Split(e.Path, "/") if len(parts) != 2 { return models.SubscribeReply{}, backend.SubscribeStreamStatusNotFound, nil @@ -43,6 +44,6 @@ func (h *CommentHandler) OnSubscribe(ctx context.Context, user *models.SignedInU } // OnPublish is not used for comments. -func (h *CommentHandler) OnPublish(_ context.Context, _ *models.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { +func (h *CommentHandler) OnPublish(_ context.Context, _ *user.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil } diff --git a/pkg/services/live/features/dashboard.go b/pkg/services/live/features/dashboard.go index 2b7af053507..4c55794546f 100644 --- a/pkg/services/live/features/dashboard.go +++ b/pkg/services/live/features/dashboard.go @@ -11,7 +11,9 @@ import ( "github.com/grafana/grafana/pkg/models" "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/user" ) type actionType string @@ -27,13 +29,13 @@ const ( // DashboardEvent events related to dashboards type dashboardEvent struct { - UID string `json:"uid"` - Action actionType `json:"action"` // saved, editing, deleted - User *models.UserDisplayDTO `json:"user,omitempty"` - SessionID string `json:"sessionId,omitempty"` - Message string `json:"message,omitempty"` - Dashboard *models.Dashboard `json:"dashboard,omitempty"` - Error string `json:"error,omitempty"` + UID string `json:"uid"` + Action actionType `json:"action"` // saved, editing, deleted + User *user.UserDisplayDTO `json:"user,omitempty"` + SessionID string `json:"sessionId,omitempty"` + Message string `json:"message,omitempty"` + Dashboard *models.Dashboard `json:"dashboard,omitempty"` + Error string `json:"error,omitempty"` } // DashboardHandler manages all the `grafana/dashboard/*` channels @@ -50,11 +52,11 @@ func (h *DashboardHandler) GetHandlerForPath(_ string) (models.ChannelHandler, e } // OnSubscribe for now allows anyone to subscribe to any dashboard -func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { parts := strings.Split(e.Path, "/") if parts[0] == "gitops" { // gitops gets all changes for everything, so lets make sure it is an admin user - if !user.HasRole(models.ROLE_ADMIN) { + if !user.HasRole(org.RoleAdmin) { return models.SubscribeReply{}, backend.SubscribeStreamStatusPermissionDenied, nil } return models.SubscribeReply{ @@ -88,11 +90,11 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedI } // OnPublish is called when someone begins to edit a dashboard -func (h *DashboardHandler) OnPublish(ctx context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { +func (h *DashboardHandler) OnPublish(ctx context.Context, user *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { parts := strings.Split(e.Path, "/") if parts[0] == "gitops" { // gitops gets all changes for everything, so lets make sure it is an admin user - if !user.HasRole(models.ROLE_ADMIN) { + if !user.HasRole(org.RoleAdmin) { return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil } @@ -161,7 +163,7 @@ func (h *DashboardHandler) publish(orgID int64, event dashboardEvent) error { } // DashboardSaved will broadcast to all connected dashboards -func (h *DashboardHandler) DashboardSaved(orgID int64, user *models.UserDisplayDTO, message string, dashboard *models.Dashboard, err error) error { +func (h *DashboardHandler) DashboardSaved(orgID int64, user *user.UserDisplayDTO, message string, dashboard *models.Dashboard, err error) error { if err != nil && !h.HasGitOpsObserver(orgID) { return nil // only broadcast if it was OK } @@ -182,7 +184,7 @@ func (h *DashboardHandler) DashboardSaved(orgID int64, user *models.UserDisplayD } // DashboardDeleted will broadcast to all connected dashboards -func (h *DashboardHandler) DashboardDeleted(orgID int64, user *models.UserDisplayDTO, uid string) error { +func (h *DashboardHandler) DashboardDeleted(orgID int64, user *user.UserDisplayDTO, uid string) error { return h.publish(orgID, dashboardEvent{ UID: uid, Action: ActionDeleted, diff --git a/pkg/services/live/features/plugin.go b/pkg/services/live/features/plugin.go index 9b938a2433a..1917f547a1e 100644 --- a/pkg/services/live/features/plugin.go +++ b/pkg/services/live/features/plugin.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/live/orgchannel" "github.com/grafana/grafana/pkg/services/live/runstream" + "github.com/grafana/grafana/pkg/services/user" "github.com/centrifugal/centrifuge" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -14,7 +15,7 @@ import ( //go:generate mockgen -destination=plugin_mock.go -package=features github.com/grafana/grafana/pkg/services/live/features PluginContextGetter type PluginContextGetter interface { - GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) + GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) } // PluginRunner can handle streaming operations for channels belonging to plugins. @@ -60,7 +61,7 @@ type PluginPathRunner struct { } // OnSubscribe passes control to a plugin. -func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { pCtx, found, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false) if err != nil { logger.Error("Get plugin context error", "error", err, "path", r.path) @@ -104,7 +105,7 @@ func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *models.SignedI } // OnPublish passes control to a plugin. -func (r *PluginPathRunner) OnPublish(ctx context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { +func (r *PluginPathRunner) OnPublish(ctx context.Context, user *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { pCtx, found, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false) if err != nil { logger.Error("Get plugin context error", "error", err, "path", r.path) diff --git a/pkg/services/live/features/plugin_mock.go b/pkg/services/live/features/plugin_mock.go index 6e2cd2e9a85..5a3f059b540 100644 --- a/pkg/services/live/features/plugin_mock.go +++ b/pkg/services/live/features/plugin_mock.go @@ -10,7 +10,7 @@ import ( gomock "github.com/golang/mock/gomock" backend "github.com/grafana/grafana-plugin-sdk-go/backend" - models "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // MockPluginContextGetter is a mock of PluginContextGetter interface. @@ -37,7 +37,7 @@ func (m *MockPluginContextGetter) EXPECT() *MockPluginContextGetterMockRecorder } // GetPluginContext mocks base method. -func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *models.SignedInUser, arg1, arg2 string) (backend.PluginContext, bool, error) { +func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *user.SignedInUser, arg1, arg2 string) (backend.PluginContext, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPluginContext", arg0, arg1, arg2) ret0, _ := ret[0].(backend.PluginContext) diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index feadc17b4bf..bfa42b421b1 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -39,9 +39,11 @@ import ( "github.com/grafana/grafana/pkg/services/live/pushws" "github.com/grafana/grafana/pkg/services/live/runstream" "github.com/grafana/grafana/pkg/services/live/survey" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/query" "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/sqlstore" + "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" @@ -752,7 +754,7 @@ func (g *GrafanaLive) handleOnPublish(ctx context.Context, client *centrifuge.Cl return centrifuge.PublishReply{}, ¢rifuge.Error{Code: uint32(code), Message: text} } } else { - if !user.HasRole(models.ROLE_ADMIN) { + if !user.HasRole(org.RoleAdmin) { // using HTTP error codes for WS errors too. code, text := publishStatusToHTTPError(backend.PublishStreamStatusPermissionDenied) return centrifuge.PublishReply{}, ¢rifuge.Error{Code: uint32(code), Message: text} @@ -839,7 +841,7 @@ func publishStatusToHTTPError(status backend.PublishStreamStatus) (int, string) } // GetChannelHandler gives thread-safe access to the channel. -func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *models.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) { +func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) { // Parse the identifier ${scope}/${namespace}/${path} addr, err := live.ParseChannel(channel) if err != nil { @@ -880,7 +882,7 @@ func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *models.Signed // GetChannelHandlerFactory gets a ChannelHandlerFactory for a namespace. // It gives thread-safe access to the channel. -func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *models.SignedInUser, scope string, namespace string) (models.ChannelHandlerFactory, error) { +func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *user.SignedInUser, scope string, namespace string) (models.ChannelHandlerFactory, error) { switch scope { case live.ScopeGrafana: return g.handleGrafanaScope(user, namespace) @@ -895,14 +897,14 @@ func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *models } } -func (g *GrafanaLive) handleGrafanaScope(_ *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handleGrafanaScope(_ *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { if p, ok := g.GrafanaScope.Features[namespace]; ok { return p, nil } return nil, fmt.Errorf("unknown feature: %q", namespace) } -func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { streamHandler, err := g.getStreamPlugin(ctx, namespace) if err != nil { return nil, fmt.Errorf("can't find stream plugin: %s", namespace) @@ -916,11 +918,11 @@ func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *models.SignedInU ), nil } -func (g *GrafanaLive) handleStreamScope(u *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handleStreamScope(u *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { return g.ManagedStreamRunner.GetOrCreateStream(u.OrgId, live.ScopeStream, namespace) } -func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) { ds, err := g.DataSourceCache.GetDatasourceByUID(ctx, namespace, user, false) if err != nil { return nil, fmt.Errorf("error getting datasource: %w", err) @@ -984,7 +986,7 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *models.ReqContext) response.Respons return response.Error(http.StatusForbidden, http.StatusText(http.StatusForbidden), nil) } } else { - if !user.HasRole(models.ROLE_ADMIN) { + if !user.HasRole(org.RoleAdmin) { return response.Error(http.StatusForbidden, http.StatusText(http.StatusForbidden), nil) } } diff --git a/pkg/services/live/livecontext/context.go b/pkg/services/live/livecontext/context.go index 36120245e34..c2ee0c61bc1 100644 --- a/pkg/services/live/livecontext/context.go +++ b/pkg/services/live/livecontext/context.go @@ -3,21 +3,21 @@ package livecontext import ( "context" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) type signedUserContextKeyType int var signedUserContextKey signedUserContextKeyType -func SetContextSignedUser(ctx context.Context, user *models.SignedInUser) context.Context { +func SetContextSignedUser(ctx context.Context, user *user.SignedInUser) context.Context { ctx = context.WithValue(ctx, signedUserContextKey, user) return ctx } -func GetContextSignedUser(ctx context.Context) (*models.SignedInUser, bool) { +func GetContextSignedUser(ctx context.Context) (*user.SignedInUser, bool) { if val := ctx.Value(signedUserContextKey); val != nil { - user, ok := val.(*models.SignedInUser) + user, ok := val.(*user.SignedInUser) return user, ok } return nil, false diff --git a/pkg/services/live/liveplugin/plugin.go b/pkg/services/live/liveplugin/plugin.go index 523cb88ada2..72b1f5f8cf8 100644 --- a/pkg/services/live/liveplugin/plugin.go +++ b/pkg/services/live/liveplugin/plugin.go @@ -4,11 +4,11 @@ import ( "context" "fmt" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/plugins/plugincontext" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/live/orgchannel" "github.com/grafana/grafana/pkg/services/live/pipeline" + "github.com/grafana/grafana/pkg/services/user" "github.com/centrifugal/centrifuge" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -72,7 +72,7 @@ func NewContextGetter(pluginContextProvider *plugincontext.Provider, dataSourceC } } -func (g *ContextGetter) GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { +func (g *ContextGetter) GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { if datasourceUID == "" { return g.pluginContextProvider.Get(ctx, pluginID, user) } diff --git a/pkg/services/live/managedstream/runner.go b/pkg/services/live/managedstream/runner.go index e30611dc51e..932c2e3e41c 100644 --- a/pkg/services/live/managedstream/runner.go +++ b/pkg/services/live/managedstream/runner.go @@ -9,6 +9,7 @@ import ( "time" "github.com/grafana/grafana/pkg/services/live/orgchannel" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" @@ -238,7 +239,7 @@ func (s *NamespaceStream) GetHandlerForPath(_ string) (models.ChannelHandler, er return s, nil } -func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) { reply := models.SubscribeReply{} frameJSON, ok, err := s.frameCache.GetFrame(ctx, u.OrgId, e.Channel) if err != nil { @@ -250,6 +251,6 @@ func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *models.SignedInUse return reply, backend.SubscribeStreamStatusOK, nil } -func (s *NamespaceStream) OnPublish(_ context.Context, _ *models.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { +func (s *NamespaceStream) OnPublish(_ context.Context, _ *user.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) { return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil } diff --git a/pkg/services/live/pipeline/auth.go b/pkg/services/live/pipeline/auth.go index ae949c0b109..f24bdcff6aa 100644 --- a/pkg/services/live/pipeline/auth.go +++ b/pkg/services/live/pipeline/auth.go @@ -3,21 +3,22 @@ package pipeline import ( "context" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/services/user" ) type RoleCheckAuthorizer struct { - role models.RoleType + role org.RoleType } -func NewRoleCheckAuthorizer(role models.RoleType) *RoleCheckAuthorizer { +func NewRoleCheckAuthorizer(role org.RoleType) *RoleCheckAuthorizer { return &RoleCheckAuthorizer{role: role} } -func (s *RoleCheckAuthorizer) CanSubscribe(_ context.Context, u *models.SignedInUser) (bool, error) { +func (s *RoleCheckAuthorizer) CanSubscribe(_ context.Context, u *user.SignedInUser) (bool, error) { return u.HasRole(s.role), nil } -func (s *RoleCheckAuthorizer) CanPublish(_ context.Context, u *models.SignedInUser) (bool, error) { +func (s *RoleCheckAuthorizer) CanPublish(_ context.Context, u *user.SignedInUser) (bool, error) { return u.HasRole(s.role), nil } diff --git a/pkg/services/live/pipeline/config.go b/pkg/services/live/pipeline/config.go index dca0bce6aff..f3133b2fc77 100644 --- a/pkg/services/live/pipeline/config.go +++ b/pkg/services/live/pipeline/config.go @@ -2,12 +2,12 @@ package pipeline import ( "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" ) // ChannelAuthCheckConfig is used to define auth rules for a channel. type ChannelAuthCheckConfig struct { - RequireRole models.RoleType `json:"role,omitempty"` + RequireRole org.RoleType `json:"role,omitempty"` } type ChannelAuthConfig struct { diff --git a/pkg/services/live/pipeline/pipeline.go b/pkg/services/live/pipeline/pipeline.go index cb6941c2c69..eb89573c11d 100644 --- a/pkg/services/live/pipeline/pipeline.go +++ b/pkg/services/live/pipeline/pipeline.go @@ -7,6 +7,7 @@ import ( "os" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" @@ -112,12 +113,12 @@ type Subscriber interface { // PublishAuthChecker checks whether current user can publish to a channel. type PublishAuthChecker interface { - CanPublish(ctx context.Context, u *models.SignedInUser) (bool, error) + CanPublish(ctx context.Context, u *user.SignedInUser) (bool, error) } // SubscribeAuthChecker checks whether current user can subscribe to a channel. type SubscribeAuthChecker interface { - CanSubscribe(ctx context.Context, u *models.SignedInUser) (bool, error) + CanSubscribe(ctx context.Context, u *user.SignedInUser) (bool, error) } // LiveChannelRule is an in-memory representation of each specific rule to be executed by Pipeline. @@ -140,7 +141,7 @@ type LiveChannelRule struct { Subscribers []Subscriber // PublishAuth allows providing authorization logic for publishing into a channel. - // If PublishAuth is not set then ROLE_ADMIN is required to publish. + // If PublishAuth is not set then RoleAdmin is required to publish. PublishAuth PublishAuthChecker // DataOutputters if set allows doing something useful with raw input data. If not set then // we step further to the converter. Each DataOutputter can optionally return a slice diff --git a/pkg/services/live/pipeline/subscribe_builtin.go b/pkg/services/live/pipeline/subscribe_builtin.go index 7b7e6ba3e0b..c4928d90af6 100644 --- a/pkg/services/live/pipeline/subscribe_builtin.go +++ b/pkg/services/live/pipeline/subscribe_builtin.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/live/livecontext" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/live" @@ -15,7 +16,7 @@ type BuiltinSubscriber struct { } type ChannelHandlerGetter interface { - GetChannelHandler(ctx context.Context, user *models.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) + GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) } const SubscriberTypeBuiltin = "builtin" diff --git a/pkg/services/live/runstream/manager.go b/pkg/services/live/runstream/manager.go index 534cc64c59f..8e96da34cfb 100644 --- a/pkg/services/live/runstream/manager.go +++ b/pkg/services/live/runstream/manager.go @@ -9,7 +9,7 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana-plugin-sdk-go/backend" ) @@ -25,7 +25,7 @@ type ChannelLocalPublisher interface { } type PluginContextGetter interface { - GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) + GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) } type NumLocalSubscribersGetter interface { @@ -373,7 +373,7 @@ func (s *Manager) Run(ctx context.Context) error { type streamRequest struct { Channel string Path string - user *models.SignedInUser + user *user.SignedInUser PluginContext backend.PluginContext StreamRunner StreamRunner Data []byte @@ -400,7 +400,7 @@ var errDatasourceNotFound = errors.New("datasource not found") // SubmitStream submits stream handler in Manager to manage. // The stream will be opened and kept till channel has active subscribers. -func (s *Manager) SubmitStream(ctx context.Context, user *models.SignedInUser, channel string, path string, data []byte, pCtx backend.PluginContext, streamRunner StreamRunner, isResubmit bool) (*submitResult, error) { +func (s *Manager) SubmitStream(ctx context.Context, user *user.SignedInUser, channel string, path string, data []byte, pCtx backend.PluginContext, streamRunner StreamRunner, isResubmit bool) (*submitResult, error) { if isResubmit { // Resolve new plugin context as it could be modified since last call. var datasourceUID string diff --git a/pkg/services/live/runstream/manager_test.go b/pkg/services/live/runstream/manager_test.go index cbf611f89a6..782d4ff84e2 100644 --- a/pkg/services/live/runstream/manager_test.go +++ b/pkg/services/live/runstream/manager_test.go @@ -6,10 +6,9 @@ import ( "testing" "time" - "github.com/grafana/grafana/pkg/models" - "github.com/golang/mock/gomock" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -71,7 +70,7 @@ func TestStreamManager_SubmitStream_Send(t *testing.T) { }, } - mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { require.Equal(t, int64(2), user.UserId) require.Equal(t, int64(1), user.OrgId) require.Equal(t, testPluginContext.PluginID, pluginID) @@ -94,12 +93,12 @@ func TestStreamManager_SubmitStream_Send(t *testing.T) { return ctx.Err() }).Times(1) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, testPluginContext, mockStreamRunner, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, testPluginContext, mockStreamRunner, false) require.NoError(t, err) require.False(t, result.StreamExists) // try submit the same. - result, err = manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) + result, err = manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) require.NoError(t, err) require.True(t, result.StreamExists) @@ -133,7 +132,7 @@ func TestStreamManager_SubmitStream_DifferentOrgID(t *testing.T) { mockPacketSender.EXPECT().PublishLocal("1/test", gomock.Any()).Times(1) mockPacketSender.EXPECT().PublishLocal("2/test", gomock.Any()).Times(1) - mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { return backend.PluginContext{}, true, nil }).Times(0) @@ -163,12 +162,12 @@ func TestStreamManager_SubmitStream_DifferentOrgID(t *testing.T) { return ctx.Err() }).Times(1) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner1, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner1, false) require.NoError(t, err) require.False(t, result.StreamExists) // try submit the same channel but different orgID. - result, err = manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 2}, "2/test", "test", nil, backend.PluginContext{}, mockStreamRunner2, false) + result, err = manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 2}, "2/test", "test", nil, backend.PluginContext{}, mockStreamRunner2, false) require.NoError(t, err) require.False(t, result.StreamExists) @@ -205,7 +204,7 @@ func TestStreamManager_SubmitStream_CloseNoSubscribers(t *testing.T) { startedCh := make(chan struct{}) doneCh := make(chan struct{}) - mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { return backend.PluginContext{}, true, nil }).Times(0) @@ -219,7 +218,7 @@ func TestStreamManager_SubmitStream_CloseNoSubscribers(t *testing.T) { return ctx.Err() }).Times(1) - _, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) + _, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) require.NoError(t, err) waitWithTimeout(t, startedCh, time.Second) @@ -254,7 +253,7 @@ func TestStreamManager_SubmitStream_ErrorRestartsRunStream(t *testing.T) { }, } - mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { require.Equal(t, int64(2), user.UserId) require.Equal(t, int64(1), user.OrgId) require.Equal(t, testPluginContext.PluginID, pluginID) @@ -273,7 +272,7 @@ func TestStreamManager_SubmitStream_ErrorRestartsRunStream(t *testing.T) { return errors.New("boom") }).Times(numErrors + 1) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) require.NoError(t, err) require.False(t, result.StreamExists) @@ -296,7 +295,7 @@ func TestStreamManager_SubmitStream_NilErrorStopsRunStream(t *testing.T) { _ = manager.Run(ctx) }() - mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { return backend.PluginContext{}, true, nil }).Times(0) @@ -307,7 +306,7 @@ func TestStreamManager_SubmitStream_NilErrorStopsRunStream(t *testing.T) { return nil }).Times(1) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, backend.PluginContext{}, mockStreamRunner, false) require.NoError(t, err) require.False(t, result.StreamExists) waitWithTimeout(t, result.CloseNotify, time.Second) @@ -337,7 +336,7 @@ func TestStreamManager_HandleDatasourceUpdate(t *testing.T) { }, } - mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { require.Equal(t, int64(2), user.UserId) require.Equal(t, int64(1), user.OrgId) require.Equal(t, testPluginContext.PluginID, pluginID) @@ -366,7 +365,7 @@ func TestStreamManager_HandleDatasourceUpdate(t *testing.T) { return nil }).Times(2) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) require.NoError(t, err) require.False(t, result.StreamExists) @@ -403,7 +402,7 @@ func TestStreamManager_HandleDatasourceDelete(t *testing.T) { }, } - mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { + mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { require.Equal(t, int64(2), user.UserId) require.Equal(t, int64(1), user.OrgId) require.Equal(t, testPluginContext.PluginID, pluginID) @@ -422,7 +421,7 @@ func TestStreamManager_HandleDatasourceDelete(t *testing.T) { return ctx.Err() }).Times(1) - result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) + result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false) require.NoError(t, err) require.False(t, result.StreamExists) diff --git a/pkg/services/live/runstream/mock.go b/pkg/services/live/runstream/mock.go index f1a5949907e..42a5324e34f 100644 --- a/pkg/services/live/runstream/mock.go +++ b/pkg/services/live/runstream/mock.go @@ -10,7 +10,7 @@ import ( gomock "github.com/golang/mock/gomock" backend "github.com/grafana/grafana-plugin-sdk-go/backend" - models "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) // MockChannelLocalPublisher is a mock of ChannelLocalPublisher interface. @@ -149,7 +149,7 @@ func (m *MockPluginContextGetter) EXPECT() *MockPluginContextGetterMockRecorder } // GetPluginContext mocks base method. -func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *models.SignedInUser, arg1, arg2 string, arg3 bool) (backend.PluginContext, bool, error) { +func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *user.SignedInUser, arg1, arg2 string, arg3 bool) (backend.PluginContext, bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPluginContext", ctx, arg0, arg1, arg2, arg3) ret0, _ := ret[0].(backend.PluginContext) diff --git a/pkg/services/login/loginservice/loginservice_test.go b/pkg/services/login/loginservice/loginservice_test.go index 2ea86490969..6b4fca5c4e2 100644 --- a/pkg/services/login/loginservice/loginservice_test.go +++ b/pkg/services/login/loginservice/loginservice_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/login" "github.com/grafana/grafana/pkg/services/login/logintest" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore/mockstore" "github.com/grafana/grafana/pkg/services/user" @@ -127,17 +128,17 @@ func createUserOrgDTO() []*models.UserOrgDTO { { OrgId: 1, Name: "Bar", - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, }, { OrgId: 10, Name: "Foo", - Role: models.ROLE_ADMIN, + Role: org.RoleAdmin, }, { OrgId: 11, Name: "Stuff", - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, }, } return users @@ -146,8 +147,8 @@ func createUserOrgDTO() []*models.UserOrgDTO { func createSimpleExternalUser() models.ExternalUserInfo { externalUser := models.ExternalUserInfo{ AuthModule: login.LDAPAuthModule, - OrgRoles: map[int64]models.RoleType{ - 1: models.ROLE_VIEWER, + OrgRoles: map[int64]org.RoleType{ + 1: org.RoleViewer, }, } diff --git a/pkg/services/ngalert/accesscontrol.go b/pkg/services/ngalert/accesscontrol.go index b0c5adba72e..ca53b60ba29 100644 --- a/pkg/services/ngalert/accesscontrol.go +++ b/pkg/services/ngalert/accesscontrol.go @@ -1,10 +1,10 @@ package ngalert 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/datasources" + "github.com/grafana/grafana/pkg/services/org" ) const AlertRolesGroup = "Alerting" @@ -140,7 +140,7 @@ var ( Group: AlertRolesGroup, Permissions: accesscontrol.ConcatPermissions(rulesReaderRole.Role.Permissions, instancesReaderRole.Role.Permissions, notificationsReaderRole.Role.Permissions), }, - Grants: []string{string(models.ROLE_VIEWER)}, + Grants: []string{string(org.RoleViewer)}, } alertingWriterRole = accesscontrol.RoleRegistration{ @@ -151,7 +151,7 @@ var ( Group: AlertRolesGroup, Permissions: accesscontrol.ConcatPermissions(rulesWriterRole.Role.Permissions, instancesWriterRole.Role.Permissions, notificationsWriterRole.Role.Permissions), }, - Grants: []string{string(models.ROLE_EDITOR), string(models.ROLE_ADMIN)}, + Grants: []string{string(org.RoleEditor), string(org.RoleAdmin)}, } alertingProvisionerRole = accesscontrol.RoleRegistration{ @@ -169,7 +169,7 @@ var ( }, }, }, - Grants: []string{string(models.ROLE_ADMIN)}, + Grants: []string{string(org.RoleAdmin)}, } ) diff --git a/pkg/services/ngalert/api/api_alertmanager_test.go b/pkg/services/ngalert/api/api_alertmanager_test.go index 9d89c2b0b30..42b857250d8 100644 --- a/pkg/services/ngalert/api/api_alertmanager_test.go +++ b/pkg/services/ngalert/api/api_alertmanager_test.go @@ -23,8 +23,10 @@ import ( ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/notifier" "github.com/grafana/grafana/pkg/services/ngalert/provisioning" + "github.com/grafana/grafana/pkg/services/org" "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/util" "github.com/grafana/grafana/pkg/web" @@ -167,7 +169,7 @@ func TestAlertmanagerConfig(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 12, }, } @@ -184,7 +186,7 @@ func TestAlertmanagerConfig(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } @@ -201,7 +203,7 @@ func TestAlertmanagerConfig(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 3, // Org 3 was initialized with broken config. }, } @@ -331,8 +333,8 @@ func TestSilenceCreate(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ - OrgRole: models.ROLE_EDITOR, + SignedInUser: &user.SignedInUser{ + OrgRole: org.RoleEditor, OrgId: 1, }, } @@ -353,7 +355,7 @@ func TestRouteCreateSilence(t *testing.T) { name string silence func() apimodels.PostableSilence accessControl func() accesscontrol.AccessControl - role models.RoleType + role org.RoleType expectedStatus int }{ { @@ -380,7 +382,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_VIEWER, + role: org.RoleViewer, expectedStatus: http.StatusUnauthorized, }, { @@ -389,7 +391,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_EDITOR, + role: org.RoleEditor, expectedStatus: http.StatusAccepted, }, { @@ -398,7 +400,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_ADMIN, + role: org.RoleAdmin, expectedStatus: http.StatusAccepted, }, { @@ -425,7 +427,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_VIEWER, + role: org.RoleViewer, expectedStatus: http.StatusUnauthorized, }, { @@ -434,7 +436,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_EDITOR, + role: org.RoleEditor, expectedStatus: http.StatusAccepted, }, { @@ -443,7 +445,7 @@ func TestRouteCreateSilence(t *testing.T) { accessControl: func() accesscontrol.AccessControl { return acMock.New().WithDisabled() }, - role: models.ROLE_ADMIN, + role: org.RoleAdmin, expectedStatus: http.StatusAccepted, }, } @@ -457,7 +459,7 @@ func TestRouteCreateSilence(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgRole: tesCase.role, OrgId: 1, }, @@ -624,7 +626,7 @@ func createRequestCtxInOrg(org int64) *models.ReqContext { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: org, }, } diff --git a/pkg/services/ngalert/api/api_configuration.go b/pkg/services/ngalert/api/api_configuration.go index 5c9acd1d094..c429d972f21 100644 --- a/pkg/services/ngalert/api/api_configuration.go +++ b/pkg/services/ngalert/api/api_configuration.go @@ -13,6 +13,7 @@ import ( apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/store" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/util" v1 "github.com/prometheus/client_golang/api/prometheus/v1" @@ -43,7 +44,7 @@ func (srv ConfigSrv) RouteGetAlertmanagers(c *models.ReqContext) response.Respon } func (srv ConfigSrv) RouteGetNGalertConfig(c *models.ReqContext) response.Response { - if c.OrgRole != models.ROLE_ADMIN { + if c.OrgRole != org.RoleAdmin { return accessForbiddenResp() } @@ -66,7 +67,7 @@ func (srv ConfigSrv) RouteGetNGalertConfig(c *models.ReqContext) response.Respon } func (srv ConfigSrv) RoutePostNGalertConfig(c *models.ReqContext, body apimodels.PostableNGalertConfig) response.Response { - if c.OrgRole != models.ROLE_ADMIN { + if c.OrgRole != org.RoleAdmin { return accessForbiddenResp() } @@ -108,7 +109,7 @@ func (srv ConfigSrv) RoutePostNGalertConfig(c *models.ReqContext, body apimodels } func (srv ConfigSrv) RouteDeleteNGalertConfig(c *models.ReqContext) response.Response { - if c.OrgRole != models.ROLE_ADMIN { + if c.OrgRole != org.RoleAdmin { return accessForbiddenResp() } diff --git a/pkg/services/ngalert/api/api_configuration_test.go b/pkg/services/ngalert/api/api_configuration_test.go index 6dfefe7de48..83b1df7e3dc 100644 --- a/pkg/services/ngalert/api/api_configuration_test.go +++ b/pkg/services/ngalert/api/api_configuration_test.go @@ -6,11 +6,11 @@ import ( "testing" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/store" + "github.com/grafana/grafana/pkg/services/org" "github.com/stretchr/testify/require" ) @@ -89,7 +89,7 @@ func TestExternalAlertmanagerChoice(t *testing.T) { }, } ctx := createRequestCtxInOrg(1) - ctx.OrgRole = models.ROLE_ADMIN + ctx.OrgRole = org.RoleAdmin for _, test := range tests { t.Run(test.name, func(t *testing.T) { sut := createAPIAdminSut(t, test.datasources) diff --git a/pkg/services/ngalert/api/api_prometheus_test.go b/pkg/services/ngalert/api/api_prometheus_test.go index 81448d72db3..19e76034ebc 100644 --- a/pkg/services/ngalert/api/api_prometheus_test.go +++ b/pkg/services/ngalert/api/api_prometheus_test.go @@ -21,6 +21,8 @@ import ( ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/state" "github.com/grafana/grafana/pkg/services/ngalert/store" + "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" ) @@ -90,7 +92,7 @@ func TestRouteGetAlertStatuses(t *testing.T) { _, _, _, api := setupAPI(t) req, err := http.NewRequest("GET", "/api/v1/alerts", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID}} r := api.RouteGetAlertStatuses(c) require.Equal(t, http.StatusOK, r.Status()) @@ -109,7 +111,7 @@ func TestRouteGetAlertStatuses(t *testing.T) { fakeAIM.GenerateAlertInstances(1, util.GenerateShortUID(), 2) req, err := http.NewRequest("GET", "/api/v1/alerts", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID}} r := api.RouteGetAlertStatuses(c) require.Equal(t, http.StatusOK, r.Status()) @@ -151,7 +153,7 @@ func TestRouteGetAlertStatuses(t *testing.T) { fakeAIM.GenerateAlertInstances(1, util.GenerateShortUID(), 2, withAlertingState()) req, err := http.NewRequest("GET", "/api/v1/alerts", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID}} r := api.RouteGetAlertStatuses(c) require.Equal(t, http.StatusOK, r.Status()) @@ -193,7 +195,7 @@ func TestRouteGetAlertStatuses(t *testing.T) { fakeAIM.GenerateAlertInstances(orgID, util.GenerateShortUID(), 2) req, err := http.NewRequest("GET", "/api/v1/alerts?includeInternalLabels=true", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID}} r := api.RouteGetAlertStatuses(c) require.Equal(t, http.StatusOK, r.Status()) @@ -255,7 +257,7 @@ func TestRouteGetRuleStatuses(t *testing.T) { req, err := http.NewRequest("GET", "/api/v1/rules", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID, OrgRole: models.ROLE_VIEWER}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID, OrgRole: org.RoleViewer}} t.Run("with no rules", func(t *testing.T) { _, _, _, api := setupAPI(t) @@ -325,7 +327,7 @@ func TestRouteGetRuleStatuses(t *testing.T) { req, err := http.NewRequest("GET", "/api/v1/rules?includeInternalLabels=true", nil) require.NoError(t, err) - c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &models.SignedInUser{OrgId: orgID, OrgRole: models.ROLE_VIEWER}} + c := &models.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgId: orgID, OrgRole: org.RoleViewer}} r := api.RouteGetRuleStatuses(c) require.Equal(t, http.StatusOK, r.Status()) diff --git a/pkg/services/ngalert/api/api_provisioning_test.go b/pkg/services/ngalert/api/api_provisioning_test.go index db9cd568617..984885549d2 100644 --- a/pkg/services/ngalert/api/api_provisioning_test.go +++ b/pkg/services/ngalert/api/api_provisioning_test.go @@ -22,6 +22,7 @@ import ( "github.com/grafana/grafana/pkg/services/secrets" secrets_fakes "github.com/grafana/grafana/pkg/services/secrets/fakes" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/web" ) @@ -372,7 +373,7 @@ func createTestRequestCtx() gfcore.ReqContext { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &gfcore.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } diff --git a/pkg/services/ngalert/api/api_ruler_test.go b/pkg/services/ngalert/api/api_ruler_test.go index 0f4e05892ec..012d587a738 100644 --- a/pkg/services/ngalert/api/api_ruler_test.go +++ b/pkg/services/ngalert/api/api_ruler_test.go @@ -23,6 +23,8 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/schedule" "github.com/grafana/grafana/pkg/services/ngalert/store" + "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" ) @@ -82,7 +84,7 @@ func TestRouteDeleteAlertRules(t *testing.T) { scheduler.On("DeleteAlertRule", mock.Anything).Panic("should not be called") ac := acMock.New().WithDisabled() - request := createRequestContext(orgID, models2.ROLE_VIEWER, nil) + request := createRequestContext(orgID, org.RoleViewer, nil) response := createService(ac, ruleStore, scheduler).RouteDeleteAlertRules(request, folder.Title, "") require.Equalf(t, 401, response.Status(), "Expected 403 but got %d: %v", response.Status(), string(response.Body())) @@ -102,7 +104,7 @@ func TestRouteDeleteAlertRules(t *testing.T) { scheduler.On("DeleteAlertRule", mock.Anything) ac := acMock.New().WithDisabled() - request := createRequestContext(orgID, models2.ROLE_EDITOR, nil) + request := createRequestContext(orgID, org.RoleEditor, nil) response := createService(ac, ruleStore, scheduler).RouteDeleteAlertRules(request, folder.Title, "") require.Equalf(t, 202, response.Status(), "Expected 202 but got %d: %v", response.Status(), string(response.Body())) assertRulesDeleted(t, rulesInFolder, ruleStore, scheduler) @@ -124,7 +126,7 @@ func TestRouteDeleteAlertRules(t *testing.T) { scheduler.On("DeleteAlertRule", mock.Anything) ac := acMock.New().WithDisabled() - request := createRequestContext(orgID, models2.ROLE_EDITOR, nil) + request := createRequestContext(orgID, org.RoleEditor, nil) response := createService(ac, ruleStore, scheduler).RouteDeleteAlertRules(request, folder.Title, groupName) require.Equalf(t, 202, response.Status(), "Expected 202 but got %d: %v", response.Status(), string(response.Body())) assertRulesDeleted(t, rulesInFolderInGroup, ruleStore, scheduler) @@ -148,7 +150,7 @@ func TestRouteDeleteAlertRules(t *testing.T) { err := svc.provenanceStore.SetProvenance(context.Background(), rulesInFolder[0], orgID, models.ProvenanceAPI) require.NoError(t, err) - request := createRequestContext(orgID, models2.ROLE_EDITOR, nil) + request := createRequestContext(orgID, org.RoleEditor, nil) response := svc.RouteDeleteAlertRules(request, folder.Title, "") require.Equalf(t, 202, response.Status(), "Expected 202 but got %d: %v", response.Status(), string(response.Body())) assertRulesDeleted(t, rulesInFolder[1:], ruleStore, scheduler) @@ -316,7 +318,7 @@ func TestRouteGetNamespaceRulesConfig(t *testing.T) { ruleStore.PutRule(context.Background(), expectedRules...) ac := acMock.New().WithDisabled() - req := createRequestContext(orgID, models2.ROLE_VIEWER, nil) + req := createRequestContext(orgID, org.RoleViewer, nil) response := createService(ac, ruleStore, nil).RouteGetNamespaceRulesConfig(req, folder.Title) require.Equal(t, http.StatusAccepted, response.Status()) @@ -359,7 +361,7 @@ func TestRouteGetNamespaceRulesConfig(t *testing.T) { err := svc.provenanceStore.SetProvenance(context.Background(), rule, orgID, models.ProvenanceAPI) require.NoError(t, err) - req := createRequestContext(orgID, models2.ROLE_VIEWER, nil) + req := createRequestContext(orgID, org.RoleViewer, nil) response := svc.RouteGetNamespaceRulesConfig(req, folder.Title) require.Equal(t, http.StatusAccepted, response.Status()) @@ -394,7 +396,7 @@ func TestRouteGetNamespaceRulesConfig(t *testing.T) { ruleStore.PutRule(context.Background(), expectedRules...) ac := acMock.New().WithDisabled() - response := createService(ac, ruleStore, nil).RouteGetNamespaceRulesConfig(createRequestContext(orgID, models2.ROLE_VIEWER, nil), folder.Title) + response := createService(ac, ruleStore, nil).RouteGetNamespaceRulesConfig(createRequestContext(orgID, org.RoleViewer, nil), folder.Title) require.Equal(t, http.StatusAccepted, response.Status()) result := &apimodels.NamespaceConfigResponse{} @@ -476,7 +478,7 @@ func TestRouteGetRulesConfig(t *testing.T) { ruleStore.PutRule(context.Background(), expectedRules...) ac := acMock.New().WithDisabled() - response := createService(ac, ruleStore, nil).RouteGetRulesConfig(createRequestContext(orgID, models2.ROLE_VIEWER, nil)) + response := createService(ac, ruleStore, nil).RouteGetRulesConfig(createRequestContext(orgID, org.RoleViewer, nil)) require.Equal(t, http.StatusOK, response.Status()) result := &apimodels.NamespaceConfigResponse{} @@ -556,7 +558,7 @@ func TestRouteGetRulesGroupConfig(t *testing.T) { ruleStore.PutRule(context.Background(), expectedRules...) ac := acMock.New().WithDisabled() - response := createService(ac, ruleStore, nil).RouteGetRulesGroupConfig(createRequestContext(orgID, models2.ROLE_VIEWER, nil), folder.Title, groupKey.RuleGroup) + response := createService(ac, ruleStore, nil).RouteGetRulesGroupConfig(createRequestContext(orgID, org.RoleViewer, nil), folder.Title, groupKey.RuleGroup) require.Equal(t, http.StatusAccepted, response.Status()) result := &apimodels.RuleGroupConfigResponse{} @@ -657,7 +659,7 @@ func createService(ac *acMock.Mock, store *store.FakeRuleStore, scheduler schedu } } -func createRequestContext(orgID int64, role models2.RoleType, params map[string]string) *models2.ReqContext { +func createRequestContext(orgID int64, role org.RoleType, params map[string]string) *models2.ReqContext { uri, _ := url.Parse("http://localhost") ctx := web.Context{Req: &http.Request{ URL: uri, @@ -668,7 +670,7 @@ func createRequestContext(orgID int64, role models2.RoleType, params map[string] return &models2.ReqContext{ IsSignedIn: true, - SignedInUser: &models2.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgRole: role, OrgId: orgID, }, diff --git a/pkg/services/ngalert/api/api_testing_test.go b/pkg/services/ngalert/api/api_testing_test.go index f2f33984bcb..4f2bbf13454 100644 --- a/pkg/services/ngalert/api/api_testing_test.go +++ b/pkg/services/ngalert/api/api_testing_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/eval" "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web" ) @@ -26,7 +27,7 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models2.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } @@ -94,7 +95,7 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) { Req: &http.Request{}, }, IsSignedIn: false, - SignedInUser: &models2.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } @@ -149,7 +150,7 @@ func TestRouteEvalQueries(t *testing.T) { Context: &web.Context{ Req: &http.Request{}, }, - SignedInUser: &models2.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } @@ -218,7 +219,7 @@ func TestRouteEvalQueries(t *testing.T) { Req: &http.Request{}, }, IsSignedIn: false, - SignedInUser: &models2.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, }, } diff --git a/pkg/services/ngalert/api/lotex_ruler_test.go b/pkg/services/ngalert/api/lotex_ruler_test.go index 55837eb3bf0..a9800a90406 100644 --- a/pkg/services/ngalert/api/lotex_ruler_test.go +++ b/pkg/services/ngalert/api/lotex_ruler_test.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasourceproxy" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web" ) @@ -113,7 +114,7 @@ type fakeCacheService struct { err error } -func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ *models.SignedInUser, _ bool) (*datasources.DataSource, error) { +func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ *user.SignedInUser, _ bool) (*datasources.DataSource, error) { if f.err != nil { return nil, f.err } @@ -121,7 +122,7 @@ func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ return f.datasource, nil } -func (f fakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) { +func (f fakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { if f.err != nil { return nil, f.err } diff --git a/pkg/services/ngalert/api/util.go b/pkg/services/ngalert/api/util.go index 98556cda844..3ca8a648c7e 100644 --- a/pkg/services/ngalert/api/util.go +++ b/pkg/services/ngalert/api/util.go @@ -21,6 +21,7 @@ import ( "github.com/grafana/grafana/pkg/services/datasources" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web" ) @@ -188,7 +189,7 @@ func messageExtractor(resp *response.NormalResponse) (interface{}, error) { return map[string]string{"message": string(resp.Body())}, nil } -func validateCondition(ctx context.Context, c ngmodels.Condition, user *models.SignedInUser, skipCache bool, datasourceCache datasources.CacheService) error { +func validateCondition(ctx context.Context, c ngmodels.Condition, user *user.SignedInUser, skipCache bool, datasourceCache datasources.CacheService) error { if len(c.Data) == 0 { return nil } @@ -215,7 +216,7 @@ func conditionValidator(c *models.ReqContext, cache datasources.CacheService) fu } } -func validateQueriesAndExpressions(ctx context.Context, data []ngmodels.AlertQuery, user *models.SignedInUser, skipCache bool, datasourceCache datasources.CacheService) (map[string]struct{}, error) { +func validateQueriesAndExpressions(ctx context.Context, data []ngmodels.AlertQuery, user *user.SignedInUser, skipCache bool, datasourceCache datasources.CacheService) (map[string]struct{}, error) { refIDs := make(map[string]struct{}) if len(data) == 0 { return nil, nil diff --git a/pkg/services/ngalert/eval/eval.go b/pkg/services/ngalert/eval/eval.go index 24f261b8b9b..64d7720267b 100644 --- a/pkg/services/ngalert/eval/eval.go +++ b/pkg/services/ngalert/eval/eval.go @@ -15,10 +15,11 @@ import ( "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/expr/classic" "github.com/grafana/grafana/pkg/infra/log" - m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/secrets" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -195,9 +196,9 @@ func getExprRequest(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, d if expr.IsDataSource(q.DatasourceUID) { ds = expr.DataSourceModel() } else { - ds, err = dsCacheService.GetDatasourceByUID(ctx.Ctx, q.DatasourceUID, &m.SignedInUser{ + ds, err = dsCacheService.GetDatasourceByUID(ctx.Ctx, q.DatasourceUID, &user.SignedInUser{ OrgId: ctx.OrgID, - OrgRole: m.ROLE_ADMIN, // Get DS as admin for service, API calls (test/post) must check permissions based on user. + OrgRole: org.RoleAdmin, // Get DS as admin for service, API calls (test/post) must check permissions based on user. }, true) if err != nil { return nil, err diff --git a/pkg/services/ngalert/schedule/schedule.go b/pkg/services/ngalert/schedule/schedule.go index bce902edece..a9d124b9333 100644 --- a/pkg/services/ngalert/schedule/schedule.go +++ b/pkg/services/ngalert/schedule/schedule.go @@ -9,7 +9,6 @@ import ( prometheusModel "github.com/prometheus/common/model" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/eval" @@ -17,6 +16,8 @@ import ( ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/state" "github.com/grafana/grafana/pkg/services/ngalert/store" + "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/benbjohnson/clock" @@ -468,9 +469,9 @@ func (sch *schedule) getRuleExtraLabels(ctx context.Context, alertRule *ngmodels extraLabels[prometheusModel.AlertNameLabel] = alertRule.Title extraLabels[ngmodels.RuleUIDLabel] = alertRule.UID - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 0, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, OrgId: alertRule.OrgID, } diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index cb9ab88d60f..e51db2ff526 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -12,6 +12,7 @@ import ( ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -48,9 +49,9 @@ type RuleStore interface { // GetRuleGroups returns the unique rule groups across all organizations. GetRuleGroups(ctx context.Context, query *ngmodels.ListRuleGroupsQuery) error GetRuleGroupInterval(ctx context.Context, orgID int64, namespaceUID string, ruleGroup string) (int64, error) - GetUserVisibleNamespaces(context.Context, int64, *models.SignedInUser) (map[string]*models.Folder, error) - GetNamespaceByTitle(context.Context, string, int64, *models.SignedInUser, bool) (*models.Folder, error) - GetNamespaceByUID(context.Context, string, int64, *models.SignedInUser) (*models.Folder, error) + GetUserVisibleNamespaces(context.Context, int64, *user.SignedInUser) (map[string]*models.Folder, error) + GetNamespaceByTitle(context.Context, string, int64, *user.SignedInUser, bool) (*models.Folder, error) + GetNamespaceByUID(context.Context, string, int64, *user.SignedInUser) (*models.Folder, error) // InsertAlertRules will insert all alert rules passed into the function // and return the map of uuid to id. InsertAlertRules(ctx context.Context, rule []ngmodels.AlertRule) (map[string]int64, error) @@ -341,7 +342,7 @@ func (st DBstore) GetRuleGroupInterval(ctx context.Context, orgID int64, namespa } // GetUserVisibleNamespaces returns the folders that are visible to the user and have at least one alert in it -func (st DBstore) GetUserVisibleNamespaces(ctx context.Context, orgID int64, user *models.SignedInUser) (map[string]*models.Folder, error) { +func (st DBstore) GetUserVisibleNamespaces(ctx context.Context, orgID int64, user *user.SignedInUser) (map[string]*models.Folder, error) { namespaceMap := make(map[string]*models.Folder) searchQuery := models.FindPersistedDashboardsQuery{ @@ -385,7 +386,7 @@ func (st DBstore) GetUserVisibleNamespaces(ctx context.Context, orgID int64, use } // GetNamespaceByTitle is a handler for retrieving a namespace by its title. Alerting rules follow a Grafana folder-like structure which we call namespaces. -func (st DBstore) GetNamespaceByTitle(ctx context.Context, namespace string, orgID int64, user *models.SignedInUser, withCanSave bool) (*models.Folder, error) { +func (st DBstore) GetNamespaceByTitle(ctx context.Context, namespace string, orgID int64, user *user.SignedInUser, withCanSave bool) (*models.Folder, error) { folder, err := st.FolderService.GetFolderByTitle(ctx, user, orgID, namespace) if err != nil { return nil, err @@ -406,7 +407,7 @@ func (st DBstore) GetNamespaceByTitle(ctx context.Context, namespace string, org } // GetNamespaceByUID is a handler for retrieving a namespace by its UID. Alerting rules follow a Grafana folder-like structure which we call namespaces. -func (st DBstore) GetNamespaceByUID(ctx context.Context, uid string, orgID int64, user *models.SignedInUser) (*models.Folder, error) { +func (st DBstore) GetNamespaceByUID(ctx context.Context, uid string, orgID int64, user *user.SignedInUser) (*models.Folder, error) { folder, err := st.FolderService.GetFolderByUID(ctx, user, orgID, uid) if err != nil { return nil, err diff --git a/pkg/services/ngalert/store/testing.go b/pkg/services/ngalert/store/testing.go index d3a704ddf1e..3abd3da304d 100644 --- a/pkg/services/ngalert/store/testing.go +++ b/pkg/services/ngalert/store/testing.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/services/annotations" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" models2 "github.com/grafana/grafana/pkg/models" @@ -262,7 +263,7 @@ func (f *FakeRuleStore) GetRuleGroups(_ context.Context, q *models.ListRuleGroup return nil } -func (f *FakeRuleStore) GetUserVisibleNamespaces(_ context.Context, orgID int64, _ *models2.SignedInUser) (map[string]*models2.Folder, error) { +func (f *FakeRuleStore) GetUserVisibleNamespaces(_ context.Context, orgID int64, _ *user.SignedInUser) (map[string]*models2.Folder, error) { f.mtx.Lock() defer f.mtx.Unlock() @@ -279,7 +280,7 @@ func (f *FakeRuleStore) GetUserVisibleNamespaces(_ context.Context, orgID int64, return namespacesMap, nil } -func (f *FakeRuleStore) GetNamespaceByTitle(_ context.Context, title string, orgID int64, _ *models2.SignedInUser, _ bool) (*models2.Folder, error) { +func (f *FakeRuleStore) GetNamespaceByTitle(_ context.Context, title string, orgID int64, _ *user.SignedInUser, _ bool) (*models2.Folder, error) { folders := f.Folders[orgID] for _, folder := range folders { if folder.Title == title { @@ -289,7 +290,7 @@ func (f *FakeRuleStore) GetNamespaceByTitle(_ context.Context, title string, org return nil, fmt.Errorf("not found") } -func (f *FakeRuleStore) GetNamespaceByUID(_ context.Context, uid string, orgID int64, _ *models2.SignedInUser) (*models2.Folder, error) { +func (f *FakeRuleStore) GetNamespaceByUID(_ context.Context, uid string, orgID int64, _ *user.SignedInUser) (*models2.Folder, error) { f.RecordedOps = append(f.RecordedOps, GenericRecordedQuery{ Name: "GetNamespaceByUID", Params: []interface{}{orgID, uid}, diff --git a/pkg/services/oauthtoken/oauth_token.go b/pkg/services/oauthtoken/oauth_token.go index 07772864626..49d516d0872 100644 --- a/pkg/services/oauthtoken/oauth_token.go +++ b/pkg/services/oauthtoken/oauth_token.go @@ -24,7 +24,7 @@ type Service struct { } type OAuthTokenService interface { - GetCurrentOAuthToken(context.Context, *models.SignedInUser) *oauth2.Token + GetCurrentOAuthToken(context.Context, *user.SignedInUser) *oauth2.Token IsOAuthPassThruEnabled(*datasources.DataSource) bool } @@ -36,7 +36,7 @@ func ProvideService(socialService social.Service, authInfoService login.AuthInfo } // GetCurrentOAuthToken returns the OAuth token, if any, for the authenticated user. Will try to refresh the token if it has expired. -func (o *Service) GetCurrentOAuthToken(ctx context.Context, usr *models.SignedInUser) *oauth2.Token { +func (o *Service) GetCurrentOAuthToken(ctx context.Context, usr *user.SignedInUser) *oauth2.Token { if usr == nil { // No user, therefore no token return nil diff --git a/pkg/services/org/model.go b/pkg/services/org/model.go index 503cae62f17..d6f10ae0b87 100644 --- a/pkg/services/org/model.go +++ b/pkg/services/org/model.go @@ -2,6 +2,8 @@ package org import ( "errors" + "fmt" + "strings" "time" ) @@ -39,9 +41,9 @@ type OrgUser struct { type RoleType string const ( - ROLE_VIEWER RoleType = "Viewer" - ROLE_EDITOR RoleType = "Editor" - ROLE_ADMIN RoleType = "Admin" + RoleViewer RoleType = "Viewer" + RoleEditor RoleType = "Editor" + RoleAdmin RoleType = "Admin" ) type CreateOrgCommand struct { @@ -58,3 +60,57 @@ type GetOrgIDForNewUserCommand struct { OrgName string SkipOrgSetup bool } + +func (r RoleType) IsValid() bool { + return r == RoleViewer || r == RoleAdmin || r == RoleEditor +} + +func (r RoleType) Includes(other RoleType) bool { + if r == RoleAdmin { + return true + } + + if r == RoleEditor { + return other != RoleAdmin + } + + return r == other +} + +func (r RoleType) Children() []RoleType { + switch r { + case RoleAdmin: + return []RoleType{RoleEditor, RoleViewer} + case RoleEditor: + return []RoleType{RoleViewer} + default: + return nil + } +} + +func (r RoleType) Parents() []RoleType { + switch r { + case RoleEditor: + return []RoleType{RoleAdmin} + case RoleViewer: + return []RoleType{RoleEditor, RoleAdmin} + 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 = RoleViewer + } + + return nil +} diff --git a/pkg/services/plugindashboards/service/dashboard_updater.go b/pkg/services/plugindashboards/service/dashboard_updater.go index d5564f8eb19..6fbc83afa33 100644 --- a/pkg/services/plugindashboards/service/dashboard_updater.go +++ b/pkg/services/plugindashboards/service/dashboard_updater.go @@ -10,8 +10,10 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/dashboardimport" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/plugindashboards" "github.com/grafana/grafana/pkg/services/pluginsettings" + "github.com/grafana/grafana/pkg/services/user" ) func ProvideDashboardUpdater(bus bus.Bus, pluginStore plugins.Store, pluginDashboardService plugindashboards.Service, @@ -170,7 +172,7 @@ func (du *DashboardUpdater) autoUpdateAppDashboard(ctx context.Context, pluginDa pluginDashInfo.Revision, "oldRev", pluginDashInfo.ImportedRevision) _, err = du.dashboardImportService.ImportDashboard(ctx, &dashboardimport.ImportDashboardRequest{ PluginId: pluginDashInfo.PluginId, - User: &models.SignedInUser{UserId: 0, OrgRole: models.ROLE_ADMIN, OrgId: orgID}, + User: &user.SignedInUser{UserId: 0, OrgRole: org.RoleAdmin, OrgId: orgID}, Path: pluginDashInfo.Reference, FolderId: 0, Dashboard: resp.Dashboard.Data, diff --git a/pkg/services/plugindashboards/service/dashboard_updater_test.go b/pkg/services/plugindashboards/service/dashboard_updater_test.go index 8b5a008766b..1196647cbaf 100644 --- a/pkg/services/plugindashboards/service/dashboard_updater_test.go +++ b/pkg/services/plugindashboards/service/dashboard_updater_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/dashboardimport" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/plugindashboards" "github.com/grafana/grafana/pkg/services/pluginsettings" "github.com/grafana/grafana/pkg/services/pluginsettings/service" @@ -192,7 +193,7 @@ func TestDashboardUpdater(t *testing.T) { require.Equal(t, "test", ctx.importDashboardArgs[0].PluginId) require.Equal(t, "updated.json", ctx.importDashboardArgs[0].Path) require.Equal(t, int64(2), ctx.importDashboardArgs[0].User.OrgId) - require.Equal(t, models.ROLE_ADMIN, ctx.importDashboardArgs[0].User.OrgRole) + require.Equal(t, org.RoleAdmin, ctx.importDashboardArgs[0].User.OrgRole) require.Equal(t, int64(0), ctx.importDashboardArgs[0].FolderId) require.True(t, ctx.importDashboardArgs[0].Overwrite) }) @@ -319,21 +320,21 @@ func TestDashboardUpdater(t *testing.T) { require.Equal(t, "test", ctx.importDashboardArgs[0].PluginId) require.Equal(t, "dashboard1.json", ctx.importDashboardArgs[0].Path) require.Equal(t, int64(2), ctx.importDashboardArgs[0].User.OrgId) - require.Equal(t, models.ROLE_ADMIN, ctx.importDashboardArgs[0].User.OrgRole) + require.Equal(t, org.RoleAdmin, ctx.importDashboardArgs[0].User.OrgRole) require.Equal(t, int64(0), ctx.importDashboardArgs[0].FolderId) require.True(t, ctx.importDashboardArgs[0].Overwrite) require.Equal(t, "test", ctx.importDashboardArgs[1].PluginId) require.Equal(t, "dashboard2.json", ctx.importDashboardArgs[1].Path) require.Equal(t, int64(2), ctx.importDashboardArgs[1].User.OrgId) - require.Equal(t, models.ROLE_ADMIN, ctx.importDashboardArgs[1].User.OrgRole) + require.Equal(t, org.RoleAdmin, ctx.importDashboardArgs[1].User.OrgRole) require.Equal(t, int64(0), ctx.importDashboardArgs[1].FolderId) require.True(t, ctx.importDashboardArgs[1].Overwrite) require.Equal(t, "test", ctx.importDashboardArgs[2].PluginId) require.Equal(t, "dashboard3.json", ctx.importDashboardArgs[2].Path) require.Equal(t, int64(2), ctx.importDashboardArgs[2].User.OrgId) - require.Equal(t, models.ROLE_ADMIN, ctx.importDashboardArgs[2].User.OrgRole) + require.Equal(t, org.RoleAdmin, ctx.importDashboardArgs[2].User.OrgRole) require.Equal(t, int64(0), ctx.importDashboardArgs[2].FolderId) require.True(t, ctx.importDashboardArgs[2].Overwrite) }) diff --git a/pkg/services/preference/prefimpl/store_test.go b/pkg/services/preference/prefimpl/store_test.go index 374454be7b0..395ebc4376a 100644 --- a/pkg/services/preference/prefimpl/store_test.go +++ b/pkg/services/preference/prefimpl/store_test.go @@ -6,9 +6,9 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/grafana/grafana/pkg/models" pref "github.com/grafana/grafana/pkg/services/preference" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -117,7 +117,7 @@ func TestIntegrationPreferencesDataAccess(t *testing.T) { ss := sqlstore.InitTestDB(t) prefStore := sqlStore{db: ss} id, err := prefStore.Insert(context.Background(), &pref.Preference{ - UserID: models.SignedInUser{}.UserId, + UserID: user.SignedInUser{}.UserId, Theme: "dark", Timezone: "browser", HomeDashboardID: 5, @@ -160,7 +160,7 @@ func TestIntegrationPreferencesDataAccess(t *testing.T) { t.Run("insert preference that does not exist", func(t *testing.T) { _, err := prefStore.Insert(context.Background(), &pref.Preference{ - UserID: models.SignedInUser{}.UserId, + UserID: user.SignedInUser{}.UserId, Created: time.Now(), Updated: time.Now(), JSONData: &pref.PreferenceJSONData{}, diff --git a/pkg/services/publicdashboards/api/api_test.go b/pkg/services/publicdashboards/api/api_test.go index bc2af0cc0ae..e51c8bbbb51 100644 --- a/pkg/services/publicdashboards/api/api_test.go +++ b/pkg/services/publicdashboards/api/api_test.go @@ -31,6 +31,7 @@ import ( . "github.com/grafana/grafana/pkg/services/publicdashboards/models" publicdashboardsService "github.com/grafana/grafana/pkg/services/publicdashboards/service" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/web" ) @@ -334,7 +335,7 @@ func TestAPIQueryPublicDashboard(t *testing.T) { fakeDashboardService.On("GetPublicDashboard", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil) fakeDashboardService.On("GetPublicDashboardConfig", mock.Anything, mock.Anything, mock.Anything).Return(&PublicDashboard{}, nil) - fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&models.SignedInUser{}, nil) + fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&user.SignedInUser{}, nil) fakeDashboardService.On("BuildPublicDashboardMetricRequest", mock.Anything, mock.Anything, mock.Anything, int64(2)).Return(dtos.MetricRequest{ Queries: []*simplejson.Json{ simplejson.MustJson([]byte(` @@ -385,7 +386,7 @@ func TestAPIQueryPublicDashboard(t *testing.T) { fakeDashboardService.On("GetPublicDashboard", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil) fakeDashboardService.On("GetPublicDashboardConfig", mock.Anything, mock.Anything, mock.Anything).Return(&PublicDashboard{}, nil) - fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&models.SignedInUser{}, nil) + fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&user.SignedInUser{}, nil) fakeDashboardService.On("BuildPublicDashboardMetricRequest", mock.Anything, mock.Anything, mock.Anything, int64(2)).Return(dtos.MetricRequest{ Queries: []*simplejson.Json{ simplejson.MustJson([]byte(` @@ -415,7 +416,7 @@ func TestAPIQueryPublicDashboard(t *testing.T) { fakeDashboardService.On("GetPublicDashboard", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil) fakeDashboardService.On("GetPublicDashboardConfig", mock.Anything, mock.Anything, mock.Anything).Return(&PublicDashboard{}, nil) - fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&models.SignedInUser{}, nil) + fakeDashboardService.On("BuildAnonymousUser", mock.Anything, mock.Anything, mock.Anything).Return(&user.SignedInUser{}, nil) fakeDashboardService.On("BuildPublicDashboardMetricRequest", mock.Anything, mock.Anything, mock.Anything, int64(2)).Return(dtos.MetricRequest{ Queries: []*simplejson.Json{ simplejson.MustJson([]byte(` diff --git a/pkg/services/publicdashboards/api/common_test.go b/pkg/services/publicdashboards/api/common_test.go index d500c8d6e90..a9945f507bc 100644 --- a/pkg/services/publicdashboards/api/common_test.go +++ b/pkg/services/publicdashboards/api/common_test.go @@ -21,8 +21,10 @@ import ( "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" "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/publicdashboards" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes" datasourceService "github.com/grafana/grafana/pkg/services/datasources/service" @@ -75,7 +77,7 @@ func setupTestServer( Logger: log.New("publicdashboards-test"), // Set signed in user. We might not actually need to do this. - SignedInUser: &models.SignedInUser{UserId: 1, OrgId: 1, OrgRole: models.ROLE_ADMIN, Login: "testUser"}, + SignedInUser: &user.SignedInUser{UserId: 1, OrgId: 1, OrgRole: org.RoleAdmin, Login: "testUser"}, } c.Req = c.Req.WithContext(ctxkey.Set(c.Req.Context(), ctx)) }) @@ -151,7 +153,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 } diff --git a/pkg/services/publicdashboards/public_dashboard_service_mock.go b/pkg/services/publicdashboards/public_dashboard_service_mock.go index d5ee71d3ab4..4f1362deb6b 100644 --- a/pkg/services/publicdashboards/public_dashboard_service_mock.go +++ b/pkg/services/publicdashboards/public_dashboard_service_mock.go @@ -9,6 +9,7 @@ import ( mock "github.com/stretchr/testify/mock" models "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" publicdashboardsmodels "github.com/grafana/grafana/pkg/services/publicdashboards/models" @@ -21,15 +22,15 @@ type FakePublicDashboardService struct { } // BuildAnonymousUser provides a mock function with given fields: ctx, dashboard -func (_m *FakePublicDashboardService) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error) { +func (_m *FakePublicDashboardService) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*user.SignedInUser, error) { ret := _m.Called(ctx, dashboard) - var r0 *models.SignedInUser - if rf, ok := ret.Get(0).(func(context.Context, *models.Dashboard) *models.SignedInUser); ok { + var r0 *user.SignedInUser + if rf, ok := ret.Get(0).(func(context.Context, *models.Dashboard) *user.SignedInUser); ok { r0 = rf(ctx, dashboard) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.SignedInUser) + r0 = ret.Get(0).(*user.SignedInUser) } } diff --git a/pkg/services/publicdashboards/publicdashboard.go b/pkg/services/publicdashboards/publicdashboard.go index c1c6e9feecd..bae58c3a7f1 100644 --- a/pkg/services/publicdashboards/publicdashboard.go +++ b/pkg/services/publicdashboards/publicdashboard.go @@ -6,13 +6,14 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/models" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" + "github.com/grafana/grafana/pkg/services/user" ) // These are the api contracts. The API should match the underlying service and store //go:generate mockery --name Service --structname FakePublicDashboardService --inpackage --filename public_dashboard_service_mock.go type Service interface { - BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error) + BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*user.SignedInUser, error) GetPublicDashboard(ctx context.Context, accessToken string) (*models.Dashboard, error) GetDashboard(ctx context.Context, dashboardUid string) (*models.Dashboard, error) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error) diff --git a/pkg/services/publicdashboards/service/service.go b/pkg/services/publicdashboards/service/service.go index 3c204a4c463..c40d83549f9 100644 --- a/pkg/services/publicdashboards/service/service.go +++ b/pkg/services/publicdashboards/service/service.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/publicdashboards" . "github.com/grafana/grafana/pkg/services/publicdashboards/models" "github.com/grafana/grafana/pkg/services/publicdashboards/validation" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -187,11 +188,11 @@ func (pd *PublicDashboardServiceImpl) BuildPublicDashboardMetricRequest(ctx cont } // BuildAnonymousUser creates a user with permissions to read from all datasources used in the dashboard -func (pd *PublicDashboardServiceImpl) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error) { +func (pd *PublicDashboardServiceImpl) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*user.SignedInUser, error) { datasourceUids := models.GetUniqueDashboardDatasourceUids(dashboard.Data) // Create a temp user with read-only datasource permissions - anonymousUser := &models.SignedInUser{OrgId: dashboard.OrgId, Permissions: make(map[int64]map[string][]string)} + anonymousUser := &user.SignedInUser{OrgId: dashboard.OrgId, Permissions: make(map[int64]map[string][]string)} permissions := make(map[string][]string) queryScopes := make([]string, 0) readScopes := make([]string, 0) diff --git a/pkg/services/query/query.go b/pkg/services/query/query.go index 2ddb7dec1b9..e908ff1295d 100644 --- a/pkg/services/query/query.go +++ b/pkg/services/query/query.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/plugins/adapters" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/oauthtoken" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/grafanads" "github.com/grafana/grafana/pkg/tsdb/legacydata" @@ -72,7 +73,7 @@ func (s *Service) Run(ctx context.Context) error { } // QueryData can process queries and return query responses. -func (s *Service) QueryData(ctx context.Context, user *models.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest, handleExpressions bool) (*backend.QueryDataResponse, error) { +func (s *Service) QueryData(ctx context.Context, user *user.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest, handleExpressions bool) (*backend.QueryDataResponse, error) { parsedReq, err := s.parseMetricRequest(ctx, user, skipCache, reqDTO) if err != nil { return nil, err @@ -84,7 +85,7 @@ func (s *Service) QueryData(ctx context.Context, user *models.SignedInUser, skip } // QueryData can process queries and return query responses. -func (s *Service) QueryDataMultipleSources(ctx context.Context, user *models.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest, handleExpressions bool) (*backend.QueryDataResponse, error) { +func (s *Service) QueryDataMultipleSources(ctx context.Context, user *user.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest, handleExpressions bool) (*backend.QueryDataResponse, error) { byDataSource := models.GroupQueriesByDataSource(reqDTO.Queries) if len(byDataSource) == 1 { @@ -111,7 +112,7 @@ func (s *Service) QueryDataMultipleSources(ctx context.Context, user *models.Sig } // handleExpressions handles POST /api/ds/query when there is an expression. -func (s *Service) handleExpressions(ctx context.Context, user *models.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { +func (s *Service) handleExpressions(ctx context.Context, user *user.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { exprReq := expr.Request{ OrgId: user.OrgId, Queries: []expr.Query{}, @@ -143,7 +144,7 @@ func (s *Service) handleExpressions(ctx context.Context, user *models.SignedInUs return qdr, nil } -func (s *Service) handleQueryData(ctx context.Context, user *models.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { +func (s *Service) handleQueryData(ctx context.Context, user *user.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { ds := parsedReq.parsedQueries[0].datasource if err := s.pluginRequestValidator.Validate(ds.Url, nil); err != nil { return nil, datasources.ErrDataSourceAccessDenied @@ -235,7 +236,7 @@ func customHeaders(jsonData *simplejson.Json, decryptedJsonData map[string]strin return headers } -func (s *Service) parseMetricRequest(ctx context.Context, user *models.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest) (*parsedRequest, error) { +func (s *Service) parseMetricRequest(ctx context.Context, user *user.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest) (*parsedRequest, error) { if len(reqDTO.Queries) == 0 { return nil, NewErrBadQuery("no queries found") } @@ -299,7 +300,7 @@ func (s *Service) parseMetricRequest(ctx context.Context, user *models.SignedInU return req, nil } -func (s *Service) getDataSourceFromQuery(ctx context.Context, user *models.SignedInUser, skipCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) { +func (s *Service) getDataSourceFromQuery(ctx context.Context, user *user.SignedInUser, skipCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) { var err error uid := query.Get("datasource").Get("uid").MustString() diff --git a/pkg/services/query/query_test.go b/pkg/services/query/query_test.go index 049c5c1d607..567d9b87f48 100644 --- a/pkg/services/query/query_test.go +++ b/pkg/services/query/query_test.go @@ -12,7 +12,6 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/plugins" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/datasources" @@ -22,6 +21,7 @@ import ( "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" ) func TestQueryData(t *testing.T) { @@ -152,7 +152,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 } @@ -164,11 +164,11 @@ type fakeDataSourceCache struct { ds *datasources.DataSource } -func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) { +func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { return c.ds, nil } -func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) { +func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { return c.ds, nil } diff --git a/pkg/services/queryhistory/database.go b/pkg/services/queryhistory/database.go index 1db7c202cc6..602bdc536d7 100644 --- a/pkg/services/queryhistory/database.go +++ b/pkg/services/queryhistory/database.go @@ -6,13 +6,13 @@ import ( "strconv" "time" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) // createQuery adds a query into query history -func (s QueryHistoryService) createQuery(ctx context.Context, user *models.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) { +func (s QueryHistoryService) createQuery(ctx context.Context, user *user.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) { queryHistory := QueryHistory{ OrgID: user.OrgId, UID: util.GenerateShortUID(), @@ -45,7 +45,7 @@ func (s QueryHistoryService) createQuery(ctx context.Context, user *models.Signe } // searchQueries searches for queries in query history based on provided parameters -func (s QueryHistoryService) searchQueries(ctx context.Context, user *models.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) { +func (s QueryHistoryService) searchQueries(ctx context.Context, user *user.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) { var dtos []QueryHistoryDTO var allQueries []interface{} @@ -109,7 +109,7 @@ func (s QueryHistoryService) searchQueries(ctx context.Context, user *models.Sig return response, nil } -func (s QueryHistoryService) deleteQuery(ctx context.Context, user *models.SignedInUser, UID string) (int64, error) { +func (s QueryHistoryService) deleteQuery(ctx context.Context, user *user.SignedInUser, UID string) (int64, error) { var queryID int64 err := s.SQLStore.WithTransactionalDbSession(ctx, func(session *sqlstore.DBSession) error { // Try to unstar the query first @@ -135,7 +135,7 @@ func (s QueryHistoryService) deleteQuery(ctx context.Context, user *models.Signe } // patchQueryComment searches updates comment for query in query history -func (s QueryHistoryService) patchQueryComment(ctx context.Context, user *models.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) { +func (s QueryHistoryService) patchQueryComment(ctx context.Context, user *user.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) { var queryHistory QueryHistory var isStarred bool @@ -180,7 +180,7 @@ func (s QueryHistoryService) patchQueryComment(ctx context.Context, user *models } // starQuery adds query into query_history_star table together with user_id and org_id -func (s QueryHistoryService) starQuery(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) { +func (s QueryHistoryService) starQuery(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) { var queryHistory QueryHistory var isStarred bool @@ -230,7 +230,7 @@ func (s QueryHistoryService) starQuery(ctx context.Context, user *models.SignedI } // unstarQuery deletes query with with user_id and org_id from query_history_star table -func (s QueryHistoryService) unstarQuery(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) { +func (s QueryHistoryService) unstarQuery(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) { var queryHistory QueryHistory var isStarred bool @@ -273,7 +273,7 @@ func (s QueryHistoryService) unstarQuery(ctx context.Context, user *models.Signe } // migrateQueries adds multiple queries into query history -func (s QueryHistoryService) migrateQueries(ctx context.Context, user *models.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) { +func (s QueryHistoryService) migrateQueries(ctx context.Context, user *user.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) { queryHistories := make([]*QueryHistory, 0, len(cmd.Queries)) starredQueries := make([]*QueryHistoryStar, 0) diff --git a/pkg/services/queryhistory/queryhistory.go b/pkg/services/queryhistory/queryhistory.go index c43eb10099f..f9da7f40937 100644 --- a/pkg/services/queryhistory/queryhistory.go +++ b/pkg/services/queryhistory/queryhistory.go @@ -5,8 +5,8 @@ import ( "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -27,13 +27,13 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister } type Service interface { - CreateQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) - SearchInQueryHistory(ctx context.Context, user *models.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) - DeleteQueryFromQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (int64, error) - PatchQueryCommentInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) - StarQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) - UnstarQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) - MigrateQueriesToQueryHistory(ctx context.Context, user *models.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) + CreateQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) + SearchInQueryHistory(ctx context.Context, user *user.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) + DeleteQueryFromQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (int64, error) + PatchQueryCommentInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) + StarQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) + UnstarQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) + MigrateQueriesToQueryHistory(ctx context.Context, user *user.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) DeleteStaleQueriesInQueryHistory(ctx context.Context, olderThan int64) (int, error) EnforceRowLimitInQueryHistory(ctx context.Context, limit int, starredQueries bool) (int, error) } @@ -45,31 +45,31 @@ type QueryHistoryService struct { log log.Logger } -func (s QueryHistoryService) CreateQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) { +func (s QueryHistoryService) CreateQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, cmd CreateQueryInQueryHistoryCommand) (QueryHistoryDTO, error) { return s.createQuery(ctx, user, cmd) } -func (s QueryHistoryService) SearchInQueryHistory(ctx context.Context, user *models.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) { +func (s QueryHistoryService) SearchInQueryHistory(ctx context.Context, user *user.SignedInUser, query SearchInQueryHistoryQuery) (QueryHistorySearchResult, error) { return s.searchQueries(ctx, user, query) } -func (s QueryHistoryService) DeleteQueryFromQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (int64, error) { +func (s QueryHistoryService) DeleteQueryFromQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (int64, error) { return s.deleteQuery(ctx, user, UID) } -func (s QueryHistoryService) PatchQueryCommentInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) { +func (s QueryHistoryService) PatchQueryCommentInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string, cmd PatchQueryCommentInQueryHistoryCommand) (QueryHistoryDTO, error) { return s.patchQueryComment(ctx, user, UID, cmd) } -func (s QueryHistoryService) StarQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) { +func (s QueryHistoryService) StarQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) { return s.starQuery(ctx, user, UID) } -func (s QueryHistoryService) UnstarQueryInQueryHistory(ctx context.Context, user *models.SignedInUser, UID string) (QueryHistoryDTO, error) { +func (s QueryHistoryService) UnstarQueryInQueryHistory(ctx context.Context, user *user.SignedInUser, UID string) (QueryHistoryDTO, error) { return s.unstarQuery(ctx, user, UID) } -func (s QueryHistoryService) MigrateQueriesToQueryHistory(ctx context.Context, user *models.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) { +func (s QueryHistoryService) MigrateQueriesToQueryHistory(ctx context.Context, user *user.SignedInUser, cmd MigrateQueriesToQueryHistoryCommand) (int, int, error) { return s.migrateQueries(ctx, user, cmd) } diff --git a/pkg/services/queryhistory/queryhistory_test.go b/pkg/services/queryhistory/queryhistory_test.go index d1f8a354336..1eb4fa4ea28 100644 --- a/pkg/services/queryhistory/queryhistory_test.go +++ b/pkg/services/queryhistory/queryhistory_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" + "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,13 +53,13 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo service.Cfg.QueryHistoryEnabled = true - usr := models.SignedInUser{ + usr := user.SignedInUser{ UserId: testUserID, Name: "Signed In User", Login: "signed_in_user", Email: "signed.in.user@test.com", OrgId: testOrgID, - OrgRole: models.ROLE_VIEWER, + OrgRole: org.RoleViewer, LastSeenAt: time.Now(), } diff --git a/pkg/services/queryhistory/writers.go b/pkg/services/queryhistory/writers.go index 4b8e4cf7087..0c07639e457 100644 --- a/pkg/services/queryhistory/writers.go +++ b/pkg/services/queryhistory/writers.go @@ -4,8 +4,8 @@ import ( "bytes" "strings" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) func writeStarredSQL(query SearchInQueryHistoryQuery, sqlStore *sqlstore.SQLStore, builder *sqlstore.SQLBuilder) { @@ -22,7 +22,7 @@ func writeStarredSQL(query SearchInQueryHistoryQuery, sqlStore *sqlstore.SQLStor } } -func writeFiltersSQL(query SearchInQueryHistoryQuery, user *models.SignedInUser, sqlStore *sqlstore.SQLStore, builder *sqlstore.SQLBuilder) { +func writeFiltersSQL(query SearchInQueryHistoryQuery, user *user.SignedInUser, sqlStore *sqlstore.SQLStore, builder *sqlstore.SQLBuilder) { params := []interface{}{user.OrgId, user.UserId, query.From, query.To, "%" + query.SearchString + "%", "%" + query.SearchString + "%"} var sql bytes.Buffer sql.WriteString(" WHERE query_history.org_id = ? AND query_history.created_by = ? AND query_history.created_at >= ? AND query_history.created_at <= ? AND (query_history.queries " + sqlStore.Dialect.LikeStr() + " ? OR query_history.comment " + sqlStore.Dialect.LikeStr() + " ?) ") diff --git a/pkg/services/rendering/interface.go b/pkg/services/rendering/interface.go index 6a7197f12e9..a7accdffec4 100644 --- a/pkg/services/rendering/interface.go +++ b/pkg/services/rendering/interface.go @@ -6,6 +6,7 @@ import ( "time" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" ) var ErrTimeout = errors.New("timeout error - you can set timeout in seconds with &timeout url parameter") @@ -27,7 +28,7 @@ type TimeoutOpts struct { type AuthOpts struct { OrgID int64 UserID int64 - OrgRole models.RoleType + OrgRole org.RoleType } func getRequestTimeout(opt TimeoutOpts) time.Duration { diff --git a/pkg/services/screenshot/screenshot.go b/pkg/services/screenshot/screenshot.go index e963448099e..cc83bfb9222 100644 --- a/pkg/services/screenshot/screenshot.go +++ b/pkg/services/screenshot/screenshot.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/components/imguploader" "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/rendering" "github.com/grafana/grafana/pkg/setting" ) @@ -226,7 +227,7 @@ func (s *RemoteRenderScreenshotService) Take(ctx context.Context, opts Screensho renderOpts := rendering.Opts{ AuthOpts: rendering.AuthOpts{ OrgID: q.Result.OrgId, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, ErrorOpts: rendering.ErrorOpts{ ErrorConcurrentLimitReached: true, diff --git a/pkg/services/screenshot/screenshot_test.go b/pkg/services/screenshot/screenshot_test.go index 729fcf8297b..303109008a1 100644 --- a/pkg/services/screenshot/screenshot_test.go +++ b/pkg/services/screenshot/screenshot_test.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/components/imguploader" "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/rendering" "github.com/grafana/grafana/pkg/setting" ) @@ -94,7 +95,7 @@ func TestBrowserScreenshotService(t *testing.T) { renderOpts := rendering.Opts{ AuthOpts: rendering.AuthOpts{ OrgID: 2, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, }, ErrorOpts: rendering.ErrorOpts{ ErrorConcurrentLimitReached: true, diff --git a/pkg/services/search/service.go b/pkg/services/search/service.go index 23d640b67e5..d33a03f695d 100644 --- a/pkg/services/search/service.go +++ b/pkg/services/search/service.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/star" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/models" @@ -30,7 +31,7 @@ type Query struct { Title string Tags []string OrgId int64 - SignedInUser *models.SignedInUser + SignedInUser *user.SignedInUser Limit int64 Page int64 IsStarred bool diff --git a/pkg/services/search/service_test.go b/pkg/services/search/service_test.go index 9d9ba74d77e..223780aa1ff 100644 --- a/pkg/services/search/service_test.go +++ b/pkg/services/search/service_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/sqlstore/mockstore" "github.com/grafana/grafana/pkg/services/star" "github.com/grafana/grafana/pkg/services/star/startest" + "github.com/grafana/grafana/pkg/services/user" ) func TestSearch_SortedResults(t *testing.T) { @@ -29,7 +30,7 @@ func TestSearch_SortedResults(t *testing.T) { &models.Hit{ID: 17, Title: "FOLDER", Type: "dash-folder"}, } }).Return(nil) - ms.ExpectedSignedInUser = &models.SignedInUser{IsGrafanaAdmin: true} + ms.ExpectedSignedInUser = &user.SignedInUser{IsGrafanaAdmin: true} ss.ExpectedUserStars = &star.GetUserStarsResult{UserStars: map[int64]bool{10: true, 12: true}} svc := &SearchService{ sqlstore: ms, @@ -39,7 +40,7 @@ func TestSearch_SortedResults(t *testing.T) { query := &Query{ Limit: 2000, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ IsGrafanaAdmin: true, }, } diff --git a/pkg/services/searchV2/allowed_actions.go b/pkg/services/searchV2/allowed_actions.go index bf720efb979..d6519c9e6b0 100644 --- a/pkg/services/searchV2/allowed_actions.go +++ b/pkg/services/searchV2/allowed_actions.go @@ -9,13 +9,13 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" - "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/datasources" + "github.com/grafana/grafana/pkg/services/user" ) -func (s *StandardSearchService) addAllowedActionsField(ctx context.Context, orgId int64, user *models.SignedInUser, response *backend.DataResponse) error { +func (s *StandardSearchService) addAllowedActionsField(ctx context.Context, orgId int64, user *user.SignedInUser, response *backend.DataResponse) error { references, err := getEntityReferences(response) if err != nil { return err @@ -51,7 +51,7 @@ type allowedActions struct { Actions []string `json:"actions"` } -func (s *StandardSearchService) createAllowedActions(ctx context.Context, orgId int64, user *models.SignedInUser, references []entityReferences) ([][]allowedActions, error) { +func (s *StandardSearchService) createAllowedActions(ctx context.Context, orgId int64, user *user.SignedInUser, references []entityReferences) ([][]allowedActions, error) { uidsPerKind := make(map[entityKind][]string) for _, refs := range references { if _, ok := uidsPerKind[refs.entityKind]; !ok { @@ -136,7 +136,7 @@ func (s *StandardSearchService) createAllowedActions(ctx context.Context, orgId return out, nil } -func (s *StandardSearchService) getAllowedActionsByUid(ctx context.Context, user *models.SignedInUser, +func (s *StandardSearchService) getAllowedActionsByUid(ctx context.Context, user *user.SignedInUser, orgID int64, prefix string, resourceIDs []string) map[string][]string { if s.ac.IsDisabled() { return map[string][]string{} diff --git a/pkg/services/searchV2/allowed_actions_test.go b/pkg/services/searchV2/allowed_actions_test.go index ce0ced9f5af..e9e305f265d 100644 --- a/pkg/services/searchV2/allowed_actions_test.go +++ b/pkg/services/searchV2/allowed_actions_test.go @@ -9,11 +9,11 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/experimental" - "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -105,7 +105,7 @@ func TestAllowedActionsForPermissionsWithScopeAll(t *testing.T) { err := frame.UnmarshalJSON([]byte(exampleListFrameJSON)) require.NoError(t, err) - err = service(t).addAllowedActionsField(context.Background(), orgId, &models.SignedInUser{ + err = service(t).addAllowedActionsField(context.Background(), orgId, &user.SignedInUser{ Permissions: map[int64]map[string][]string{ orgId: tt.permissions, }, diff --git a/pkg/services/searchV2/auth.go b/pkg/services/searchV2/auth.go index 35e02808ca9..6db43830661 100644 --- a/pkg/services/searchV2/auth.go +++ b/pkg/services/searchV2/auth.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/permissions" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" ) // ResourceFilter checks if a given a uid (resource identifier) check if we have the requested permission @@ -15,7 +16,7 @@ type ResourceFilter func(uid string) bool // FutureAuthService eventually implemented by the security service type FutureAuthService interface { - GetDashboardReadFilter(user *models.SignedInUser) (ResourceFilter, error) + GetDashboardReadFilter(user *user.SignedInUser) (ResourceFilter, error) } var _ FutureAuthService = (*simpleSQLAuthService)(nil) @@ -29,7 +30,7 @@ type dashIdQueryResult struct { UID string `xorm:"uid"` } -func (a *simpleSQLAuthService) getDashboardTableAuthFilter(user *models.SignedInUser) searchstore.FilterWhere { +func (a *simpleSQLAuthService) getDashboardTableAuthFilter(user *user.SignedInUser) searchstore.FilterWhere { if a.ac.IsDisabled() { return permissions.DashboardPermissionFilter{ OrgRole: user.OrgRole, @@ -43,7 +44,7 @@ func (a *simpleSQLAuthService) getDashboardTableAuthFilter(user *models.SignedIn return permissions.NewAccessControlDashboardPermissionFilter(user, models.PERMISSION_VIEW, searchstore.TypeDashboard) } -func (a *simpleSQLAuthService) GetDashboardReadFilter(user *models.SignedInUser) (ResourceFilter, error) { +func (a *simpleSQLAuthService) GetDashboardReadFilter(user *user.SignedInUser) (ResourceFilter, error) { filter := a.getDashboardTableAuthFilter(user) rows := make([]*dashIdQueryResult, 0) diff --git a/pkg/services/searchV2/service.go b/pkg/services/searchV2/service.go index b1f6314dc3d..b45b5362746 100644 --- a/pkg/services/searchV2/service.go +++ b/pkg/services/searchV2/service.go @@ -11,8 +11,10 @@ import ( "github.com/grafana/grafana/pkg/registry" "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/store" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -118,21 +120,21 @@ func (s *StandardSearchService) RegisterDashboardIndexExtender(ext DashboardInde s.dashboardIndex.extender = ext.GetDocumentExtender() } -func (s *StandardSearchService) getUser(ctx context.Context, backendUser *backend.User, orgId int64) (*models.SignedInUser, error) { +func (s *StandardSearchService) getUser(ctx context.Context, backendUser *backend.User, orgId int64) (*user.SignedInUser, error) { // TODO: get user & user's permissions from the request context - var user *models.SignedInUser + var usr *user.SignedInUser if s.cfg.AnonymousEnabled && backendUser.Email == "" && backendUser.Login == "" { - org, err := s.sql.GetOrgByName(s.cfg.AnonymousOrgName) + orga, err := s.sql.GetOrgByName(s.cfg.AnonymousOrgName) if err != nil { s.logger.Error("Anonymous access organization error.", "org_name", s.cfg.AnonymousOrgName, "error", err) return nil, err } - user = &models.SignedInUser{ - OrgId: org.Id, - OrgName: org.Name, - OrgRole: models.RoleType(s.cfg.AnonymousOrgRole), + usr = &user.SignedInUser{ + OrgId: orga.Id, + OrgName: orga.Name, + OrgRole: org.RoleType(s.cfg.AnonymousOrgRole), IsAnonymous: true, } } else { @@ -152,32 +154,32 @@ func (s *StandardSearchService) getUser(ctx context.Context, backendUser *backen return nil, errors.New("auth error") } - user = getSignedInUserQuery.Result + usr = getSignedInUserQuery.Result } if s.ac.IsDisabled() { - return user, nil + return usr, nil } - if user.Permissions == nil { - user.Permissions = make(map[int64]map[string][]string) + if usr.Permissions == nil { + usr.Permissions = make(map[int64]map[string][]string) } - if _, ok := user.Permissions[orgId]; ok { + if _, ok := usr.Permissions[orgId]; ok { // permissions as part of the `s.sql.GetSignedInUser` query - return early - return user, nil + return usr, nil } // TODO: ensure this is cached - permissions, err := s.ac.GetUserPermissions(ctx, user, + permissions, err := s.ac.GetUserPermissions(ctx, usr, accesscontrol.Options{ReloadCache: false}) if err != nil { s.logger.Error("failed to retrieve user permissions", "error", err, "email", backendUser.Email) return nil, errors.New("auth error") } - user.Permissions[orgId] = accesscontrol.GroupScopesByAction(permissions) - return user, nil + usr.Permissions[orgId] = accesscontrol.GroupScopesByAction(permissions) + return usr, nil } func (s *StandardSearchService) DoDashboardQuery(ctx context.Context, user *backend.User, orgID int64, q DashboardQuery) *backend.DataResponse { diff --git a/pkg/services/serviceaccounts/api/api.go b/pkg/services/serviceaccounts/api/api.go index 87a16c72bb9..173f76e7dbc 100644 --- a/pkg/services/serviceaccounts/api/api.go +++ b/pkg/services/serviceaccounts/api/api.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/middleware" "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/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/database" "github.com/grafana/grafana/pkg/setting" @@ -234,7 +235,7 @@ func (api *ServiceAccountsAPI) UpdateServiceAccount(c *models.ReqContext) respon }) } -func (api *ServiceAccountsAPI) validateRole(r *models.RoleType, orgRole *models.RoleType) error { +func (api *ServiceAccountsAPI) validateRole(r *org.RoleType, orgRole *org.RoleType) error { if r != nil && !r.IsValid() { return serviceaccounts.ErrServiceAccountInvalidRole } diff --git a/pkg/services/serviceaccounts/api/api_test.go b/pkg/services/serviceaccounts/api/api_test.go index 5dc1e2bdbe6..af62fece90c 100644 --- a/pkg/services/serviceaccounts/api/api_test.go +++ b/pkg/services/serviceaccounts/api/api_test.go @@ -22,10 +22,12 @@ import ( "github.com/grafana/grafana/pkg/services/apikey/apikeyimpl" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" "github.com/grafana/grafana/pkg/services/licensing" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/database" "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/assert" @@ -69,7 +71,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { wantID: "sa-new-sa", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil }, false, @@ -82,7 +84,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { wantID: "sa-new-sa-hp", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil }, false, @@ -96,7 +98,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { wantError: "invalid role value: Random", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil }, false, @@ -109,7 +111,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { wantError: "service account already exists", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil }, false, @@ -122,7 +124,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { wantError: "required value Name must not be empty", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil }, false, @@ -134,7 +136,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { body: map[string]interface{}{}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{}, nil }, false, @@ -155,7 +157,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { testUser := &tests.TestUser{} for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - serviceAccountRequestScenario(t, http.MethodPost, serviceAccountPath, testUser, func(httpmethod string, endpoint string, user *tests.TestUser) { + serviceAccountRequestScenario(t, http.MethodPost, serviceAccountPath, testUser, func(httpmethod string, endpoint string, usr *tests.TestUser) { server, api := setupTestServer(t, &svcmock, routing.NewRouteRegister(), tc.acmock, store, saStore) marshalled, err := json.Marshal(tc.body) require.NoError(t, err) @@ -178,7 +180,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { assert.NotZero(t, sa.Id) assert.Equal(t, tc.body["name"], sa.Name) assert.Equal(t, tc.wantID, sa.Login) - tempUser := &models.SignedInUser{ + tempUser := &user.SignedInUser{ OrgId: 1, UserId: 1, Permissions: map[int64]map[string][]string{ @@ -227,7 +229,7 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) { user: tests.TestUser{Login: "servicetest1@admin", IsServiceAccount: true}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionDelete, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -251,7 +253,7 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) { user: tests.TestUser{Login: "servicetest2@admin", IsServiceAccount: true}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{}, nil }, false, @@ -286,10 +288,10 @@ func setupTestServer(t *testing.T, svc *tests.ServiceAccountMock, a.cfg.ApiKeyMaxSecondsToLive = -1 // disable api key expiration m := web.New() - signedUser := &models.SignedInUser{ + signedUser := &user.SignedInUser{ OrgId: 1, UserId: 1, - OrgRole: models.ROLE_VIEWER, + OrgRole: org.RoleViewer, } m.Use(func(c *web.Context) { @@ -324,7 +326,7 @@ func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) { user: &tests.TestUser{Login: "servicetest1@admin", IsServiceAccount: true}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -336,7 +338,7 @@ func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) { user: &tests.TestUser{Login: "servicetest2@admin", IsServiceAccount: true}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{}, nil }, false, @@ -349,7 +351,7 @@ func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) { Id: 12, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -412,9 +414,9 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { Id int } - viewerRole := models.ROLE_VIEWER - editorRole := models.ROLE_EDITOR - var invalidRole models.RoleType = "InvalidRole" + viewerRole := org.RoleViewer + editorRole := org.RoleEditor + var invalidRole org.RoleType = "InvalidRole" testCases := []testUpdateSATestCase{ { desc: "should be ok to update serviceaccount with permissions", @@ -422,7 +424,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { body: &serviceaccounts.UpdateServiceAccountForm{Name: newString("New Name"), Role: &viewerRole}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -435,7 +437,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { body: &serviceaccounts.UpdateServiceAccountForm{Name: newString("New Name 2"), Role: &editorRole}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -448,7 +450,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { body: &serviceaccounts.UpdateServiceAccountForm{Name: newString("NameB"), Role: &invalidRole}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -461,7 +463,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { body: nil, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{}, nil }, false, @@ -475,7 +477,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) { Id: 12, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, diff --git a/pkg/services/serviceaccounts/api/token_test.go b/pkg/services/serviceaccounts/api/token_test.go index 6ba0af898f2..7545e437413 100644 --- a/pkg/services/serviceaccounts/api/token_test.go +++ b/pkg/services/serviceaccounts/api/token_test.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/components/apikeygen" apikeygenprefix "github.com/grafana/grafana/pkg/components/apikeygenprefixed" "github.com/grafana/grafana/pkg/infra/kvstore" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/apikey" @@ -24,6 +23,7 @@ import ( "github.com/grafana/grafana/pkg/services/serviceaccounts/database" "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -71,7 +71,7 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) { desc: "should be ok to create serviceaccount token with scope all permissions", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -83,7 +83,7 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) { desc: "serviceaccount token should match SA orgID and SA provided in parameters even if specified in body", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -95,7 +95,7 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) { desc: "should be ok to create serviceaccount token with scope id permissions", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, nil }, false, @@ -107,7 +107,7 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) { desc: "should be forbidden to create serviceaccount token if wrong scoped", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:2"}}, nil }, false, @@ -189,7 +189,7 @@ func TestServiceAccountsAPI_DeleteToken(t *testing.T) { keyName: "Test1", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:1"}}, nil }, false, @@ -201,7 +201,7 @@ func TestServiceAccountsAPI_DeleteToken(t *testing.T) { keyName: "Test2", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll}}, nil }, false, @@ -213,7 +213,7 @@ func TestServiceAccountsAPI_DeleteToken(t *testing.T) { keyName: "Test3", acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionWrite, Scope: "serviceaccounts:id:10"}}, nil }, false, @@ -296,7 +296,7 @@ func TestServiceAccountsAPI_ListTokens(t *testing.T) { }}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: "serviceaccounts:id:1"}}, nil }, false, @@ -316,7 +316,7 @@ func TestServiceAccountsAPI_ListTokens(t *testing.T) { }}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: "serviceaccounts:id:1"}}, nil }, false, @@ -336,7 +336,7 @@ func TestServiceAccountsAPI_ListTokens(t *testing.T) { }}, acmock: tests.SetupMockAccesscontrol( t, - func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { + func(c context.Context, siu *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) { return []accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: "serviceaccounts:id:1"}}, nil }, false, diff --git a/pkg/services/serviceaccounts/database/database.go b/pkg/services/serviceaccounts/database/database.go index 8ecce955b88..e8228fa0ea7 100644 --- a/pkg/services/serviceaccounts/database/database.go +++ b/pkg/services/serviceaccounts/database/database.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apikey" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" @@ -39,7 +40,7 @@ func (s *ServiceAccountsStoreImpl) CreateServiceAccount(ctx context.Context, org generatedLogin := "sa-" + strings.ToLower(saForm.Name) generatedLogin = strings.ReplaceAll(generatedLogin, " ", "-") isDisabled := false - role := models.ROLE_VIEWER + role := org.RoleViewer if saForm.IsDisabled != nil { isDisabled = *saForm.IsDisabled } @@ -276,7 +277,7 @@ func (s *ServiceAccountsStoreImpl) RetrieveServiceAccountIdByName(ctx context.Co func (s *ServiceAccountsStoreImpl) SearchOrgServiceAccounts( ctx context.Context, orgId int64, query string, filter serviceaccounts.ServiceAccountFilter, page int, limit int, - signedInUser *models.SignedInUser, + signedInUser *user.SignedInUser, ) (*serviceaccounts.SearchServiceAccountsResult, error) { searchResult := &serviceaccounts.SearchServiceAccountsResult{ TotalCount: 0, diff --git a/pkg/services/serviceaccounts/database/database_test.go b/pkg/services/serviceaccounts/database/database_test.go index 62a3159f71f..2d482f173d3 100644 --- a/pkg/services/serviceaccounts/database/database_test.go +++ b/pkg/services/serviceaccounts/database/database_test.go @@ -8,9 +8,11 @@ import ( "github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/apikey/apikeyimpl" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -21,7 +23,7 @@ func TestStore_CreateServiceAccountOrgNonExistant(t *testing.T) { t.Run("create service account", func(t *testing.T) { serviceAccountName := "new Service Account" serviceAccountOrgId := int64(1) - serviceAccountRole := models.ROLE_ADMIN + serviceAccountRole := org.RoleAdmin isDisabled := true saForm := serviceaccounts.CreateServiceAccountForm{ Name: serviceAccountName, @@ -43,7 +45,7 @@ func TestStore_CreateServiceAccount(t *testing.T) { t.Run("create service account", func(t *testing.T) { serviceAccountName := "new Service Account" serviceAccountOrgId := orgQuery.Result.Id - serviceAccountRole := models.ROLE_ADMIN + serviceAccountRole := org.RoleAdmin isDisabled := true saForm := serviceaccounts.CreateServiceAccountForm{ Name: serviceAccountName, @@ -153,7 +155,7 @@ func TestStore_MigrateApiKeys(t *testing.T) { }{ { desc: "api key should be migrated to service account token", - key: tests.TestApiKey{Name: "Test1", Role: models.ROLE_EDITOR, OrgId: 1}, + key: tests.TestApiKey{Name: "Test1", Role: org.RoleEditor, OrgId: 1}, expectedErr: nil, }, } @@ -173,7 +175,7 @@ func TestStore_MigrateApiKeys(t *testing.T) { } else { require.NoError(t, err) - serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ + serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ key.OrgId: { "serviceaccounts:read": {"serviceaccounts:id:*"}, }, @@ -202,9 +204,9 @@ func TestStore_MigrateAllApiKeys(t *testing.T) { { desc: "api keys should be migrated to service account tokens within provided org", keys: []tests.TestApiKey{ - {Name: "test1", Role: models.ROLE_EDITOR, Key: "secret1", OrgId: 1}, - {Name: "test2", Role: models.ROLE_EDITOR, Key: "secret2", OrgId: 1}, - {Name: "test3", Role: models.ROLE_EDITOR, Key: "secret3", OrgId: 2}, + {Name: "test1", Role: org.RoleEditor, Key: "secret1", OrgId: 1}, + {Name: "test2", Role: org.RoleEditor, Key: "secret2", OrgId: 1}, + {Name: "test3", Role: org.RoleEditor, Key: "secret3", OrgId: 2}, }, orgId: 1, expectedServiceAccouts: 2, @@ -213,8 +215,8 @@ func TestStore_MigrateAllApiKeys(t *testing.T) { { desc: "api keys from another orgs shouldn't be migrated", keys: []tests.TestApiKey{ - {Name: "test1", Role: models.ROLE_EDITOR, Key: "secret1", OrgId: 2}, - {Name: "test2", Role: models.ROLE_EDITOR, Key: "secret2", OrgId: 2}, + {Name: "test1", Role: org.RoleEditor, Key: "secret1", OrgId: 2}, + {Name: "test2", Role: org.RoleEditor, Key: "secret2", OrgId: 2}, }, orgId: 1, expectedServiceAccouts: 0, @@ -223,8 +225,8 @@ func TestStore_MigrateAllApiKeys(t *testing.T) { { desc: "expired api keys should be migrated", keys: []tests.TestApiKey{ - {Name: "test1", Role: models.ROLE_EDITOR, Key: "secret1", OrgId: 1}, - {Name: "test2", Role: models.ROLE_EDITOR, Key: "secret2", OrgId: 1, IsExpired: true}, + {Name: "test1", Role: org.RoleEditor, Key: "secret1", OrgId: 1}, + {Name: "test2", Role: org.RoleEditor, Key: "secret2", OrgId: 1, IsExpired: true}, }, orgId: 1, expectedServiceAccouts: 2, @@ -251,7 +253,7 @@ func TestStore_MigrateAllApiKeys(t *testing.T) { } else { require.NoError(t, err) - serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), c.orgId, "", "all", 1, 50, &models.SignedInUser{UserId: 101, OrgId: c.orgId, Permissions: map[int64]map[string][]string{ + serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), c.orgId, "", "all", 1, 50, &user.SignedInUser{UserId: 101, OrgId: c.orgId, Permissions: map[int64]map[string][]string{ c.orgId: { "serviceaccounts:read": {"serviceaccounts:id:*"}, }, @@ -280,12 +282,12 @@ func TestStore_RevertApiKey(t *testing.T) { }{ { desc: "service account token should be reverted to api key", - key: tests.TestApiKey{Name: "Test1", Role: models.ROLE_EDITOR, OrgId: 1}, + key: tests.TestApiKey{Name: "Test1", Role: org.RoleEditor, OrgId: 1}, expectedErr: nil, }, { desc: "should fail reverting to api key when the token is assigned to a different service account", - key: tests.TestApiKey{Name: "Test1", Role: models.ROLE_EDITOR, OrgId: 1}, + key: tests.TestApiKey{Name: "Test1", Role: org.RoleEditor, OrgId: 1}, forceMismatchServiceAccount: true, expectedErr: ErrServiceAccountAndTokenMismatch, }, @@ -308,7 +310,7 @@ func TestStore_RevertApiKey(t *testing.T) { if c.forceMismatchServiceAccount { saId = rand.Int63() } else { - serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ + serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ key.OrgId: { "serviceaccounts:read": {"serviceaccounts:id:*"}, }, @@ -324,7 +326,7 @@ func TestStore_RevertApiKey(t *testing.T) { } else { require.NoError(t, err) - serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ + serviceAccounts, err := store.SearchOrgServiceAccounts(context.Background(), key.OrgId, "", "all", 1, 50, &user.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{ key.OrgId: { "serviceaccounts:read": {"serviceaccounts:id:*"}, }, diff --git a/pkg/services/serviceaccounts/database/token_store.go b/pkg/services/serviceaccounts/database/token_store.go index 15fc34fac5c..0cb704607f6 100644 --- a/pkg/services/serviceaccounts/database/token_store.go +++ b/pkg/services/serviceaccounts/database/token_store.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/apikey" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/sqlstore" "xorm.io/xorm" @@ -51,7 +51,7 @@ func (s *ServiceAccountsStoreImpl) AddServiceAccountToken(ctx context.Context, s token := apikey.APIKey{ OrgId: cmd.OrgId, Name: cmd.Name, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, Key: cmd.Key, Created: updated, Updated: updated, diff --git a/pkg/services/serviceaccounts/manager/roles.go b/pkg/services/serviceaccounts/manager/roles.go index 6f317700c92..6b958716cba 100644 --- a/pkg/services/serviceaccounts/manager/roles.go +++ b/pkg/services/serviceaccounts/manager/roles.go @@ -1,8 +1,8 @@ package manager import ( - "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/serviceaccounts" ) @@ -20,7 +20,7 @@ func RegisterRoles(ac accesscontrol.AccessControl) error { }, }, }, - Grants: []string{string(models.ROLE_ADMIN)}, + Grants: []string{string(org.RoleAdmin)}, } saCreator := accesscontrol.RoleRegistration{ @@ -35,7 +35,7 @@ func RegisterRoles(ac accesscontrol.AccessControl) error { }, }, }, - Grants: []string{string(models.ROLE_ADMIN)}, + Grants: []string{string(org.RoleAdmin)}, } saWriter := accesscontrol.RoleRegistration{ @@ -66,7 +66,7 @@ func RegisterRoles(ac accesscontrol.AccessControl) error { }, }), }, - Grants: []string{string(models.ROLE_ADMIN)}, + Grants: []string{string(org.RoleAdmin)}, } if err := ac.DeclareFixedRoles(saReader, saCreator, saWriter); err != nil { diff --git a/pkg/services/serviceaccounts/models.go b/pkg/services/serviceaccounts/models.go index dad902ba164..a4a0feaace4 100644 --- a/pkg/services/serviceaccounts/models.go +++ b/pkg/services/serviceaccounts/models.go @@ -3,9 +3,9 @@ package serviceaccounts import ( "time" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apikey" + "github.com/grafana/grafana/pkg/services/org" ) var ( @@ -31,16 +31,16 @@ type CreateServiceAccountForm struct { // example: grafana Name string `json:"name" binding:"Required"` // example: Admin - Role *models.RoleType `json:"role"` + Role *org.RoleType `json:"role"` // example: false IsDisabled *bool `json:"isDisabled"` } // swagger:model type UpdateServiceAccountForm struct { - Name *string `json:"name"` - Role *models.RoleType `json:"role"` - IsDisabled *bool `json:"isDisabled"` + Name *string `json:"name"` + Role *org.RoleType `json:"role"` + IsDisabled *bool `json:"isDisabled"` } // swagger: model diff --git a/pkg/services/serviceaccounts/serviceaccounts.go b/pkg/services/serviceaccounts/serviceaccounts.go index 788f29db90c..83dc48fbb11 100644 --- a/pkg/services/serviceaccounts/serviceaccounts.go +++ b/pkg/services/serviceaccounts/serviceaccounts.go @@ -3,8 +3,8 @@ package serviceaccounts import ( "context" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/apikey" + "github.com/grafana/grafana/pkg/services/user" ) // this should reflect the api @@ -17,7 +17,7 @@ type Service interface { type Store interface { CreateServiceAccount(ctx context.Context, orgID int64, saForm *CreateServiceAccountForm) (*ServiceAccountDTO, error) SearchOrgServiceAccounts(ctx context.Context, orgID int64, query string, filter ServiceAccountFilter, page int, limit int, - signedInUser *models.SignedInUser) (*SearchServiceAccountsResult, error) + signedInUser *user.SignedInUser) (*SearchServiceAccountsResult, error) UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, saForm *UpdateServiceAccountForm) (*ServiceAccountProfileDTO, error) RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*ServiceAccountProfileDTO, error) diff --git a/pkg/services/serviceaccounts/tests/common.go b/pkg/services/serviceaccounts/tests/common.go index a22b35d6960..9cda7250956 100644 --- a/pkg/services/serviceaccounts/tests/common.go +++ b/pkg/services/serviceaccounts/tests/common.go @@ -4,11 +4,11 @@ import ( "context" "testing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/apikey" "github.com/grafana/grafana/pkg/services/apikey/apikeyimpl" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" @@ -24,14 +24,14 @@ type TestUser struct { type TestApiKey struct { Name string - Role models.RoleType + Role org.RoleType OrgId int64 Key string IsExpired bool } func SetupUserServiceAccount(t *testing.T, sqlStore *sqlstore.SQLStore, testUser TestUser) *user.User { - role := string(models.ROLE_VIEWER) + role := string(org.RoleViewer) if testUser.Role != "" { role = testUser.Role } @@ -47,7 +47,7 @@ func SetupUserServiceAccount(t *testing.T, sqlStore *sqlstore.SQLStore, testUser } func SetupApiKey(t *testing.T, sqlStore *sqlstore.SQLStore, testKey TestApiKey) *apikey.APIKey { - role := models.ROLE_VIEWER + role := org.RoleViewer if testKey.Role != "" { role = testKey.Role } @@ -103,7 +103,7 @@ func (s *ServiceAccountMock) Migrated(ctx context.Context, orgID int64) bool { } func SetupMockAccesscontrol(t *testing.T, - userpermissionsfunc func(c context.Context, siu *models.SignedInUser, opt accesscontrol.Options) ([]accesscontrol.Permission, error), + userpermissionsfunc func(c context.Context, siu *user.SignedInUser, opt accesscontrol.Options) ([]accesscontrol.Permission, error), disableAccessControl bool) *accesscontrolmock.Mock { t.Helper() acmock := accesscontrolmock.New() @@ -208,7 +208,7 @@ func (s *ServiceAccountsStoreMock) SearchOrgServiceAccounts( filter serviceaccounts.ServiceAccountFilter, page int, limit int, - user *models.SignedInUser) (*serviceaccounts.SearchServiceAccountsResult, error) { + user *user.SignedInUser) (*serviceaccounts.SearchServiceAccountsResult, error) { s.Calls.SearchOrgServiceAccounts = append(s.Calls.SearchOrgServiceAccounts, []interface{}{ctx, orgID, query, page, limit, user}) return nil, nil } diff --git a/pkg/services/shorturls/short_url_service.go b/pkg/services/shorturls/short_url_service.go index f2b48d708e4..589d8283ebd 100644 --- a/pkg/services/shorturls/short_url_service.go +++ b/pkg/services/shorturls/short_url_service.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -20,8 +21,8 @@ func ProvideService(sqlStore *sqlstore.SQLStore) *ShortURLService { } type Service interface { - GetShortURLByUID(ctx context.Context, user *models.SignedInUser, uid string) (*models.ShortUrl, error) - CreateShortURL(ctx context.Context, user *models.SignedInUser, path string) (*models.ShortUrl, error) + GetShortURLByUID(ctx context.Context, user *user.SignedInUser, uid string) (*models.ShortUrl, error) + CreateShortURL(ctx context.Context, user *user.SignedInUser, path string) (*models.ShortUrl, error) UpdateLastSeenAt(ctx context.Context, shortURL *models.ShortUrl) error DeleteStaleShortURLs(ctx context.Context, cmd *models.DeleteShortUrlCommand) error } @@ -30,7 +31,7 @@ type ShortURLService struct { SQLStore *sqlstore.SQLStore } -func (s ShortURLService) GetShortURLByUID(ctx context.Context, user *models.SignedInUser, uid string) (*models.ShortUrl, error) { +func (s ShortURLService) GetShortURLByUID(ctx context.Context, user *user.SignedInUser, uid string) (*models.ShortUrl, error) { var shortURL models.ShortUrl err := s.SQLStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error { exists, err := dbSession.Where("org_id=? AND uid=?", user.OrgId, uid).Get(&shortURL) @@ -62,7 +63,7 @@ func (s ShortURLService) UpdateLastSeenAt(ctx context.Context, shortURL *models. }) } -func (s ShortURLService) CreateShortURL(ctx context.Context, user *models.SignedInUser, relPath string) (*models.ShortUrl, error) { +func (s ShortURLService) CreateShortURL(ctx context.Context, user *user.SignedInUser, relPath string) (*models.ShortUrl, error) { relPath = strings.TrimSpace(relPath) if path.IsAbs(relPath) { diff --git a/pkg/services/shorturls/short_url_service_test.go b/pkg/services/shorturls/short_url_service_test.go index 61278d9d3ac..95395867a0c 100644 --- a/pkg/services/shorturls/short_url_service_test.go +++ b/pkg/services/shorturls/short_url_service_test.go @@ -9,10 +9,11 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" ) func TestShortURLService(t *testing.T) { - user := &models.SignedInUser{UserId: 1} + user := &user.SignedInUser{UserId: 1} sqlStore := sqlstore.InitTestDB(t) t.Run("User can create and read short URLs", func(t *testing.T) { diff --git a/pkg/services/sqlstore/annotation.go b/pkg/services/sqlstore/annotation.go index 6d9f90c0b4b..41836daf73c 100644 --- a/pkg/services/sqlstore/annotation.go +++ b/pkg/services/sqlstore/annotation.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/sqlstore/permissions" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" ) // Update the item so that EpochEnd >= Epoch @@ -255,7 +256,7 @@ func (r *SQLAnnotationRepo) Find(ctx context.Context, query *annotations.ItemQue return items, err } -func getAccessControlFilter(user *models.SignedInUser) (string, []interface{}, error) { +func getAccessControlFilter(user *user.SignedInUser) (string, []interface{}, error) { if user == nil || user.Permissions[user.OrgId] == nil { return "", nil, errors.New("missing permissions") } diff --git a/pkg/services/sqlstore/annotation_test.go b/pkg/services/sqlstore/annotation_test.go index c0d44e19652..f828c94e639 100644 --- a/pkg/services/sqlstore/annotation_test.go +++ b/pkg/services/sqlstore/annotation_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -26,7 +27,7 @@ func TestIntegrationAnnotations(t *testing.T) { sql := sqlstore.InitTestDB(t) repo := sqlstore.NewSQLAnnotationRepo(sql) - testUser := &models.SignedInUser{ + testUser := &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{ 1: { @@ -436,7 +437,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) { err = repo.Save(organizationAnnotation) require.NoError(t, err) - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 1, OrgId: 1, } diff --git a/pkg/services/sqlstore/migrations/accesscontrol/managed_permission_migrator.go b/pkg/services/sqlstore/migrations/accesscontrol/managed_permission_migrator.go index 756502be02d..361f7c2f346 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/managed_permission_migrator.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/managed_permission_migrator.go @@ -13,8 +13,8 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/log" - "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/sqlstore/migrator" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -80,7 +80,7 @@ func (sp *managedPermissionMigrator) Exec(sess *xorm.Session, mg *migrator.Migra // Add parent roles + permissions to the map as "true" -- need to be inserted basicRoleName := ParseRoleFromName(roleName) - for _, parent := range models.RoleType(basicRoleName).Parents() { + for _, parent := range org.RoleType(basicRoleName).Parents() { parentManagedRoleName := "managed:builtins:" + strings.ToLower(string(parent)) + ":permissions" if _, ok := permissionMap[p.OrgID][parentManagedRoleName]; !ok { diff --git a/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go b/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go index 4197b9f5abd..6c806f93a28 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/team_membership.go @@ -9,6 +9,7 @@ import ( "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/sqlstore/migrator" ) @@ -209,7 +210,7 @@ func (p *teamPermissionMigrator) generateAssociatedPermissions(teamMemberships [ // only admins or editors (when editorsCanAdmin option is enabled) // can access team administration endpoints if m.Permission == models.PERMISSION_ADMIN { - if userRolesByOrg[m.OrgId][m.UserId] == string(models.ROLE_VIEWER) || (userRolesByOrg[m.OrgId][m.UserId] == string(models.ROLE_EDITOR) && !p.editorsCanAdmin) { + if userRolesByOrg[m.OrgId][m.UserId] == string(org.RoleViewer) || (userRolesByOrg[m.OrgId][m.UserId] == string(org.RoleEditor) && !p.editorsCanAdmin) { m.Permission = 0 if _, err := p.sess.Cols("permission").Where("org_id=? and team_id=? and user_id=?", m.OrgId, m.TeamId, m.UserId).Update(m); err != nil { diff --git a/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go b/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go index 0afc150d334..e18459ecd70 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/test/ac_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "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/sqlstore/migrations" acmig "github.com/grafana/grafana/pkg/services/sqlstore/migrations/accesscontrol" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" @@ -276,35 +277,35 @@ func setupTeams(t *testing.T, x *xorm.Engine) { { OrgId: 1, UserId: 1, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, Created: now, Updated: now, }, { OrgId: 1, UserId: 2, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, Created: now, Updated: now, }, { OrgId: 1, UserId: 3, - Role: models.ROLE_EDITOR, + Role: org.RoleEditor, Created: now, Updated: now, }, { OrgId: 1, UserId: 4, - Role: models.ROLE_ADMIN, + Role: org.RoleAdmin, Created: now, Updated: now, }, { OrgId: 2, UserId: 5, - Role: models.ROLE_EDITOR, + Role: org.RoleEditor, Created: now, Updated: now, }, diff --git a/pkg/services/sqlstore/migrations/ualert/permissions.go b/pkg/services/sqlstore/migrations/ualert/permissions.go index ad12c35bdd2..24e71ac2514 100644 --- a/pkg/services/sqlstore/migrations/ualert/permissions.go +++ b/pkg/services/sqlstore/migrations/ualert/permissions.go @@ -19,13 +19,13 @@ import ( type roleType string const ( - ROLE_VIEWER roleType = "Viewer" - ROLE_EDITOR roleType = "Editor" - ROLE_ADMIN roleType = "Admin" + RoleViewer roleType = "Viewer" + RoleEditor roleType = "Editor" + RoleAdmin roleType = "Admin" ) func (r roleType) IsValid() bool { - return r == ROLE_VIEWER || r == ROLE_ADMIN || r == ROLE_EDITOR + return r == RoleViewer || r == RoleAdmin || r == RoleEditor } type permissionType int diff --git a/pkg/services/sqlstore/mockstore/mockstore.go b/pkg/services/sqlstore/mockstore/mockstore.go index 8118db20aff..e1a62d0c847 100644 --- a/pkg/services/sqlstore/mockstore/mockstore.go +++ b/pkg/services/sqlstore/mockstore/mockstore.go @@ -39,7 +39,7 @@ type SQLStoreMock struct { ExpectedDataSourcesAccessStats []*models.DataSourceAccessStats ExpectedNotifierUsageStats []*models.NotifierUsageStats ExpectedPersistedDashboards models.HitList - ExpectedSignedInUser *models.SignedInUser + ExpectedSignedInUser *user.SignedInUser ExpectedUserStars map[int64]bool ExpectedLoginAttempts int64 diff --git a/pkg/services/sqlstore/org.go b/pkg/services/sqlstore/org.go index 65bd9dfeab6..8c2ac00f6a8 100644 --- a/pkg/services/sqlstore/org.go +++ b/pkg/services/sqlstore/org.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "xorm.io/xorm" ) @@ -103,7 +104,7 @@ func isOrgNameTaken(name string, existingId int64, sess *DBSession) (bool, error } func (ss *SQLStore) createOrg(ctx context.Context, name string, userID int64, engine *xorm.Engine) (models.Org, error) { - org := models.Org{ + orga := models.Org{ Name: name, Created: time.Now(), Updated: time.Now(), @@ -115,14 +116,14 @@ func (ss *SQLStore) createOrg(ctx context.Context, name string, userID int64, en return models.ErrOrgNameTaken } - if _, err := sess.Insert(&org); err != nil { + if _, err := sess.Insert(&orga); err != nil { return err } user := models.OrgUser{ - OrgId: org.Id, + OrgId: orga.Id, UserId: userID, - Role: models.ROLE_ADMIN, + Role: org.RoleAdmin, Created: time.Now(), Updated: time.Now(), } @@ -130,17 +131,17 @@ func (ss *SQLStore) createOrg(ctx context.Context, name string, userID int64, en _, err := sess.Insert(&user) sess.publishAfterCommit(&events.OrgCreated{ - Timestamp: org.Created, - Id: org.Id, - Name: org.Name, + Timestamp: orga.Created, + Id: orga.Id, + Name: orga.Name, }) return err }, 0); err != nil { - return org, err + return orga, err } - return org, nil + return orga, nil } // CreateOrgWithMember creates an organization with a certain name and a certain user as member. diff --git a/pkg/services/sqlstore/org_test.go b/pkg/services/sqlstore/org_test.go index 250c275da30..10b9173b8db 100644 --- a/pkg/services/sqlstore/org_test.go +++ b/pkg/services/sqlstore/org_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -23,7 +24,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { } t.Run("Testing Account DB Access", func(t *testing.T) { sqlStore := InitTestDB(t) - testUser := &models.SignedInUser{ + testUser := &user.SignedInUser{ Permissions: map[int64]map[string][]string{ 1: {accesscontrol.ActionOrgUsersRead: []string{accesscontrol.ScopeUsersAll}}, }, @@ -175,7 +176,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { }) t.Run("Can search users", func(t *testing.T) { - query := models.SearchUsersQuery{Query: "", SignedInUser: &models.SignedInUser{ + query := models.SearchUsersQuery{Query: "", SignedInUser: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{ 1: {accesscontrol.ActionUsersRead: {accesscontrol.ScopeGlobalUsersAll}}, @@ -193,7 +194,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { cmd := models.AddOrgUserCommand{ OrgId: ac1.OrgID, UserId: ac2.ID, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, } err := sqlStore.AddOrgUser(context.Background(), &cmd) @@ -202,13 +203,13 @@ func TestIntegrationAccountDataAccess(t *testing.T) { }) t.Run("Can update org user role", func(t *testing.T) { - updateCmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID, Role: models.ROLE_ADMIN} + updateCmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID, Role: org.RoleAdmin} err = sqlStore.UpdateOrgUser(context.Background(), &updateCmd) require.NoError(t, err) orgUsersQuery := models.GetOrgUsersQuery{ OrgId: ac1.OrgID, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: ac1.OrgID, Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}}, }, @@ -216,7 +217,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { err = sqlStore.GetOrgUsers(context.Background(), &orgUsersQuery) require.NoError(t, err) - require.EqualValues(t, orgUsersQuery.Result[1].Role, models.ROLE_ADMIN) + require.EqualValues(t, orgUsersQuery.Result[1].Role, org.RoleAdmin) }) t.Run("Can get logged in user projection", func(t *testing.T) { @@ -244,7 +245,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { t.Run("Can get organization users", func(t *testing.T) { query := models.GetOrgUsersQuery{ OrgId: ac1.OrgID, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: ac1.OrgID, Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}}, }, @@ -260,7 +261,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { query := models.GetOrgUsersQuery{ OrgId: ac1.OrgID, Query: "ac1", - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: ac1.OrgID, Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}}, }, @@ -277,7 +278,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { OrgId: ac1.OrgID, Query: "ac", Limit: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: ac1.OrgID, Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}}, }, @@ -341,7 +342,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { }) t.Run("Cannot update role so no one is admin user", func(t *testing.T) { - cmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac1.ID, Role: models.ROLE_VIEWER} + cmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac1.ID, Role: org.RoleViewer} err := sqlStore.UpdateOrgUser(context.Background(), &cmd) require.Equal(t, err, models.ErrLastOrgAdmin) }) @@ -354,7 +355,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { orgUserCmd := models.AddOrgUserCommand{ OrgId: ac1.OrgID, UserId: ac3.ID, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, } err = sqlStore.AddOrgUser(context.Background(), &orgUserCmd) @@ -362,7 +363,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) { query := models.GetOrgUsersQuery{ OrgId: ac1.OrgID, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: ac1.OrgID, Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}}, }, diff --git a/pkg/services/sqlstore/org_users_test.go b/pkg/services/sqlstore/org_users_test.go index 1e253a8ef29..34dfbf5bb8d 100644 --- a/pkg/services/sqlstore/org_users_test.go +++ b/pkg/services/sqlstore/org_users_test.go @@ -26,7 +26,7 @@ func TestSQLStore_GetOrgUsers(t *testing.T) { desc: "should return all users", query: &models.GetOrgUsersQuery{ OrgId: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}}}, }, @@ -37,7 +37,7 @@ func TestSQLStore_GetOrgUsers(t *testing.T) { desc: "should return no users", query: &models.GetOrgUsersQuery{ OrgId: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: {""}}}, }, @@ -48,7 +48,7 @@ func TestSQLStore_GetOrgUsers(t *testing.T) { desc: "should return some users", query: &models.GetOrgUsersQuery{ OrgId: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: { "users:id:1", @@ -95,7 +95,7 @@ func TestSQLStore_SearchOrgUsers(t *testing.T) { desc: "should return all users", query: &models.SearchOrgUsersQuery{ OrgID: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}}}, }, @@ -106,7 +106,7 @@ func TestSQLStore_SearchOrgUsers(t *testing.T) { desc: "should return no users", query: &models.SearchOrgUsersQuery{ OrgID: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: {""}}}, }, @@ -117,7 +117,7 @@ func TestSQLStore_SearchOrgUsers(t *testing.T) { desc: "should return some users", query: &models.SearchOrgUsersQuery{ OrgID: 1, - User: &models.SignedInUser{ + User: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: { "users:id:1", @@ -271,7 +271,7 @@ func seedOrgUsers(t *testing.T, store *SQLStore, numUsers int) { } } -func hasWildcardScope(user *models.SignedInUser, action string) bool { +func hasWildcardScope(user *user.SignedInUser, action string) bool { for _, scope := range user.Permissions[user.OrgId][action] { if strings.HasSuffix(scope, ":*") { return true diff --git a/pkg/services/sqlstore/permissions/dashboard.go b/pkg/services/sqlstore/permissions/dashboard.go index f67f22e9099..10e2fb84ef7 100644 --- a/pkg/services/sqlstore/permissions/dashboard.go +++ b/pkg/services/sqlstore/permissions/dashboard.go @@ -6,12 +6,14 @@ 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/org" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" ) type DashboardPermissionFilter struct { - OrgRole models.RoleType + OrgRole org.RoleType Dialect migrator.Dialect UserId int64 OrgId int64 @@ -19,13 +21,13 @@ type DashboardPermissionFilter struct { } func (d DashboardPermissionFilter) Where() (string, []interface{}) { - if d.OrgRole == models.ROLE_ADMIN { + if d.OrgRole == org.RoleAdmin { return "", nil } okRoles := []interface{}{d.OrgRole} - if d.OrgRole == models.ROLE_EDITOR { - okRoles = append(okRoles, models.ROLE_VIEWER) + if d.OrgRole == org.RoleEditor { + okRoles = append(okRoles, org.RoleViewer) } falseStr := d.Dialect.BooleanStr(false) @@ -78,13 +80,13 @@ func (d DashboardPermissionFilter) Where() (string, []interface{}) { } type AccessControlDashboardPermissionFilter struct { - User *models.SignedInUser + User *user.SignedInUser dashboardActions []string folderActions []string } // NewAccessControlDashboardPermissionFilter creates a new AccessControlDashboardPermissionFilter that is configured with specific actions calculated based on the models.PermissionType and query type -func NewAccessControlDashboardPermissionFilter(user *models.SignedInUser, permissionLevel models.PermissionType, queryType string) AccessControlDashboardPermissionFilter { +func NewAccessControlDashboardPermissionFilter(user *user.SignedInUser, permissionLevel models.PermissionType, queryType string) AccessControlDashboardPermissionFilter { needEdit := permissionLevel > models.PERMISSION_VIEW folderActions := []string{dashboards.ActionFoldersRead} var dashboardActions []string diff --git a/pkg/services/sqlstore/permissions/dashboard_test.go b/pkg/services/sqlstore/permissions/dashboard_test.go index 3645eb4a968..3c5d3e9b2e6 100644 --- a/pkg/services/sqlstore/permissions/dashboard_test.go +++ b/pkg/services/sqlstore/permissions/dashboard_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -89,7 +90,7 @@ func TestNewAccessControlDashboardPermissionFilter(t *testing.T) { for _, testCase := range testCases { t.Run(fmt.Sprintf("query type %s, permissions %s", testCase.queryType, testCase.permission), func(t *testing.T) { - filters := NewAccessControlDashboardPermissionFilter(&models.SignedInUser{}, testCase.permission, testCase.queryType) + filters := NewAccessControlDashboardPermissionFilter(&user.SignedInUser{}, testCase.permission, testCase.queryType) require.Equal(t, testCase.expectedDashboardActions, filters.dashboardActions) require.Equal(t, testCase.expectedFolderActions, filters.folderActions) @@ -133,7 +134,7 @@ func TestAccessControlDashboardPermissionFilter_Where(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.title, func(t *testing.T) { filter := AccessControlDashboardPermissionFilter{ - User: &models.SignedInUser{Permissions: map[int64]map[string][]string{}}, + User: &user.SignedInUser{Permissions: map[int64]map[string][]string{}}, dashboardActions: testCase.dashboardActions, folderActions: testCase.folderActions, } diff --git a/pkg/services/sqlstore/searchstore/search_test.go b/pkg/services/sqlstore/searchstore/search_test.go index 4b4dd130cb5..4dfa7061d4e 100644 --- a/pkg/services/sqlstore/searchstore/search_test.go +++ b/pkg/services/sqlstore/searchstore/search_test.go @@ -11,9 +11,11 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "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/services/sqlstore/permissions" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" ) @@ -23,10 +25,10 @@ const ( ) func TestBuilder_EqualResults_Basic(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 1, OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, } db := setupTestEnvironment(t) @@ -65,10 +67,10 @@ func TestBuilder_EqualResults_Basic(t *testing.T) { } func TestBuilder_Pagination(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 1, OrgId: 1, - OrgRole: models.ROLE_VIEWER, + OrgRole: org.RoleViewer, } db := setupTestEnvironment(t) @@ -111,10 +113,10 @@ func TestBuilder_Pagination(t *testing.T) { } func TestBuilder_Permissions(t *testing.T) { - user := &models.SignedInUser{ + user := &user.SignedInUser{ UserId: 1, OrgId: 1, - OrgRole: models.ROLE_VIEWER, + OrgRole: org.RoleViewer, } db := setupTestEnvironment(t) diff --git a/pkg/services/sqlstore/sqlbuilder.go b/pkg/services/sqlstore/sqlbuilder.go index dbdcc32cd46..9426bb8526b 100644 --- a/pkg/services/sqlstore/sqlbuilder.go +++ b/pkg/services/sqlstore/sqlbuilder.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/sqlstore/permissions" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -39,7 +40,7 @@ func (sb *SQLBuilder) AddParams(params ...interface{}) { sb.params = append(sb.params, params...) } -func (sb *SQLBuilder) WriteDashboardPermissionFilter(user *models.SignedInUser, permission models.PermissionType) { +func (sb *SQLBuilder) WriteDashboardPermissionFilter(user *user.SignedInUser, permission models.PermissionType) { var ( sql string params []interface{} diff --git a/pkg/services/sqlstore/sqlbuilder_test.go b/pkg/services/sqlstore/sqlbuilder_test.go index f8554d87bf5..6a727e72b77 100644 --- a/pkg/services/sqlstore/sqlbuilder_test.go +++ b/pkg/services/sqlstore/sqlbuilder_test.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -52,29 +53,29 @@ func TestIntegrationSQLBuilder(t *testing.T) { t.Run("role ACL", func(t *testing.T) { test(t, DashboardProps{}, - &DashboardPermission{Role: models.ROLE_VIEWER, Permission: models.PERMISSION_VIEW}, - Search{UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_VIEW}, + &DashboardPermission{Role: org.RoleViewer, Permission: models.PERMISSION_VIEW}, + Search{UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_VIEW}, shouldFind, ) test(t, DashboardProps{}, - &DashboardPermission{Role: models.ROLE_VIEWER, Permission: models.PERMISSION_VIEW}, - Search{UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_EDIT}, + &DashboardPermission{Role: org.RoleViewer, Permission: models.PERMISSION_VIEW}, + Search{UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_EDIT}, shouldNotFind, ) test(t, DashboardProps{}, - &DashboardPermission{Role: models.ROLE_EDITOR, Permission: models.PERMISSION_VIEW}, - Search{UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_VIEW}, + &DashboardPermission{Role: org.RoleEditor, Permission: models.PERMISSION_VIEW}, + Search{UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_VIEW}, shouldNotFind, ) test(t, DashboardProps{}, - &DashboardPermission{Role: models.ROLE_EDITOR, Permission: models.PERMISSION_VIEW}, - Search{UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_VIEW}, + &DashboardPermission{Role: org.RoleEditor, Permission: models.PERMISSION_VIEW}, + Search{UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_VIEW}, shouldNotFind, ) }) @@ -113,28 +114,28 @@ func TestIntegrationSQLBuilder(t *testing.T) { test(t, DashboardProps{}, nil, - Search{OrgId: -1, UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_VIEW}, + Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_VIEW}, shouldNotFind, ) test(t, DashboardProps{OrgId: -1}, nil, - Search{OrgId: -1, UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_VIEW}, + Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_VIEW}, shouldFind, ) test(t, DashboardProps{OrgId: -1}, nil, - Search{OrgId: -1, UsersOrgRole: models.ROLE_EDITOR, RequiredPermission: models.PERMISSION_EDIT}, + Search{OrgId: -1, UsersOrgRole: org.RoleEditor, RequiredPermission: models.PERMISSION_EDIT}, shouldFind, ) test(t, DashboardProps{OrgId: -1}, nil, - Search{OrgId: -1, UsersOrgRole: models.ROLE_VIEWER, RequiredPermission: models.PERMISSION_EDIT}, + Search{OrgId: -1, UsersOrgRole: org.RoleViewer, RequiredPermission: models.PERMISSION_EDIT}, shouldNotFind, ) }) @@ -151,12 +152,12 @@ type DashboardProps struct { type DashboardPermission struct { User bool Team bool - Role models.RoleType + Role org.RoleType Permission models.PermissionType } type Search struct { - UsersOrgRole models.RoleType + UsersOrgRole org.RoleType UserFromACL bool RequiredPermission models.PermissionType OrgId int64 @@ -205,7 +206,7 @@ func createDummyUser(t *testing.T, sqlStore *SQLStore) *user.User { EmailVerified: true, IsAdmin: false, SkipOrgSetup: false, - DefaultOrgRole: string(models.ROLE_VIEWER), + DefaultOrgRole: string(org.RoleViewer), } user, err := sqlStore.CreateUser(context.Background(), createUserCmd) require.NoError(t, err) @@ -306,7 +307,7 @@ func getDashboards(t *testing.T, sqlStore *SQLStore, search Search, aclUserID in }() builder := NewSqlBuilder(sqlStore.Cfg) - signedInUser := &models.SignedInUser{ + signedInUser := &user.SignedInUser{ UserId: 9999999999, } @@ -319,7 +320,7 @@ func getDashboards(t *testing.T, sqlStore *SQLStore, search Search, aclUserID in if len(string(search.UsersOrgRole)) > 0 { signedInUser.OrgRole = search.UsersOrgRole } else { - signedInUser.OrgRole = models.ROLE_VIEWER + signedInUser.OrgRole = org.RoleViewer } if search.UserFromACL { signedInUser.UserId = aclUserID diff --git a/pkg/services/sqlstore/stats.go b/pkg/services/sqlstore/stats.go index 3eeab812a9c..f0a635e68f7 100644 --- a/pkg/services/sqlstore/stats.go +++ b/pkg/services/sqlstore/stats.go @@ -6,6 +6,7 @@ import ( "time" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" ) @@ -147,7 +148,7 @@ func viewersPermissionsCounterSQL(statName string, isFolder bool, permission mod FROM ` + dialect.Quote("dashboard_acl") + ` AS acl INNER JOIN ` + dialect.Quote("dashboard") + ` AS d ON d.id = acl.dashboard_id - WHERE acl.role = '` + string(models.ROLE_VIEWER) + `' + WHERE acl.role = '` + string(org.RoleViewer) + `' AND d.is_folder = ` + dialect.BooleanStr(isFolder) + ` AND acl.permission = ` + strconv.FormatInt(int64(permission), 10) + ` ) AS ` + statName + `, ` @@ -305,11 +306,11 @@ GROUP BY active, daily_active, role;` memo := memoUserStats{memoized: time.Now()} for _, role := range bitmap { - roletype := models.ROLE_VIEWER + roletype := org.RoleViewer if role.Bitrole&0b100 != 0 { - roletype = models.ROLE_ADMIN + roletype = org.RoleAdmin } else if role.Bitrole&0b10 != 0 { - roletype = models.ROLE_EDITOR + roletype = org.RoleEditor } memo.total = addToStats(memo.total, roletype, role.Count) @@ -326,13 +327,13 @@ GROUP BY active, daily_active, role;` }) } -func addToStats(base models.UserStats, role models.RoleType, count int64) models.UserStats { +func addToStats(base models.UserStats, role org.RoleType, count int64) models.UserStats { base.Users += count switch role { - case models.ROLE_ADMIN: + case org.RoleAdmin: base.Admins += count - case models.ROLE_EDITOR: + case org.RoleEditor: base.Editors += count default: base.Viewers += count diff --git a/pkg/services/sqlstore/stats_test.go b/pkg/services/sqlstore/stats_test.go index f9e62523959..3bf6d22aabe 100644 --- a/pkg/services/sqlstore/stats_test.go +++ b/pkg/services/sqlstore/stats_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -82,22 +83,22 @@ func populateDB(t *testing.T, sqlStore *SQLStore) { getOrgByIdQuery := &models.GetOrgByIdQuery{Id: users[0].OrgID} err := sqlStore.GetOrgById(context.Background(), getOrgByIdQuery) require.NoError(t, err) - org := getOrgByIdQuery.Result + orga := getOrgByIdQuery.Result // add 2nd user as editor cmd := &models.AddOrgUserCommand{ - OrgId: org.Id, + OrgId: orga.Id, UserId: users[1].ID, - Role: models.ROLE_EDITOR, + Role: org.RoleEditor, } err = sqlStore.AddOrgUser(context.Background(), cmd) require.NoError(t, err) // add 3rd user as viewer cmd = &models.AddOrgUserCommand{ - OrgId: org.Id, + OrgId: orga.Id, UserId: users[2].ID, - Role: models.ROLE_VIEWER, + Role: org.RoleViewer, } err = sqlStore.AddOrgUser(context.Background(), cmd) require.NoError(t, err) @@ -106,13 +107,13 @@ func populateDB(t *testing.T, sqlStore *SQLStore) { getOrgByIdQuery = &models.GetOrgByIdQuery{Id: users[1].OrgID} err = sqlStore.GetOrgById(context.Background(), getOrgByIdQuery) require.NoError(t, err) - org = getOrgByIdQuery.Result + orga = getOrgByIdQuery.Result // add 1st user as admin cmd = &models.AddOrgUserCommand{ - OrgId: org.Id, + OrgId: orga.Id, UserId: users[0].ID, - Role: models.ROLE_ADMIN, + Role: org.RoleAdmin, } err = sqlStore.AddOrgUser(context.Background(), cmd) require.NoError(t, err) diff --git a/pkg/services/sqlstore/team.go b/pkg/services/sqlstore/team.go index b303b031a51..72f1bf9f7e5 100644 --- a/pkg/services/sqlstore/team.go +++ b/pkg/services/sqlstore/team.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/user" ) type TeamStore interface { @@ -22,7 +23,7 @@ type TeamStore interface { GetUserTeamMemberships(ctx context.Context, orgID, userID int64, external bool) ([]*models.TeamMemberDTO, error) } -func getFilteredUsers(signedInUser *models.SignedInUser, hiddenUsers map[string]struct{}) []string { +func getFilteredUsers(signedInUser *user.SignedInUser, hiddenUsers map[string]struct{}) []string { filteredUsers := make([]string, 0, len(hiddenUsers)) if signedInUser == nil || signedInUser.IsGrafanaAdmin { return filteredUsers diff --git a/pkg/services/sqlstore/team_test.go b/pkg/services/sqlstore/team_test.go index 04c3c80dfc6..44ed2771f60 100644 --- a/pkg/services/sqlstore/team_test.go +++ b/pkg/services/sqlstore/team_test.go @@ -20,7 +20,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { } t.Run("Testing Team commands & queries", func(t *testing.T) { sqlStore := InitTestDB(t) - testUser := &models.SignedInUser{ + testUser := &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{ 1: { @@ -226,7 +226,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { query := &models.GetTeamsByUserQuery{ OrgId: testOrgID, UserId: userIds[0], - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: testOrgID, Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}, ac.ActionTeamsRead: {ac.ScopeTeamsAll}}}, }, @@ -319,12 +319,12 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { err = sqlStore.AddTeamMember(userIds[1], testOrgID, groupId, false, models.PERMISSION_ADMIN) require.NoError(t, err) - query := &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgID, UserId: userIds[0]}} + query := &models.IsAdminOfTeamsQuery{SignedInUser: &user.SignedInUser{OrgId: testOrgID, UserId: userIds[0]}} err = sqlStore.IsAdminOfTeams(context.Background(), query) require.NoError(t, err) require.False(t, query.Result) - query = &models.IsAdminOfTeamsQuery{SignedInUser: &models.SignedInUser{OrgId: testOrgID, UserId: userIds[1]}} + query = &models.IsAdminOfTeamsQuery{SignedInUser: &user.SignedInUser{OrgId: testOrgID, UserId: userIds[1]}} err = sqlStore.IsAdminOfTeams(context.Background(), query) require.NoError(t, err) require.True(t, query.Result) @@ -333,7 +333,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { t.Run("Should not return hidden users in team member count", func(t *testing.T) { sqlStore = InitTestDB(t) setup() - signedInUser := &models.SignedInUser{ + signedInUser := &user.SignedInUser{ Login: "loginuser0", OrgId: testOrgID, Permissions: map[int64]map[string][]string{ @@ -423,7 +423,7 @@ func TestIntegrationSQLStore_SearchTeams(t *testing.T) { desc: "should return all teams", query: &models.SearchTeamsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionTeamsRead: {ac.ScopeTeamsAll}}}, }, @@ -434,7 +434,7 @@ func TestIntegrationSQLStore_SearchTeams(t *testing.T) { desc: "should return no teams", query: &models.SearchTeamsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionTeamsRead: {""}}}, }, @@ -445,7 +445,7 @@ func TestIntegrationSQLStore_SearchTeams(t *testing.T) { desc: "should return some teams", query: &models.SearchTeamsQuery{ OrgId: 1, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {ac.ActionTeamsRead: { "teams:id:1", @@ -533,7 +533,7 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) { desc: "should return all team members", query: &models.GetTeamMembersQuery{ OrgId: testOrgID, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: testOrgID, Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}}}, }, @@ -544,7 +544,7 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) { desc: "should return no team members", query: &models.GetTeamMembersQuery{ OrgId: testOrgID, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: testOrgID, Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {""}}}, }, @@ -556,7 +556,7 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) { desc: "should return some team members", query: &models.GetTeamMembersQuery{ OrgId: testOrgID, - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ OrgId: testOrgID, Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: { ac.Scope("users", "id", fmt.Sprintf("%d", userIds[0])), diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index 7b0e9ba8939..418b19092cd 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/models" ac "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/util" ) @@ -157,16 +158,16 @@ func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args user.C orgUser := models.OrgUser{ OrgId: orgID, UserId: usr.ID, - Role: models.ROLE_ADMIN, + Role: org.RoleAdmin, Created: time.Now(), Updated: time.Now(), } if ss.Cfg.AutoAssignOrg && !usr.IsAdmin { if len(args.DefaultOrgRole) > 0 { - orgUser.Role = models.RoleType(args.DefaultOrgRole) + orgUser.Role = org.RoleType(args.DefaultOrgRole) } else { - orgUser.Role = models.RoleType(ss.Cfg.AutoAssignOrgRole) + orgUser.Role = org.RoleType(ss.Cfg.AutoAssignOrgRole) } } @@ -475,7 +476,7 @@ func newSignedInUserCacheKey(orgID, userID int64) string { func (ss *SQLStore) GetSignedInUserWithCacheCtx(ctx context.Context, query *models.GetSignedInUserQuery) error { cacheKey := newSignedInUserCacheKey(query.OrgId, query.UserId) if cached, found := ss.CacheService.Get(cacheKey); found { - cachedUser := cached.(models.SignedInUser) + cachedUser := cached.(user.SignedInUser) query.Result = &cachedUser return nil } @@ -536,7 +537,7 @@ func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSigned } } - var usr models.SignedInUser + var usr user.SignedInUser has, err := sess.Get(&usr) if err != nil { return err @@ -554,7 +555,7 @@ func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSigned } // tempUser is used to retrieve the teams for the signed in user for internal use. - tempUser := &models.SignedInUser{ + tempUser := &user.SignedInUser{ OrgId: usr.OrgId, Permissions: map[int64]map[string][]string{ usr.OrgId: { @@ -847,7 +848,7 @@ func (ss *SQLStore) SetUserHelpFlag(ctx context.Context, cmd *models.SetUserHelp return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error { user := user.User{ ID: cmd.UserId, - HelpFlags1: user.HelpFlags1(cmd.HelpFlags1), + HelpFlags1: cmd.HelpFlags1, Updated: time.Now(), } diff --git a/pkg/services/sqlstore/user_test.go b/pkg/services/sqlstore/user_test.go index ab48f73c907..29507ec05a2 100644 --- a/pkg/services/sqlstore/user_test.go +++ b/pkg/services/sqlstore/user_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/assert" @@ -84,7 +85,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { t.Skip("skipping integration test") } ss := InitTestDB(t) - usr := &models.SignedInUser{ + usr := &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {"users:read": {"global.users:*"}}}, } @@ -352,7 +353,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { }) err = ss.AddOrgUser(context.Background(), &models.AddOrgUserCommand{ - LoginOrEmail: users[1].Login, Role: models.ROLE_VIEWER, + LoginOrEmail: users[1].Login, Role: org.RoleViewer, OrgId: users[0].OrgID, UserId: users[1].ID, }) require.Nil(t, err) @@ -391,7 +392,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { } }) err = ss.AddOrgUser(context.Background(), &models.AddOrgUserCommand{ - LoginOrEmail: users[1].Login, Role: models.ROLE_VIEWER, + LoginOrEmail: users[1].Login, Role: org.RoleViewer, OrgId: users[0].OrgID, UserId: users[1].ID, }) require.Nil(t, err) @@ -464,7 +465,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { } }) - testUser := &models.SignedInUser{ + testUser := &user.SignedInUser{ OrgId: 1, Permissions: map[int64]map[string][]string{1: {"users:read": {"global.users:id:1", "global.users:id:3"}}}, } diff --git a/pkg/services/store/file_guardian.go b/pkg/services/store/file_guardian.go index 56a1d58c42e..1a10e95eed8 100644 --- a/pkg/services/store/file_guardian.go +++ b/pkg/services/store/file_guardian.go @@ -6,7 +6,7 @@ import ( "github.com/grafana/grafana/pkg/infra/filestorage" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) const ( @@ -25,7 +25,7 @@ func isValidAction(action string) bool { } type storageAuthService interface { - newGuardian(ctx context.Context, user *models.SignedInUser, prefix string) fileGuardian + newGuardian(ctx context.Context, user *user.SignedInUser, prefix string) fileGuardian } type fileGuardian interface { @@ -39,7 +39,7 @@ type fileGuardian interface { type pathFilterFileGuardian struct { ctx context.Context - user *models.SignedInUser + user *user.SignedInUser prefix string pathFilterByAction map[string]filestorage.PathFilter log log.Logger diff --git a/pkg/services/store/sanitize.go b/pkg/services/store/sanitize.go index 98435e7d2ad..5c573720adb 100644 --- a/pkg/services/store/sanitize.go +++ b/pkg/services/store/sanitize.go @@ -6,12 +6,12 @@ import ( "path/filepath" "github.com/grafana/grafana/pkg/infra/filestorage" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/services/store/sanitizer" + "github.com/grafana/grafana/pkg/services/user" ) -func (s *standardStorageService) sanitizeContents(ctx context.Context, user *models.SignedInUser, req *UploadRequest, storagePath string) ([]byte, error) { +func (s *standardStorageService) sanitizeContents(ctx context.Context, user *user.SignedInUser, req *UploadRequest, storagePath string) ([]byte, error) { if req.EntityType == EntityTypeImage { ext := filepath.Ext(req.Path) if ext == ".svg" { @@ -36,7 +36,7 @@ func (s *standardStorageService) sanitizeContents(ctx context.Context, user *mod return req.Contents, nil } -func (s *standardStorageService) sanitizeUploadRequest(ctx context.Context, user *models.SignedInUser, req *UploadRequest, storagePath string) (*filestorage.UpsertFileCommand, error) { +func (s *standardStorageService) sanitizeUploadRequest(ctx context.Context, user *user.SignedInUser, req *UploadRequest, storagePath string) (*filestorage.UpsertFileCommand, error) { contents, err := s.sanitizeContents(ctx, user, req, storagePath) if err != nil { return nil, err diff --git a/pkg/services/store/service.go b/pkg/services/store/service.go index 93de53853e6..8d08260984c 100644 --- a/pkg/services/store/service.go +++ b/pkg/services/store/service.go @@ -12,12 +12,12 @@ import ( "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/filestorage" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/registry" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/quota" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -41,8 +41,8 @@ const brandingStorage = "branding" const SystemBrandingStorage = "system/" + brandingStorage var ( - SystemBrandingReader = &models.SignedInUser{OrgId: ac.GlobalOrgID} - SystemBrandingAdmin = &models.SignedInUser{OrgId: ac.GlobalOrgID} + SystemBrandingReader = &user.SignedInUser{OrgId: ac.GlobalOrgID} + SystemBrandingAdmin = &user.SignedInUser{OrgId: ac.GlobalOrgID} ) const MAX_UPLOAD_SIZE = 1 * 1024 * 1024 // 3MB @@ -63,23 +63,23 @@ type StorageService interface { RegisterHTTPRoutes(routing.RouteRegister) // List folder contents - List(ctx context.Context, user *models.SignedInUser, path string) (*StorageListFrame, error) + List(ctx context.Context, user *user.SignedInUser, path string) (*StorageListFrame, error) // Read raw file contents out of the store - Read(ctx context.Context, user *models.SignedInUser, path string) (*filestorage.File, error) + Read(ctx context.Context, user *user.SignedInUser, path string) (*filestorage.File, error) - Upload(ctx context.Context, user *models.SignedInUser, req *UploadRequest) error + Upload(ctx context.Context, user *user.SignedInUser, req *UploadRequest) error - Delete(ctx context.Context, user *models.SignedInUser, path string) error + Delete(ctx context.Context, user *user.SignedInUser, path string) error - DeleteFolder(ctx context.Context, user *models.SignedInUser, cmd *DeleteFolderCmd) error + DeleteFolder(ctx context.Context, user *user.SignedInUser, cmd *DeleteFolderCmd) error - CreateFolder(ctx context.Context, user *models.SignedInUser, cmd *CreateFolderCmd) error + CreateFolder(ctx context.Context, user *user.SignedInUser, cmd *CreateFolderCmd) error - validateUploadRequest(ctx context.Context, user *models.SignedInUser, req *UploadRequest, storagePath string) validationResult + validateUploadRequest(ctx context.Context, user *user.SignedInUser, req *UploadRequest, storagePath string) validationResult // sanitizeUploadRequest sanitizes the upload request and converts it into a command accepted by the FileStorage API - sanitizeUploadRequest(ctx context.Context, user *models.SignedInUser, req *UploadRequest, storagePath string) (*filestorage.UpsertFileCommand, error) + sanitizeUploadRequest(ctx context.Context, user *user.SignedInUser, req *UploadRequest, storagePath string) (*filestorage.UpsertFileCommand, error) } type standardStorageService struct { @@ -182,7 +182,7 @@ func ProvideService( globalRoots = append(globalRoots, initializeOrgStorages(ac.GlobalOrgID)...) - authService := newStaticStorageAuthService(func(ctx context.Context, user *models.SignedInUser, storageName string) map[string]filestorage.PathFilter { + authService := newStaticStorageAuthService(func(ctx context.Context, user *user.SignedInUser, storageName string) map[string]filestorage.PathFilter { // Public is OK to read regardless of user settings if storageName == RootPublicStatic { return map[string]filestorage.PathFilter{ @@ -268,7 +268,7 @@ func (s *standardStorageService) Run(ctx context.Context) error { return nil } -func getOrgId(user *models.SignedInUser) int64 { +func getOrgId(user *user.SignedInUser) int64 { if user == nil { return ac.GlobalOrgID } @@ -276,12 +276,12 @@ func getOrgId(user *models.SignedInUser) int64 { return user.OrgId } -func (s *standardStorageService) List(ctx context.Context, user *models.SignedInUser, path string) (*StorageListFrame, error) { +func (s *standardStorageService) List(ctx context.Context, user *user.SignedInUser, path string) (*StorageListFrame, error) { guardian := s.authService.newGuardian(ctx, user, getFirstSegment(path)) return s.tree.ListFolder(ctx, getOrgId(user), path, guardian.getPathFilter(ActionFilesRead)) } -func (s *standardStorageService) Read(ctx context.Context, user *models.SignedInUser, path string) (*filestorage.File, error) { +func (s *standardStorageService) Read(ctx context.Context, user *user.SignedInUser, path string) (*filestorage.File, error) { guardian := s.authService.newGuardian(ctx, user, getFirstSegment(path)) if !guardian.canView(path) { return nil, ErrAccessDenied @@ -300,7 +300,7 @@ type UploadRequest struct { OverwriteExistingFile bool } -func (s *standardStorageService) Upload(ctx context.Context, user *models.SignedInUser, req *UploadRequest) error { +func (s *standardStorageService) Upload(ctx context.Context, user *user.SignedInUser, req *UploadRequest) error { if err := s.checkFileQuota(ctx, req.Path); err != nil { return err } @@ -369,7 +369,7 @@ func (s *standardStorageService) checkFileQuota(ctx context.Context, path string return nil } -func (s *standardStorageService) DeleteFolder(ctx context.Context, user *models.SignedInUser, cmd *DeleteFolderCmd) error { +func (s *standardStorageService) DeleteFolder(ctx context.Context, user *user.SignedInUser, cmd *DeleteFolderCmd) error { guardian := s.authService.newGuardian(ctx, user, getFirstSegment(cmd.Path)) if !guardian.canDelete(cmd.Path) { return ErrAccessDenied @@ -390,7 +390,7 @@ func (s *standardStorageService) DeleteFolder(ctx context.Context, user *models. return root.Store().DeleteFolder(ctx, storagePath, &filestorage.DeleteFolderOptions{Force: cmd.Force, AccessFilter: guardian.getPathFilter(ActionFilesDelete)}) } -func (s *standardStorageService) CreateFolder(ctx context.Context, user *models.SignedInUser, cmd *CreateFolderCmd) error { +func (s *standardStorageService) CreateFolder(ctx context.Context, user *user.SignedInUser, cmd *CreateFolderCmd) error { if err := s.checkFileQuota(ctx, cmd.Path); err != nil { return err } @@ -416,7 +416,7 @@ func (s *standardStorageService) CreateFolder(ctx context.Context, user *models. return nil } -func (s *standardStorageService) Delete(ctx context.Context, user *models.SignedInUser, path string) error { +func (s *standardStorageService) Delete(ctx context.Context, user *user.SignedInUser, path string) error { guardian := s.authService.newGuardian(ctx, user, getFirstSegment(path)) if !guardian.canDelete(path) { return ErrAccessDenied @@ -438,7 +438,7 @@ func (s *standardStorageService) Delete(ctx context.Context, user *models.Signed return nil } -func (s *standardStorageService) write(ctx context.Context, user *models.SignedInUser, req *WriteValueRequest) (*WriteValueResponse, error) { +func (s *standardStorageService) write(ctx context.Context, user *user.SignedInUser, req *WriteValueRequest) (*WriteValueResponse, error) { guardian := s.authService.newGuardian(ctx, user, getFirstSegment(req.Path)) if !guardian.canWrite(req.Path) { return nil, ErrAccessDenied @@ -481,7 +481,7 @@ type optionInfo struct { Workflows []workflowInfo `json:"workflows"` } -func (s *standardStorageService) getWorkflowOptions(ctx context.Context, user *models.SignedInUser, path string) (optionInfo, error) { +func (s *standardStorageService) getWorkflowOptions(ctx context.Context, user *user.SignedInUser, path string) (optionInfo, error) { options := optionInfo{ Path: path, Workflows: make([]workflowInfo, 0), diff --git a/pkg/services/store/service_test.go b/pkg/services/store/service_test.go index 647cf9cdfb6..3e443d442cd 100644 --- a/pkg/services/store/service_test.go +++ b/pkg/services/store/service_test.go @@ -9,9 +9,9 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/experimental" "github.com/grafana/grafana/pkg/infra/filestorage" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/testdatasource" "github.com/stretchr/testify/mock" @@ -27,15 +27,15 @@ var ( htmlBytes, _ = ioutil.ReadFile("testdata/page.html") jpgBytes, _ = ioutil.ReadFile("testdata/image.jpg") svgBytes, _ = ioutil.ReadFile("testdata/image.svg") - dummyUser = &models.SignedInUser{OrgId: 1} - allowAllAuthService = newStaticStorageAuthService(func(ctx context.Context, user *models.SignedInUser, storageName string) map[string]filestorage.PathFilter { + dummyUser = &user.SignedInUser{OrgId: 1} + allowAllAuthService = newStaticStorageAuthService(func(ctx context.Context, user *user.SignedInUser, storageName string) map[string]filestorage.PathFilter { return map[string]filestorage.PathFilter{ ActionFilesDelete: allowAllPathFilter, ActionFilesWrite: allowAllPathFilter, ActionFilesRead: allowAllPathFilter, } }) - denyAllAuthService = newStaticStorageAuthService(func(ctx context.Context, user *models.SignedInUser, storageName string) map[string]filestorage.PathFilter { + denyAllAuthService = newStaticStorageAuthService(func(ctx context.Context, user *user.SignedInUser, storageName string) map[string]filestorage.PathFilter { return map[string]filestorage.PathFilter{ ActionFilesDelete: denyAllPathFilter, ActionFilesWrite: denyAllPathFilter, diff --git a/pkg/services/store/static_auth.go b/pkg/services/store/static_auth.go index e97db52c487..ff6c98465c9 100644 --- a/pkg/services/store/static_auth.go +++ b/pkg/services/store/static_auth.go @@ -5,10 +5,10 @@ import ( "github.com/grafana/grafana/pkg/infra/filestorage" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) -type createPathFilterByAction func(ctx context.Context, user *models.SignedInUser, storageName string) map[string]filestorage.PathFilter +type createPathFilterByAction func(ctx context.Context, user *user.SignedInUser, storageName string) map[string]filestorage.PathFilter func newStaticStorageAuthService(createPathFilterByAction createPathFilterByAction) storageAuthService { return &staticStorageAuth{ @@ -24,7 +24,7 @@ type staticStorageAuth struct { createPathFilterByAction createPathFilterByAction } -func (a *staticStorageAuth) newGuardian(ctx context.Context, user *models.SignedInUser, storageName string) fileGuardian { +func (a *staticStorageAuth) newGuardian(ctx context.Context, user *user.SignedInUser, storageName string) fileGuardian { pathFilter := a.createPathFilterByAction(ctx, user, storageName) if pathFilter == nil { diff --git a/pkg/services/store/storage_git.go b/pkg/services/store/storage_git.go index 3f62e398308..c3f8f92b173 100644 --- a/pkg/services/store/storage_git.go +++ b/pkg/services/store/storage_git.go @@ -14,7 +14,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/infra/filestorage" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "gocloud.dev/blob" ) @@ -339,15 +339,15 @@ func (s *rootStorageGit) Write(ctx context.Context, cmd *WriteValueRequest) (*Wr if msg == "" { msg = "changes from grafana ui" } - user := cmd.User - if user == nil { - user = &models.SignedInUser{} + usr := cmd.User + if usr == nil { + usr = &user.SignedInUser{} } hash, err := w.Commit(msg, &git.CommitOptions{ Author: &object.Signature{ - Name: firstRealString(user.Name, user.Login, user.Email, "?"), - Email: firstRealString(user.Email, user.Login, user.Name, "?"), + Name: firstRealString(usr.Name, usr.Login, usr.Email, "?"), + Email: firstRealString(usr.Email, usr.Login, usr.Name, "?"), When: time.Now(), }, }) diff --git a/pkg/services/store/types.go b/pkg/services/store/types.go index 973d8982db7..0a8a1cafc81 100644 --- a/pkg/services/store/types.go +++ b/pkg/services/store/types.go @@ -6,7 +6,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/infra/filestorage" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) type WriteValueWorkflow = string @@ -18,7 +18,7 @@ var ( ) type WriteValueRequest struct { - User *models.SignedInUser + User *user.SignedInUser Path string // added from URL EntityType EntityType `json:"kind,omitempty"` // for now only dashboard Body json.RawMessage `json:"body,omitempty"` diff --git a/pkg/services/store/validate.go b/pkg/services/store/validate.go index 2cea23394cb..67ce257f439 100644 --- a/pkg/services/store/validate.go +++ b/pkg/services/store/validate.go @@ -9,8 +9,8 @@ import ( "strings" "github.com/grafana/grafana/pkg/infra/filestorage" - "github.com/grafana/grafana/pkg/models" issvg "github.com/grafana/grafana/pkg/services/store/go-is-svg" + "github.com/grafana/grafana/pkg/services/user" ) var ( @@ -50,7 +50,7 @@ func fail(reason string) validationResult { } } -func (s *standardStorageService) detectMimeType(ctx context.Context, user *models.SignedInUser, uploadRequest *UploadRequest) string { +func (s *standardStorageService) detectMimeType(ctx context.Context, user *user.SignedInUser, uploadRequest *UploadRequest) string { if strings.HasSuffix(uploadRequest.Path, ".svg") { if issvg.IsSVG(uploadRequest.Contents) { return "image/svg+xml" @@ -60,7 +60,7 @@ func (s *standardStorageService) detectMimeType(ctx context.Context, user *model return http.DetectContentType(uploadRequest.Contents) } -func (s *standardStorageService) validateImage(ctx context.Context, user *models.SignedInUser, uploadRequest *UploadRequest) validationResult { +func (s *standardStorageService) validateImage(ctx context.Context, user *user.SignedInUser, uploadRequest *UploadRequest) validationResult { ext := filepath.Ext(uploadRequest.Path) if !allowedImageExtensions[ext] { return fail(fmt.Sprintf("unsupported extension: %s", ext)) @@ -74,7 +74,7 @@ func (s *standardStorageService) validateImage(ctx context.Context, user *models return success() } -func (s *standardStorageService) validateUploadRequest(ctx context.Context, user *models.SignedInUser, req *UploadRequest, storagePath string) validationResult { +func (s *standardStorageService) validateUploadRequest(ctx context.Context, user *user.SignedInUser, req *UploadRequest, storagePath string) validationResult { // TODO: validateSize // TODO: validateProperties diff --git a/pkg/services/teamguardian/manager/service.go b/pkg/services/teamguardian/manager/service.go index 9e2ccbf354e..6cc9e665208 100644 --- a/pkg/services/teamguardian/manager/service.go +++ b/pkg/services/teamguardian/manager/service.go @@ -4,7 +4,9 @@ import ( "context" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/teamguardian" + "github.com/grafana/grafana/pkg/services/user" ) type Service struct { @@ -15,8 +17,8 @@ func ProvideService(store teamguardian.Store) teamguardian.TeamGuardian { return &Service{store: store} } -func (s *Service) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *models.SignedInUser) error { - if user.OrgRole == models.ROLE_ADMIN { +func (s *Service) CanAdmin(ctx context.Context, orgId int64, teamId int64, user *user.SignedInUser) error { + if user.OrgRole == org.RoleAdmin { return nil } diff --git a/pkg/services/teamguardian/manager/service_mock.go b/pkg/services/teamguardian/manager/service_mock.go index dbd37fbb006..8ba08d98c45 100644 --- a/pkg/services/teamguardian/manager/service_mock.go +++ b/pkg/services/teamguardian/manager/service_mock.go @@ -3,7 +3,7 @@ package manager import ( "context" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/mock" ) @@ -16,7 +16,7 @@ func NewTeamGuardianMock() *TeamGuardianMock { return &TeamGuardianMock{} } -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 { args := t.Called(ctx, orgId, teamId, user) return args.Error(0) } diff --git a/pkg/services/teamguardian/manager/service_test.go b/pkg/services/teamguardian/manager/service_test.go index feb1878bec9..de506c76e3a 100644 --- a/pkg/services/teamguardian/manager/service_test.go +++ b/pkg/services/teamguardian/manager/service_test.go @@ -5,7 +5,9 @@ import ( "testing" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/teamguardian/database" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -15,15 +17,15 @@ func TestUpdateTeam(t *testing.T) { teamGuardianService := ProvideService(store) t.Run("Updating a team", func(t *testing.T) { - admin := models.SignedInUser{ + admin := user.SignedInUser{ UserId: 1, OrgId: 1, - OrgRole: models.ROLE_ADMIN, + OrgRole: org.RoleAdmin, } - editor := models.SignedInUser{ + editor := user.SignedInUser{ UserId: 2, OrgId: 1, - OrgRole: models.ROLE_EDITOR, + OrgRole: org.RoleEditor, } testTeam := models.Team{ Id: 1, diff --git a/pkg/services/teamguardian/team.go b/pkg/services/teamguardian/team.go index 505999b509b..497d5d89f9d 100644 --- a/pkg/services/teamguardian/team.go +++ b/pkg/services/teamguardian/team.go @@ -4,10 +4,11 @@ import ( "context" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" ) type TeamGuardian interface { - CanAdmin(context.Context, int64, int64, *models.SignedInUser) error + CanAdmin(context.Context, int64, int64, *user.SignedInUser) error DeleteByUser(context.Context, int64) error } diff --git a/pkg/services/thumbs/crawler_auth.go b/pkg/services/thumbs/crawler_auth.go index 5ace4272695..eb71e29186c 100644 --- a/pkg/services/thumbs/crawler_auth.go +++ b/pkg/services/thumbs/crawler_auth.go @@ -7,6 +7,7 @@ import ( "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/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/database" "github.com/grafana/grafana/pkg/services/sqlstore" @@ -37,7 +38,7 @@ type OSSCrawlerAuthSetupService struct { type CrawlerAuth interface { GetUserId(orgId int64) int64 GetLogin(orgId int64) string - GetOrgRole() models.RoleType + GetOrgRole() org.RoleType } func (o *OSSCrawlerAuthSetupService) findAllOrgIds(ctx context.Context) ([]int64, error) { @@ -58,10 +59,10 @@ func (o *OSSCrawlerAuthSetupService) findAllOrgIds(ctx context.Context) ([]int64 type crawlerAuth struct { accountIdByOrgId map[int64]int64 loginByOrgId map[int64]string - orgRole models.RoleType + orgRole org.RoleType } -func (o *crawlerAuth) GetOrgRole() models.RoleType { +func (o *crawlerAuth) GetOrgRole() org.RoleType { return o.orgRole } @@ -79,9 +80,9 @@ func (o *OSSCrawlerAuthSetupService) Setup(ctx context.Context) (CrawlerAuth, er return nil, err } - // userId:0 and ROLE_ADMIN grants the crawler process permissions to view all dashboards in all folders & orgs + // userId:0 and RoleAdmin grants the crawler process permissions to view all dashboards in all folders & orgs // the process doesn't and shouldn't actually need to edit/modify any resources from the UI - orgRole := models.ROLE_ADMIN + orgRole := org.RoleAdmin accountIdByOrgId := make(map[int64]int64) loginByOrgId := make(map[int64]string) diff --git a/pkg/services/user/model.go b/pkg/services/user/model.go index 1cb3f3755ef..7537dc477dd 100644 --- a/pkg/services/user/model.go +++ b/pkg/services/user/model.go @@ -5,10 +5,20 @@ import ( "fmt" "strings" "time" + + "github.com/grafana/grafana/pkg/services/org" ) type HelpFlags1 uint64 +func (f HelpFlags1) HasFlag(flag HelpFlags1) bool { return f&flag != 0 } +func (f *HelpFlags1) AddFlag(flag HelpFlags1) { *f |= flag } + +const ( + HelpFlagGettingStartedPanelDismissed HelpFlags1 = 1 << iota + HelpFlagDashboardHelp1 +) + // Typed errors var ( ErrCaseInsensitive = errors.New("case insensitive conflict") @@ -108,6 +118,71 @@ type ErrCaseInsensitiveLoginConflict struct { Users []User } +type SignedInUser struct { + UserId int64 + OrgId int64 + OrgName string + OrgRole org.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:"-"` +} + +type UserDisplayDTO struct { + Id int64 `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Login string `json:"login,omitempty"` + AvatarUrl string `json:"avatarUrl"` +} + +// ------------------------ +// DTO & Projections + +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, + } +} +func (u *SignedInUser) HasRole(role org.RoleType) bool { + if u.IsGrafanaAdmin { + return true + } + + return u.OrgRole.Includes(role) +} + +func (u *SignedInUser) IsRealUser() bool { + return u.UserId != 0 +} + func (e *ErrCaseInsensitiveLoginConflict) Unwrap() error { return ErrCaseInsensitive } diff --git a/pkg/services/user/userimpl/user.go b/pkg/services/user/userimpl/user.go index c1d8134a3f8..2fca2fb543e 100644 --- a/pkg/services/user/userimpl/user.go +++ b/pkg/services/user/userimpl/user.go @@ -141,7 +141,7 @@ func (s *Service) Create(ctx context.Context, cmd *user.CreateUserCommand) (*use orgUser := org.OrgUser{ OrgID: orgID, UserID: usr.ID, - Role: org.ROLE_ADMIN, + Role: org.RoleAdmin, Created: time.Now(), Updated: time.Now(), } diff --git a/pkg/tests/api/alerting/api_admin_configuration_test.go b/pkg/tests/api/alerting/api_admin_configuration_test.go index 8fd107aa090..01fcf12114f 100644 --- a/pkg/tests/api/alerting/api_admin_configuration_test.go +++ b/pkg/tests/api/alerting/api_admin_configuration_test.go @@ -12,10 +12,10 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/models" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/sender" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" ) @@ -35,7 +35,7 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) { // Create a user to make authenticated requests userID := createUser(t, s, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Login: "grafana", Password: "password", }) @@ -47,7 +47,7 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) { // create user under different organisation createUser(t, s, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin-42", Login: "admin-42", OrgID: orgID, diff --git a/pkg/tests/api/alerting/api_alertmanager_configuration_test.go b/pkg/tests/api/alerting/api_alertmanager_configuration_test.go index 9250bd1320e..4da868528df 100644 --- a/pkg/tests/api/alerting/api_alertmanager_configuration_test.go +++ b/pkg/tests/api/alerting/api_alertmanager_configuration_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" "github.com/stretchr/testify/assert" @@ -33,7 +33,7 @@ func TestAlertmanagerConfigurationIsTransactional(t *testing.T) { // create user under main organisation userID := createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) @@ -43,7 +43,7 @@ func TestAlertmanagerConfigurationIsTransactional(t *testing.T) { // create user under different organisation createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor-42", Login: "editor-42", OrgID: orgID, @@ -141,7 +141,7 @@ func TestAlertmanagerConfigurationPersistSecrets(t *testing.T) { alertConfigURL := fmt.Sprintf("http://editor:editor@%s/api/alertmanager/grafana/config/api/v1/alerts", grafanaListedAddr) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) diff --git a/pkg/tests/api/alerting/api_alertmanager_test.go b/pkg/tests/api/alerting/api_alertmanager_test.go index 9c34290fbf1..07793a5e0eb 100644 --- a/pkg/tests/api/alerting/api_alertmanager_test.go +++ b/pkg/tests/api/alerting/api_alertmanager_test.go @@ -20,6 +20,7 @@ import ( apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ngstore "github.com/grafana/grafana/pkg/services/ngalert/store" + "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" @@ -43,17 +44,17 @@ func TestAMConfigAccess(t *testing.T) { // Create a users to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_VIEWER), + DefaultOrgRole: string(org.RoleViewer), Password: "viewer", Login: "viewer", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) @@ -417,7 +418,7 @@ func TestAlertAndGroupsQuery(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -561,17 +562,17 @@ func TestRulerAccess(t *testing.T) { // Create a users to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_VIEWER), + DefaultOrgRole: string(org.RoleViewer), Password: "viewer", Login: "viewer", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) @@ -675,12 +676,12 @@ func TestDeleteFolderWithRules(t *testing.T) { grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_VIEWER), + DefaultOrgRole: string(org.RoleViewer), Password: "viewer", Login: "viewer", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) @@ -835,7 +836,7 @@ func TestAlertRuleCRUD(t *testing.T) { grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -1878,7 +1879,7 @@ func TestQuota(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -2094,7 +2095,7 @@ func TestEval(t *testing.T) { grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) diff --git a/pkg/tests/api/alerting/api_available_channel_test.go b/pkg/tests/api/alerting/api_available_channel_test.go index 4fd7cc3a077..9e6417d95a8 100644 --- a/pkg/tests/api/alerting/api_available_channel_test.go +++ b/pkg/tests/api/alerting/api_available_channel_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/ngalert/notifier/channels_config" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" ) @@ -27,7 +27,7 @@ func TestAvailableChannels(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) diff --git a/pkg/tests/api/alerting/api_notification_channel_test.go b/pkg/tests/api/alerting/api_notification_channel_test.go index 588c0c483a5..8808e6ce06f 100644 --- a/pkg/tests/api/alerting/api_notification_channel_test.go +++ b/pkg/tests/api/alerting/api_notification_channel_test.go @@ -26,6 +26,7 @@ import ( ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/notifier/channels" "github.com/grafana/grafana/pkg/services/ngalert/store" + "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/tests/testinfra" @@ -43,7 +44,7 @@ func TestTestReceivers(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -77,7 +78,7 @@ func TestTestReceivers(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -159,7 +160,7 @@ func TestTestReceivers(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -236,7 +237,7 @@ func TestTestReceivers(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -323,7 +324,7 @@ func TestTestReceivers(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -436,7 +437,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -529,7 +530,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -617,7 +618,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) { grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Login: "grafana", Password: "password", }) @@ -740,7 +741,7 @@ func TestNotificationChannels(t *testing.T) { // Create a user to make authenticated requests createUser(t, env.SQLStore, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) diff --git a/pkg/tests/api/alerting/api_prometheus_test.go b/pkg/tests/api/alerting/api_prometheus_test.go index 8dacad65c22..a88c86b9943 100644 --- a/pkg/tests/api/alerting/api_prometheus_test.go +++ b/pkg/tests/api/alerting/api_prometheus_test.go @@ -15,12 +15,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database" "github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" ) @@ -37,7 +37,7 @@ func TestPrometheusRules(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -331,7 +331,7 @@ func TestPrometheusRulesFilterByDashboard(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -625,7 +625,7 @@ func TestPrometheusRulesPermissions(t *testing.T) { // Create a user to make authenticated requests userID := createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -673,8 +673,8 @@ func TestPrometheusRulesPermissions(t *testing.T) { require.Equal(t, "folder2", body.Data.Groups[1].File) } - // remove permissions from folder2 - removeFolderPermission(t, permissionsStore, 1, userID, models.ROLE_EDITOR, "folder2") + // remove permissions from folder2org.ROLE + removeFolderPermission(t, permissionsStore, 1, userID, org.RoleEditor, "folder2") apiClient.ReloadCachedPermissions(t) // make sure that folder2 is not included in the response @@ -698,8 +698,8 @@ func TestPrometheusRulesPermissions(t *testing.T) { require.Equal(t, "folder1", body.Data.Groups[0].File) } - // remove permissions from folder1 - removeFolderPermission(t, permissionsStore, 1, userID, models.ROLE_EDITOR, "folder1") + // remove permissions from folder1org.ROLE + removeFolderPermission(t, permissionsStore, 1, userID, org.RoleEditor, "folder1") apiClient.ReloadCachedPermissions(t) // make sure that no folders are included in the response @@ -726,7 +726,7 @@ func TestPrometheusRulesPermissions(t *testing.T) { } } -func removeFolderPermission(t *testing.T, store *acdb.AccessControlStore, orgID, userID int64, role models.RoleType, uid string) { +func removeFolderPermission(t *testing.T, store *acdb.AccessControlStore, orgID, userID int64, role org.RoleType, uid string) { t.Helper() // remove user permissions on folder _, _ = store.SetUserResourcePermission(context.Background(), orgID, accesscontrol.User{ID: userID}, types.SetResourcePermissionCommand{ diff --git a/pkg/tests/api/alerting/api_provisioning_test.go b/pkg/tests/api/alerting/api_provisioning_test.go index f4d78dde729..33c4495a608 100644 --- a/pkg/tests/api/alerting/api_provisioning_test.go +++ b/pkg/tests/api/alerting/api_provisioning_test.go @@ -7,7 +7,7 @@ import ( "net/http" "testing" - "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/tests/testinfra" "github.com/stretchr/testify/require" @@ -25,17 +25,17 @@ func TestProvisioning(t *testing.T) { // Create a users to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_VIEWER), + DefaultOrgRole: string(org.RoleViewer), Password: "viewer", Login: "viewer", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "editor", Login: "editor", }) createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) diff --git a/pkg/tests/api/alerting/api_ruler_test.go b/pkg/tests/api/alerting/api_ruler_test.go index cb9c4df0c88..96a755135ac 100644 --- a/pkg/tests/api/alerting/api_ruler_test.go +++ b/pkg/tests/api/alerting/api_ruler_test.go @@ -13,10 +13,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/models" acdb "github.com/grafana/grafana/pkg/services/accesscontrol/database" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" "github.com/grafana/grafana/pkg/util" @@ -36,7 +36,7 @@ func TestAlertRulePermissions(t *testing.T) { // Create a user to make authenticated requests userID := createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -176,7 +176,7 @@ func TestAlertRulePermissions(t *testing.T) { assert.JSONEq(t, expectedGetNamespaceResponseBody, body) // remove permissions from folder2 - removeFolderPermission(t, permissionsStore, 1, userID, models.ROLE_EDITOR, "folder2") + removeFolderPermission(t, permissionsStore, 1, userID, org.RoleEditor, "folder2") apiClient.ReloadCachedPermissions(t) // make sure that folder2 is not included in the response @@ -250,7 +250,7 @@ func TestAlertRulePermissions(t *testing.T) { } // Remove permissions from folder1. - removeFolderPermission(t, permissionsStore, 1, userID, models.ROLE_EDITOR, "folder1") + removeFolderPermission(t, permissionsStore, 1, userID, org.RoleEditor, "folder1") apiClient.ReloadCachedPermissions(t) { u := fmt.Sprintf("http://grafana:password@%s/api/ruler/grafana/api/v1/rules", grafanaListedAddr) @@ -326,7 +326,7 @@ func TestAlertRuleConflictingTitle(t *testing.T) { // Create user createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) @@ -393,7 +393,7 @@ func TestRulerRulesFilterByDashboard(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -731,7 +731,7 @@ func TestRuleGroupSequence(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) @@ -827,7 +827,7 @@ func TestRuleUpdate(t *testing.T) { // Create a user to make authenticated requests createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: "password", Login: "grafana", }) diff --git a/pkg/tests/api/correlations/correlations_create_test.go b/pkg/tests/api/correlations/correlations_create_test.go index 8808c218040..aa3fcee75b2 100644 --- a/pkg/tests/api/correlations/correlations_create_test.go +++ b/pkg/tests/api/correlations/correlations_create_test.go @@ -7,9 +7,9 @@ import ( "net/http" "testing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/correlations" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -30,12 +30,12 @@ func TestIntegrationCreateCorrelation(t *testing.T) { } ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: editorUser.password, Login: editorUser.username, }) ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: adminUser.password, Login: adminUser.username, }) diff --git a/pkg/tests/api/correlations/correlations_delete_test.go b/pkg/tests/api/correlations/correlations_delete_test.go index 2ac6f3861af..a09d330b64e 100644 --- a/pkg/tests/api/correlations/correlations_delete_test.go +++ b/pkg/tests/api/correlations/correlations_delete_test.go @@ -7,9 +7,9 @@ import ( "net/http" "testing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/correlations" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -30,12 +30,12 @@ func TestIntegrationDeleteCorrelation(t *testing.T) { } ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: editorUser.password, Login: editorUser.username, }) ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: adminUser.password, Login: adminUser.username, }) diff --git a/pkg/tests/api/correlations/correlations_update_test.go b/pkg/tests/api/correlations/correlations_update_test.go index 8da912e5e72..d6165f82b31 100644 --- a/pkg/tests/api/correlations/correlations_update_test.go +++ b/pkg/tests/api/correlations/correlations_update_test.go @@ -7,9 +7,9 @@ import ( "net/http" "testing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/correlations" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -30,12 +30,12 @@ func TestIntegrationUpdateCorrelation(t *testing.T) { } ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_EDITOR), + DefaultOrgRole: string(org.RoleEditor), Password: editorUser.password, Login: editorUser.username, }) ctx.createUser(user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: adminUser.password, Login: adminUser.username, }) diff --git a/pkg/tests/api/dashboards/api_dashboards_test.go b/pkg/tests/api/dashboards/api_dashboards_test.go index b05709cf230..c3f1ea2d230 100644 --- a/pkg/tests/api/dashboards/api_dashboards_test.go +++ b/pkg/tests/api/dashboards/api_dashboards_test.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboardimport" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/plugindashboards" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" @@ -38,7 +39,7 @@ func TestDashboardQuota(t *testing.T) { grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path) // Create user createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) @@ -131,7 +132,7 @@ providers: grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path) // Create user createUser(t, store, user.CreateUserCommand{ - DefaultOrgRole: string(models.ROLE_ADMIN), + DefaultOrgRole: string(org.RoleAdmin), Password: "admin", Login: "admin", }) diff --git a/pkg/tests/testinfra/testinfra.go b/pkg/tests/testinfra/testinfra.go index cae8ee96d75..4ac4e6db647 100644 --- a/pkg/tests/testinfra/testinfra.go +++ b/pkg/tests/testinfra/testinfra.go @@ -19,8 +19,8 @@ import ( "github.com/grafana/grafana/pkg/api" "github.com/grafana/grafana/pkg/extensions" "github.com/grafana/grafana/pkg/infra/fs" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/server" + "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/setting" ) @@ -321,7 +321,7 @@ type GrafanaOpts struct { EnableFeatureToggles []string NGAlertAdminConfigPollInterval time.Duration NGAlertAlertmanagerConfigPollInterval time.Duration - AnonymousUserRole models.RoleType + AnonymousUserRole org.RoleType EnableQuota bool DashboardOrgQuota *int64 DisableAnonymous bool diff --git a/pkg/tsdb/legacydata/contracts.go b/pkg/tsdb/legacydata/contracts.go index d1b2d1f6e65..224733c9b6a 100644 --- a/pkg/tsdb/legacydata/contracts.go +++ b/pkg/tsdb/legacydata/contracts.go @@ -10,8 +10,8 @@ import ( "github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) // RequestHandler is a data request handler interface. @@ -37,7 +37,7 @@ type DataQuery struct { Queries []DataSubQuery Headers map[string]string Debug bool - User *models.SignedInUser + User *user.SignedInUser } type DataTable struct { diff --git a/pkg/web/webtest/webtest.go b/pkg/web/webtest/webtest.go index c0cd02767e7..d76f6b56b5d 100644 --- a/pkg/web/webtest/webtest.go +++ b/pkg/web/webtest/webtest.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/web" ) @@ -109,7 +110,7 @@ func RequestWithWebContext(req *http.Request, c *models.ReqContext) *http.Reques return req } -func RequestWithSignedInUser(req *http.Request, user *models.SignedInUser) *http.Request { +func RequestWithSignedInUser(req *http.Request, user *user.SignedInUser) *http.Request { return RequestWithWebContext(req, &models.ReqContext{ SignedInUser: user, IsSignedIn: true, diff --git a/pkg/web/webtest/webtest_test.go b/pkg/web/webtest/webtest_test.go index 3bb55911ded..e5aea951888 100644 --- a/pkg/web/webtest/webtest_test.go +++ b/pkg/web/webtest/webtest_test.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" ) @@ -87,7 +88,7 @@ func TestServerClient(t *testing.T) { t.Run("Making a request with user 1 should return user 1 as signed in user", func(t *testing.T) { req := s.NewRequest(http.MethodGet, "/test", nil) req = RequestWithWebContext(req, &models.ReqContext{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ UserId: 1, }, }) @@ -99,7 +100,7 @@ func TestServerClient(t *testing.T) { require.NoError(t, err) require.NoError(t, resp.Body.Close()) - var user models.SignedInUser + var user user.SignedInUser err = json.Unmarshal(bytes, &user) require.NoError(t, err) require.NotNil(t, user) @@ -109,7 +110,7 @@ func TestServerClient(t *testing.T) { t.Run("Making a request with user 2 should return user 2 as signed in user", func(t *testing.T) { req := s.NewRequest(http.MethodGet, "/test", nil) req = RequestWithWebContext(req, &models.ReqContext{ - SignedInUser: &models.SignedInUser{ + SignedInUser: &user.SignedInUser{ UserId: 2, }, }) @@ -121,7 +122,7 @@ func TestServerClient(t *testing.T) { require.NoError(t, err) require.NoError(t, resp.Body.Close()) - var user models.SignedInUser + var user user.SignedInUser err = json.Unmarshal(bytes, &user) require.NoError(t, err) require.NotNil(t, user)