From a3075822129457e9f1ff5c724f2446f2035e13cf Mon Sep 17 00:00:00 2001 From: Jo Date: Mon, 28 Aug 2023 21:05:59 +0200 Subject: [PATCH] Revert "Replace signed in user for identity.requester (#73750)" (#73962) This reverts commit 9b9c9e83dc7131c7abdb7ea538af39feaa8f9596. --- pkg/api/dashboard.go | 172 +++++++----------- pkg/api/dashboard_test.go | 102 +++++------ pkg/expr/service.go | 6 +- pkg/expr/testing.go | 14 +- pkg/expr/transform.go | 4 +- pkg/services/alerting/models.go | 4 +- .../dashboardimport/service/service_test.go | 11 +- pkg/services/dashboards/models.go | 3 +- .../dashboards/service/dashboard_service.go | 36 +--- .../dashboard_service_integration_test.go | 51 +----- pkg/services/datasources/datasources.go | 6 +- .../datasources/fakes/fake_cache_service.go | 6 +- pkg/services/datasources/guardian/provider.go | 6 +- pkg/services/datasources/service/cache.go | 26 +-- pkg/services/folder/folderimpl/folder.go | 18 +- pkg/services/folder/model.go | 2 - .../guardian/accesscontrol_guardian.go | 30 ++- pkg/services/guardian/guardian.go | 76 ++++---- pkg/services/guardian/provider.go | 18 +- pkg/services/live/features/broadcast.go | 10 +- pkg/services/live/features/dashboard.go | 20 +- pkg/services/live/features/plugin.go | 10 +- pkg/services/live/features/plugin_mock.go | 4 +- pkg/services/live/live.go | 67 ++++--- pkg/services/live/livecontext/context.go | 8 +- pkg/services/live/liveplugin/plugin.go | 6 +- pkg/services/live/managedstream/runner.go | 8 +- pkg/services/live/model/model.go | 6 +- pkg/services/live/pipeline/auth.go | 6 +- pkg/services/live/pipeline/pipeline.go | 6 +- .../live/pipeline/subscribe_builtin.go | 4 +- pkg/services/live/pushws/push_pipeline.go | 2 +- pkg/services/live/pushws/push_stream.go | 2 +- pkg/services/live/runstream/manager.go | 8 +- pkg/services/live/runstream/manager_test.go | 40 ++-- pkg/services/live/runstream/mock.go | 4 +- pkg/services/ngalert/api/lotex_ruler_test.go | 6 +- .../pluginsintegration/adapters/adapters.go | 16 +- .../plugincontext/plugincontext.go | 12 +- pkg/services/query/query.go | 20 +- pkg/services/query/query_service_mock.go | 8 +- pkg/services/query/query_test.go | 5 +- pkg/services/user/identity.go | 13 -- 43 files changed, 359 insertions(+), 523 deletions(-) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 6cc09c69e14..5038c2e02ef 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -20,7 +20,6 @@ import ( "github.com/grafana/grafana/pkg/kinds/dashboard" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/alerting" - "github.com/grafana/grafana/pkg/services/auth/identity" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" @@ -33,7 +32,6 @@ import ( "github.com/grafana/grafana/pkg/services/star" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util" - "github.com/grafana/grafana/pkg/util/errutil" "github.com/grafana/grafana/pkg/web" ) @@ -46,27 +44,15 @@ func (hs *HTTPServer) isDashboardStarredByUser(c *contextmodel.ReqContext, dashI return false, nil } - namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() - - if namespaceID != identity.NamespaceUser { - return false, errutil.BadRequest("User does not belong to a user namespace") - } - - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - - if err != nil { - return false, err - } - - query := star.IsStarredByUserQuery{UserID: userID, DashboardID: dashID} + query := star.IsStarredByUserQuery{UserID: c.UserID, DashboardID: dashID} return hs.starService.IsStarredByUser(c.Req.Context(), &query) } func dashboardGuardianResponse(err error) response.Response { if err != nil { - return response.Error(http.StatusInternalServerError, "Error while checking dashboard permissions", err) + return response.Error(500, "Error while checking dashboard permissions", err) } - return response.Error(http.StatusForbidden, "Access denied to this dashboard", nil) + return response.Error(403, "Access denied to this dashboard", nil) } // swagger:route POST /dashboards/trim dashboards trimDashboard @@ -109,7 +95,7 @@ func (hs *HTTPServer) TrimDashboard(c *contextmodel.ReqContext) response.Respons // 500: internalServerError func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response { uid := web.Params(c.Req)[":uid"] - dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgID, 0, uid) if rsp != nil { return rsp } @@ -122,9 +108,9 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response // If public dashboards is enabled and we have a public dashboard, update meta // values if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) { - publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(c.Req.Context(), c.SignedInUser.GetOrgID(), dash.UID) + publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(c.Req.Context(), c.OrgID, dash.UID) if err != nil && !errors.Is(err, publicdashboardModels.ErrPublicDashboardNotFound) { - return response.Error(http.StatusInternalServerError, "Error while retrieving public dashboards", err) + return response.Error(500, "Error while retrieving public dashboards", err) } if publicDashboard != nil { @@ -142,10 +128,10 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response } } if isEmptyData { - return response.Error(http.StatusInternalServerError, "Error while loading dashboard, dashboard data is invalid", nil) + return response.Error(500, "Error while loading dashboard, dashboard data is invalid", nil) } } - guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -160,7 +146,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response isStarred, err := hs.isDashboardStarredByUser(c, dash.ID) if err != nil { - return response.Error(http.StatusInternalServerError, "Error while checking if dashboard was starred by user", err) + return response.Error(500, "Error while checking if dashboard was starred by user", err) } // Finding creator and last updater of the dashboard updater, creator := anonString, anonString @@ -200,13 +186,13 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response // lookup folder title if dash.FolderID > 0 { - query := dashboards.GetDashboardQuery{ID: dash.FolderID, OrgID: c.SignedInUser.GetOrgID()} + query := dashboards.GetDashboardQuery{ID: dash.FolderID, OrgID: c.OrgID} queryResult, err := hs.DashboardService.GetDashboard(c.Req.Context(), &query) if err != nil { if errors.Is(err, dashboards.ErrFolderNotFound) { - return response.Error(http.StatusNotFound, "Folder not found", err) + return response.Error(404, "Folder not found", err) } - return response.Error(http.StatusInternalServerError, "Dashboard folder could not be read", err) + return response.Error(500, "Dashboard folder could not be read", err) } meta.FolderUid = queryResult.UID meta.FolderTitle = queryResult.Title @@ -215,7 +201,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(c.Req.Context(), dash.ID) if err != nil { - return response.Error(http.StatusInternalServerError, "Error while checking if dashboard is provisioned", err) + return response.Error(500, "Error while checking if dashboard is provisioned", err) } if provisioningData != nil { @@ -289,7 +275,7 @@ func (hs *HTTPServer) getDashboardHelper(ctx context.Context, orgID int64, id in queryResult, err := hs.DashboardService.GetDashboard(ctx, &query) if err != nil { - return nil, response.Error(http.StatusNotFound, "Dashboard not found", err) + return nil, response.Error(404, "Dashboard not found", err) } return queryResult, nil @@ -312,11 +298,11 @@ func (hs *HTTPServer) DeleteDashboardByUID(c *contextmodel.ReqContext) response. } func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Response { - dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, web.Params(c.Req)[":uid"]) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgID, 0, web.Params(c.Req)[":uid"]) if rsp != nil { return rsp } - guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -325,17 +311,10 @@ func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Respo return dashboardGuardianResponse(err) } - namespaceID, userIDStr := c.SignedInUser.GetNamespacedID() - // disconnect all library elements for this dashboard err = hs.LibraryElementService.DisconnectElementsFromDashboard(c.Req.Context(), dash.ID) if err != nil { - hs.log.Error( - "Failed to disconnect library elements", - "dashboard", dash.ID, - "namespaceID", namespaceID, - "user", userIDStr, - "error", err) + hs.log.Error("Failed to disconnect library elements", "dashboard", dash.ID, "user", c.SignedInUser.UserID, "error", err) } // deletes all related public dashboard entities @@ -344,7 +323,7 @@ func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Respo hs.log.Error("Failed to delete public dashboard") } - err = hs.DashboardService.DeleteDashboard(c.Req.Context(), dash.ID, c.SignedInUser.GetOrgID()) + err = hs.DashboardService.DeleteDashboard(c.Req.Context(), dash.ID, c.OrgID) if err != nil { var dashboardErr dashboards.DashboardErr if ok := errors.As(err, &dashboardErr); ok { @@ -352,16 +331,11 @@ func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Respo return response.Error(dashboardErr.StatusCode, dashboardErr.Error(), err) } } - return response.Error(http.StatusInternalServerError, "Failed to delete dashboard", err) - } - - userDTODisplay, err := user.NewUserDisplayDTOFromRequester(c.SignedInUser) - if err != nil { - return response.Error(http.StatusInternalServerError, "Error while parsing the user DTO model", err) + return response.Error(500, "Failed to delete dashboard", err) } if hs.Live != nil { - err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.SignedInUser.GetOrgID(), userDTODisplay, dash.UID) + err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.OrgID, c.ToUserDisplayDTO(), dash.UID) if err != nil { hs.log.Error("Failed to broadcast delete info", "dashboard", dash.UID, "error", err) } @@ -422,26 +396,19 @@ func (hs *HTTPServer) PostDashboard(c *contextmodel.ReqContext) response.Respons func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.SaveDashboardCommand) response.Response { ctx := c.Req.Context() var err error - - namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) - } - - cmd.OrgID = c.SignedInUser.GetOrgID() - cmd.UserID = userID + cmd.OrgID = c.OrgID + cmd.UserID = c.UserID if cmd.FolderUID != "" { folder, err := hs.folderService.Get(ctx, &folder.GetFolderQuery{ - OrgID: c.SignedInUser.GetOrgID(), + OrgID: c.OrgID, UID: &cmd.FolderUID, SignedInUser: c.SignedInUser, }) if err != nil { if errors.Is(err, dashboards.ErrFolderNotFound) { - return response.Error(http.StatusBadRequest, "Folder not found", err) + return response.Error(400, "Folder not found", err) } - return response.Error(http.StatusInternalServerError, "Error while checking folder ID", err) + return response.Error(500, "Error while checking folder ID", err) } cmd.FolderID = folder.ID } @@ -451,10 +418,10 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S if newDashboard { limitReached, err := hs.QuotaService.QuotaReached(c, dashboards.QuotaTargetSrv) if err != nil { - return response.Error(http.StatusInternalServerError, "failed to get quota", err) + return response.Error(500, "failed to get quota", err) } if limitReached { - return response.Error(http.StatusForbidden, "Quota reached", nil) + return response.Error(403, "Quota reached", nil) } } @@ -462,13 +429,13 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S if dash.ID != 0 { data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(c.Req.Context(), dash.ID) if err != nil { - return response.Error(http.StatusInternalServerError, "Error while checking if dashboard is provisioned using ID", err) + return response.Error(500, "Error while checking if dashboard is provisioned using ID", err) } provisioningData = data } else if dash.UID != "" { data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardUID(c.Req.Context(), dash.OrgID, dash.UID) if err != nil && !errors.Is(err, dashboards.ErrProvisionedDashboardNotFound) && !errors.Is(err, dashboards.ErrDashboardNotFound) { - return response.Error(http.StatusInternalServerError, "Error while checking if dashboard is provisioned", err) + return response.Error(500, "Error while checking if dashboard is provisioned", err) } provisioningData = data } @@ -481,7 +448,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S dashItem := &dashboards.SaveDashboardDTO{ Dashboard: dash, Message: cmd.Message, - OrgID: c.SignedInUser.GetOrgID(), + OrgID: c.OrgID, User: c.SignedInUser, Overwrite: cmd.Overwrite, } @@ -494,19 +461,14 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S dashboard = dash // the original request } - userDTODisplay, err := user.NewUserDisplayDTOFromRequester(c.SignedInUser) - if err != nil { - return response.Error(http.StatusInternalServerError, "Error while parsing the user DTO model", err) - } - // This will broadcast all save requests only if a `gitops` observer exists. // gitops is useful when trying to save dashboards in an environment where the user can not save channel := hs.Live.GrafanaScope.Dashboards - liveerr := channel.DashboardSaved(c.SignedInUser.GetOrgID(), userDTODisplay, cmd.Message, dashboard, err) + liveerr := channel.DashboardSaved(c.SignedInUser.OrgID, c.SignedInUser.ToUserDisplayDTO(), cmd.Message, dashboard, err) // When an error exists, but the value broadcast to a gitops listener return 202 - if liveerr == nil && err != nil && channel.HasGitOpsObserver(c.SignedInUser.GetOrgID()) { - return response.JSON(http.StatusAccepted, util.DynMap{ + if liveerr == nil && err != nil && channel.HasGitOpsObserver(c.SignedInUser.OrgID) { + return response.JSON(202, util.DynMap{ "status": "pending", "message": "changes were broadcast to the gitops listener", }) @@ -530,7 +492,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S // connect library panels for this dashboard after the dashboard is stored and has an ID err = hs.LibraryPanelService.ConnectLibraryPanelsForDashboard(ctx, c.SignedInUser, dashboard) if err != nil { - return response.Error(http.StatusInternalServerError, "Error while connecting library panels", err) + return response.Error(500, "Error while connecting library panels", err) } c.TimeRequest(metrics.MApiDashboardSave) @@ -553,17 +515,12 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S // 401: unauthorisedError // 500: internalServerError func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Response { - namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr, "err", err) - } - prefsQuery := pref.GetPreferenceWithDefaultsQuery{OrgID: c.SignedInUser.GetOrgID(), UserID: userID, Teams: c.SignedInUser.GetTeams()} + prefsQuery := pref.GetPreferenceWithDefaultsQuery{OrgID: c.OrgID, UserID: c.SignedInUser.UserID, Teams: c.Teams} homePage := hs.Cfg.HomePage preference, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery) if err != nil { - return response.Error(http.StatusInternalServerError, "Failed to get preferences", err) + return response.Error(500, "Failed to get preferences", err) } if preference.HomeDashboardID == 0 && len(homePage) > 0 { @@ -592,7 +549,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Resp // nolint:gosec file, err := os.Open(filePath) if err != nil { - return response.Error(http.StatusInternalServerError, "Failed to load home dashboard", err) + return response.Error(500, "Failed to load home dashboard", err) } defer func() { if err := file.Close(); err != nil { @@ -607,7 +564,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Resp jsonParser := json.NewDecoder(file) if err := jsonParser.Decode(dash.Dashboard); err != nil { - return response.Error(http.StatusInternalServerError, "Failed to load home dashboard", err) + return response.Error(500, "Failed to load home dashboard", err) } hs.addGettingStartedPanelToHomeDashboard(c, dash.Dashboard) @@ -679,12 +636,12 @@ func (hs *HTTPServer) GetDashboardVersions(c *contextmodel.ReqContext) response. } } - dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), dashID, dashUID) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgID, dashID, dashUID) if rsp != nil { return rsp } - guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -693,7 +650,7 @@ func (hs *HTTPServer) GetDashboardVersions(c *contextmodel.ReqContext) response. } query := dashver.ListDashboardVersionsQuery{ - OrgID: c.SignedInUser.GetOrgID(), + OrgID: c.OrgID, DashboardID: dash.ID, DashboardUID: dash.UID, Limit: c.QueryInt("limit"), @@ -702,7 +659,7 @@ func (hs *HTTPServer) GetDashboardVersions(c *contextmodel.ReqContext) response. versions, err := hs.dashboardVersionService.List(c.Req.Context(), &query) if err != nil { - return response.Error(http.StatusNotFound, fmt.Sprintf("No versions found for dashboardId %d", dash.ID), err) + return response.Error(404, fmt.Sprintf("No versions found for dashboardId %d", dash.ID), err) } loginMem := make(map[int64]string, len(versions)) @@ -790,12 +747,12 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R } } - dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), dashID, dashUID) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgID, dashID, dashUID) if rsp != nil { return rsp } - guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -806,7 +763,7 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R version, _ := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 32) query := dashver.GetDashboardVersionQuery{ - OrgID: c.SignedInUser.GetOrgID(), + OrgID: c.OrgID, DashboardID: dash.ID, DashboardUID: dash.UID, Version: int(version), @@ -814,7 +771,7 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R res, err := hs.dashboardVersionService.Get(c.Req.Context(), &query) if err != nil { - return response.Error(http.StatusInternalServerError, fmt.Sprintf("Dashboard version %d not found for dashboardId %d", query.Version, dash.ID), err) + return response.Error(500, fmt.Sprintf("Dashboard version %d not found for dashboardId %d", query.Version, dash.ID), err) } creator := anonString @@ -922,7 +879,7 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons if err := web.Bind(c.Req, &apiOptions); err != nil { return response.Error(http.StatusBadRequest, "bad request data", err) } - guardianBase, err := guardian.New(c.Req.Context(), apiOptions.Base.DashboardId, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardianBase, err := guardian.New(c.Req.Context(), apiOptions.Base.DashboardId, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -932,7 +889,7 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons } if apiOptions.Base.DashboardId != apiOptions.New.DashboardId { - guardianNew, err := guardian.New(c.Req.Context(), apiOptions.New.DashboardId, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardianNew, err := guardian.New(c.Req.Context(), apiOptions.New.DashboardId, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -943,7 +900,7 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons } options := dashdiffs.Options{ - OrgId: c.SignedInUser.GetOrgID(), + OrgId: c.OrgID, DiffType: dashdiffs.ParseDiffType(apiOptions.DiffType), Base: dashdiffs.DiffTarget{ DashboardId: apiOptions.Base.DashboardId, @@ -966,9 +923,9 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons baseVersionRes, err := hs.dashboardVersionService.Get(c.Req.Context(), &baseVersionQuery) if err != nil { if errors.Is(err, dashver.ErrDashboardVersionNotFound) { - return response.Error(http.StatusNotFound, "Dashboard version not found", err) + return response.Error(404, "Dashboard version not found", err) } - return response.Error(http.StatusInternalServerError, "Unable to compute diff", err) + return response.Error(500, "Unable to compute diff", err) } newVersionQuery := dashver.GetDashboardVersionQuery{ @@ -980,9 +937,9 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons newVersionRes, err := hs.dashboardVersionService.Get(c.Req.Context(), &newVersionQuery) if err != nil { if errors.Is(err, dashver.ErrDashboardVersionNotFound) { - return response.Error(http.StatusNotFound, "Dashboard version not found", err) + return response.Error(404, "Dashboard version not found", err) } - return response.Error(http.StatusInternalServerError, "Unable to compute diff", err) + return response.Error(500, "Unable to compute diff", err) } baseData := baseVersionRes.Data @@ -992,9 +949,9 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons if err != nil { if errors.Is(err, dashver.ErrDashboardVersionNotFound) { - return response.Error(http.StatusNotFound, "Dashboard version not found", err) + return response.Error(404, "Dashboard version not found", err) } - return response.Error(http.StatusInternalServerError, "Unable to compute diff", err) + return response.Error(500, "Unable to compute diff", err) } if options.DiffType == dashdiffs.DiffDelta { @@ -1046,12 +1003,12 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *contextmodel.ReqContext) respon } } - dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), dashID, dashUID) + dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.OrgID, dashID, dashUID) if rsp != nil { return rsp } - guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) + guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.OrgID, c.SignedInUser) if err != nil { return response.Err(err) } @@ -1060,21 +1017,16 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *contextmodel.ReqContext) respon return dashboardGuardianResponse(err) } - versionQuery := dashver.GetDashboardVersionQuery{DashboardID: dashID, DashboardUID: dash.UID, Version: apiCmd.Version, OrgID: c.SignedInUser.GetOrgID()} + versionQuery := dashver.GetDashboardVersionQuery{DashboardID: dashID, DashboardUID: dash.UID, Version: apiCmd.Version, OrgID: c.OrgID} version, err := hs.dashboardVersionService.Get(c.Req.Context(), &versionQuery) if err != nil { - return response.Error(http.StatusNotFound, "Dashboard version not found", nil) - } - - userID, err := identity.IntIdentifier(c.SignedInUser.GetNamespacedID()) - if err != nil { - return response.Error(http.StatusInternalServerError, "failed to get user id", err) + return response.Error(404, "Dashboard version not found", nil) } saveCmd := dashboards.SaveDashboardCommand{} saveCmd.RestoredFrom = version.Version - saveCmd.OrgID = c.SignedInUser.GetOrgID() - saveCmd.UserID = userID + saveCmd.OrgID = c.OrgID + saveCmd.UserID = c.UserID saveCmd.Dashboard = version.Data saveCmd.Dashboard.Set("version", dash.Version) saveCmd.Dashboard.Set("uid", dash.UID) @@ -1093,7 +1045,7 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *contextmodel.ReqContext) respon // 401: unauthorisedError // 500: internalServerError func (hs *HTTPServer) GetDashboardTags(c *contextmodel.ReqContext) { - query := dashboards.GetDashboardTagsQuery{OrgID: c.SignedInUser.GetOrgID()} + query := dashboards.GetDashboardTagsQuery{OrgID: c.OrgID} queryResult, err := hs.DashboardService.GetDashboardTags(c.Req.Context(), &query) if err != nil { c.JsonApiErr(500, "Failed to get tags from database", err) diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 2ef06395503..ecf71818572 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -78,7 +78,6 @@ func TestGetHomeDashboard(t *testing.T) { preferenceService: prefService, dashboardVersionService: dashboardVersionService, Kinds: corekind.NewBase(nil), - log: log.New("test-logger"), } tests := []struct { @@ -203,7 +202,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.sqlStore = mockSQLStore hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", @@ -212,7 +211,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.sqlStore = mockSQLStore hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) }) @@ -235,7 +234,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.sqlStore = mockSQLStore hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) var version *dashver.DashboardVersionMeta err := json.NewDecoder(sc.resp.Body).Decode(&version) require.NoError(t, err) @@ -247,7 +246,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) }) }) @@ -311,7 +310,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.handlerFunc = hs.GetDashboard sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", @@ -320,7 +319,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.sqlStore = mockSQLStore hs.callDeleteDashboardByUID(t, sc, dashboardService, nil) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", @@ -329,7 +328,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.sqlStore = mockSQLStore hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", @@ -337,7 +336,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) }) @@ -350,7 +349,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.handlerFunc = hs.GetDashboard sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", @@ -358,7 +357,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() hs.callDeleteDashboardByUID(t, sc, dashboardService, nil) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", @@ -366,7 +365,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", @@ -374,7 +373,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) }) @@ -414,7 +413,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { pubdashService.On("DeleteByDashboard", mock.Anything, mock.Anything).Return(nil) hs.callDeleteDashboardByUID(t, sc, dashboardService, pubdashService) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) }) @@ -448,7 +447,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUpInner() hs.callDeleteDashboardByUID(t, sc, dashboardService, nil) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) }) @@ -487,21 +486,21 @@ func TestDashboardAPIEndpoint(t *testing.T) { pubdashService.On("DeleteByDashboard", mock.Anything, mock.Anything).Return(nil) hs.callDeleteDashboardByUID(t, sc, dashboardService, pubdashService) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { setUpInner() hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) { setUpInner() hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) }) @@ -531,21 +530,21 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUpInner() hs.callDeleteDashboardByUID(t, sc, dashboardService, nil) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) { setUpInner() hs.callGetDashboardVersion(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions", "/api/dashboards/id/:dashboardId/versions", role, func(sc *scenarioContext) { setUpInner() hs.callGetDashboardVersions(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, mockSQLStore) }) }) @@ -655,7 +654,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { postDashboardScenario(t, "When calling POST on", "/api/dashboards", "/api/dashboards", cmd, dashboardService, mockFolder, func(sc *scenarioContext) { callPostDashboard(sc) - assert.Equal(t, http.StatusInternalServerError, sc.resp.Code) + assert.Equal(t, 500, sc.resp.Code) }) }) @@ -665,23 +664,23 @@ func TestDashboardAPIEndpoint(t *testing.T) { SaveError error ExpectedStatusCode int }{ - {SaveError: dashboards.ErrDashboardNotFound, ExpectedStatusCode: http.StatusNotFound}, - {SaveError: dashboards.ErrFolderNotFound, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardWithSameUIDExists, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardWithSameNameInFolderExists, ExpectedStatusCode: http.StatusPreconditionFailed}, - {SaveError: dashboards.ErrDashboardVersionMismatch, ExpectedStatusCode: http.StatusPreconditionFailed}, - {SaveError: dashboards.ErrDashboardTitleEmpty, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardFolderCannotHaveParent, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: alerting.ValidationError{Reason: "Mu"}, ExpectedStatusCode: http.StatusUnprocessableEntity}, - {SaveError: dashboards.ErrDashboardTypeMismatch, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardFolderWithSameNameAsDashboard, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardWithSameNameAsFolder, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardFolderNameExists, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardUpdateAccessDenied, ExpectedStatusCode: http.StatusForbidden}, - {SaveError: dashboards.ErrDashboardInvalidUid, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardUidTooLong, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.ErrDashboardCannotSaveProvisionedDashboard, ExpectedStatusCode: http.StatusBadRequest}, - {SaveError: dashboards.UpdatePluginDashboardError{PluginId: "plug"}, ExpectedStatusCode: http.StatusPreconditionFailed}, + {SaveError: dashboards.ErrDashboardNotFound, ExpectedStatusCode: 404}, + {SaveError: dashboards.ErrFolderNotFound, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardWithSameUIDExists, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardWithSameNameInFolderExists, ExpectedStatusCode: 412}, + {SaveError: dashboards.ErrDashboardVersionMismatch, ExpectedStatusCode: 412}, + {SaveError: dashboards.ErrDashboardTitleEmpty, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardFolderCannotHaveParent, ExpectedStatusCode: 400}, + {SaveError: alerting.ValidationError{Reason: "Mu"}, ExpectedStatusCode: 422}, + {SaveError: dashboards.ErrDashboardTypeMismatch, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardFolderWithSameNameAsDashboard, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardWithSameNameAsFolder, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardFolderNameExists, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardUpdateAccessDenied, ExpectedStatusCode: 403}, + {SaveError: dashboards.ErrDashboardInvalidUid, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardUidTooLong, ExpectedStatusCode: 400}, + {SaveError: dashboards.ErrDashboardCannotSaveProvisionedDashboard, ExpectedStatusCode: 400}, + {SaveError: dashboards.UpdatePluginDashboardError{PluginId: "plug"}, ExpectedStatusCode: 412}, } cmd := dashboards.SaveDashboardCommand{ @@ -698,7 +697,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { postDashboardScenario(t, fmt.Sprintf("Expect '%s' error when calling POST on", tc.SaveError.Error()), "/api/dashboards", "/api/dashboards", cmd, dashboardService, nil, func(sc *scenarioContext) { callPostDashboard(sc) - assert.Equal(t, tc.ExpectedStatusCode, sc.resp.Code, sc.resp.Body.String()) + assert.Equal(t, tc.ExpectedStatusCode, sc.resp.Code) }) } }) @@ -717,7 +716,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { callPostDashboard(sc) result := sc.ToJSON() - assert.Equal(t, http.StatusUnprocessableEntity, sc.resp.Code) + assert.Equal(t, 422, sc.resp.Code) assert.False(t, result.Get("isValid").MustBool()) assert.NotEmpty(t, result.Get("message").MustString()) }, sqlmock) @@ -733,7 +732,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { callPostDashboard(sc) result := sc.ToJSON() - assert.Equal(t, http.StatusPreconditionFailed, sc.resp.Code) + assert.Equal(t, 412, sc.resp.Code) assert.False(t, result.Get("isValid").MustBool()) assert.Equal(t, "invalid schema version", result.Get("message").MustString()) }, sqlmock) @@ -752,7 +751,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { callPostDashboard(sc) result := sc.ToJSON() - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) assert.True(t, result.Get("isValid").MustBool()) }, sqlmock) }) @@ -804,7 +803,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { setUp() callPostDashboard(sc) - assert.Equal(t, http.StatusForbidden, sc.resp.Code) + assert.Equal(t, 403, sc.resp.Code) }, sqlmock, fakeDashboardVersionService) }) @@ -814,7 +813,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { // This test shouldn't hit GetDashboardACLInfoList, so no setup needed sc.dashboardVersionService = fakeDashboardVersionService callPostDashboard(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, sqlmock, fakeDashboardVersionService) }) }) @@ -851,7 +850,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { sc.dashboardVersionService = fakeDashboardVersionService callRestoreDashboardVersion(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) }) @@ -884,7 +883,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { restoreDashboardVersionScenario(t, "When calling POST on", "/api/dashboards/id/1/restore", "/api/dashboards/id/:dashboardId/restore", dashboardService, fakeDashboardVersionService, cmd, func(sc *scenarioContext) { callRestoreDashboardVersion(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) }, mockSQLStore) }) @@ -940,7 +939,7 @@ func TestDashboardAPIEndpoint(t *testing.T) { } hs.callGetDashboard(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) dash := dtos.DashboardFullWithMeta{} err := json.NewDecoder(sc.resp.Body).Decode(&dash) @@ -1012,7 +1011,7 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) { ExpectedUser: &user.User{ID: 1, Login: "test-user"}, }).callGetDashboardVersions(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) var versions []dashver.DashboardVersionMeta err := json.NewDecoder(sc.resp.Body).Decode(&versions) require.NoError(t, err) @@ -1038,7 +1037,7 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) { ExpectedError: user.ErrUserNotFound, }).callGetDashboardVersions(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) var versions []dashver.DashboardVersionMeta err := json.NewDecoder(sc.resp.Body).Decode(&versions) require.NoError(t, err) @@ -1064,7 +1063,7 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) { ExpectedError: fmt.Errorf("some error"), }).callGetDashboardVersions(sc) - assert.Equal(t, http.StatusOK, sc.resp.Code) + assert.Equal(t, 200, sc.resp.Code) var versions []dashver.DashboardVersionMeta err := json.NewDecoder(sc.resp.Body).Decode(&versions) require.NoError(t, err) @@ -1193,7 +1192,6 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s Features: featuremgmt.WithFeatures(), Kinds: corekind.NewBase(nil), accesscontrolService: actest.FakeService{}, - log: log.New("test-logger"), } sc := setupScenarioContext(t, url) diff --git a/pkg/expr/service.go b/pkg/expr/service.go index 63fca9e83a4..678be80c093 100644 --- a/pkg/expr/service.go +++ b/pkg/expr/service.go @@ -12,10 +12,10 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -68,8 +68,8 @@ type Service struct { } type pluginContextProvider interface { - Get(ctx context.Context, pluginID string, user identity.Requester, orgID int64) (backend.PluginContext, error) - GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) + Get(ctx context.Context, pluginID string, user *user.SignedInUser, orgID int64) (backend.PluginContext, error) + GetWithDataSource(ctx context.Context, pluginID string, user *user.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, error) } func ProvideService(cfg *setting.Cfg, pluginClient plugins.Client, pCtxProvider *plugincontext.Provider, diff --git a/pkg/expr/testing.go b/pkg/expr/testing.go index 4ffcf124610..38fbda4bbb1 100644 --- a/pkg/expr/testing.go +++ b/pkg/expr/testing.go @@ -5,8 +5,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) type fakePluginContextProvider struct { @@ -20,7 +20,7 @@ type fakePluginContextProvider struct { var _ pluginContextProvider = &fakePluginContextProvider{} -func (f *fakePluginContextProvider) Get(_ context.Context, pluginID string, user identity.Requester, orgID int64) (backend.PluginContext, error) { +func (f *fakePluginContextProvider) Get(_ context.Context, pluginID string, user *user.SignedInUser, orgID int64) (backend.PluginContext, error) { f.recordings = append(f.recordings, struct { method string params []interface{} @@ -31,9 +31,9 @@ func (f *fakePluginContextProvider) Get(_ context.Context, pluginID string, user var u *backend.User if user != nil { u = &backend.User{ - Login: user.GetLogin(), - Name: user.GetDisplayName(), - Email: user.GetEmail(), + Login: user.Login, + Name: user.Name, + Email: user.Email, } } return backend.PluginContext{ @@ -45,7 +45,7 @@ func (f *fakePluginContextProvider) Get(_ context.Context, pluginID string, user }, nil } -func (f *fakePluginContextProvider) GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) { +func (f *fakePluginContextProvider) GetWithDataSource(ctx context.Context, pluginID string, user *user.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, error) { f.recordings = append(f.recordings, struct { method string params []interface{} @@ -57,7 +57,7 @@ func (f *fakePluginContextProvider) GetWithDataSource(ctx context.Context, plugi orgId := int64(1) if user != nil { - orgId = user.GetOrgID() + orgId = user.OrgID } r, err := f.Get(ctx, pluginID, user, orgId) if ds != nil { diff --git a/pkg/expr/transform.go b/pkg/expr/transform.go index ac97c01930c..ead26b6dde6 100644 --- a/pkg/expr/transform.go +++ b/pkg/expr/transform.go @@ -8,8 +8,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) // Request is similar to plugins.DataQuery but with the Time Ranges is per Query. @@ -18,7 +18,7 @@ type Request struct { Debug bool OrgId int64 Queries []Query - User identity.Requester + User *user.SignedInUser } // Query is like plugins.DataSubQuery, but with a a time range, and only the UID diff --git a/pkg/services/alerting/models.go b/pkg/services/alerting/models.go index d2706752819..3193b54c655 100644 --- a/pkg/services/alerting/models.go +++ b/pkg/services/alerting/models.go @@ -4,8 +4,8 @@ import ( "sync" "github.com/grafana/grafana/pkg/components/null" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/user" ) // Job holds state about when the alert rule should be evaluated. @@ -46,7 +46,7 @@ type EvalMatch struct { } type DashAlertInfo struct { - User identity.Requester + User *user.SignedInUser Dash *dashboards.Dashboard OrgID int64 } diff --git a/pkg/services/dashboardimport/service/service_test.go b/pkg/services/dashboardimport/service/service_test.go index 2ed02333ff1..c0c14d601e2 100644 --- a/pkg/services/dashboardimport/service/service_test.go +++ b/pkg/services/dashboardimport/service/service_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboardimport" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/folder" @@ -84,12 +83,9 @@ func TestImportDashboardService(t *testing.T) { require.NotNil(t, resp) require.Equal(t, "UDdpyzz7z", resp.UID) - userID, err := identity.IntIdentifier(importDashboardArg.User.GetNamespacedID()) - require.NoError(t, err) - require.NotNil(t, importDashboardArg) require.Equal(t, int64(3), importDashboardArg.OrgID) - require.Equal(t, int64(2), userID) + require.Equal(t, int64(2), importDashboardArg.User.UserID) require.Equal(t, "prometheus", importDashboardArg.Dashboard.PluginID) require.Equal(t, int64(5), importDashboardArg.Dashboard.FolderID) @@ -151,12 +147,9 @@ func TestImportDashboardService(t *testing.T) { require.NotNil(t, resp) require.Equal(t, "UDdpyzz7z", resp.UID) - userID, err := identity.IntIdentifier(importDashboardArg.User.GetNamespacedID()) - require.NoError(t, err) - require.NotNil(t, importDashboardArg) require.Equal(t, int64(3), importDashboardArg.OrgID) - require.Equal(t, int64(2), userID) + require.Equal(t, int64(2), importDashboardArg.User.UserID) require.Equal(t, "", importDashboardArg.Dashboard.PluginID) require.Equal(t, int64(5), importDashboardArg.Dashboard.FolderID) diff --git a/pkg/services/dashboards/models.go b/pkg/services/dashboards/models.go index a5253cbaaac..7ce7d14a284 100644 --- a/pkg/services/dashboards/models.go +++ b/pkg/services/dashboards/models.go @@ -9,7 +9,6 @@ import ( "github.com/grafana/grafana/pkg/kinds" "github.com/grafana/grafana/pkg/kinds/dashboard" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota" @@ -338,7 +337,7 @@ type GetDashboardRefByIDQuery struct { type SaveDashboardDTO struct { OrgID int64 UpdatedAt time.Time - User identity.Requester + User *user.SignedInUser Message string Overwrite bool Dashboard *Dashboard diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index 55c8de11aeb..24d2fb37082 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/alerting" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -182,18 +181,12 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d } } - namespaceID, userIDstr := dto.User.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - dr.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) - } - cmd := &dashboards.SaveDashboardCommand{ Dashboard: dash.Data, Message: dto.Message, OrgID: dto.OrgID, Overwrite: dto.Overwrite, - UserID: userID, + UserID: dto.User.UserID, FolderID: dash.FolderID, IsFolder: dash.IsFolder, PluginID: dash.PluginID, @@ -216,7 +209,7 @@ func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context. // getGuardianForSavePermissionCheck returns the guardian to be used for checking permission of dashboard // It replaces deleted Dashboard.GetDashboardIdForSavePermissionCheck() -func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user identity.Requester) (guardian.DashboardGuardian, error) { +func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user *user.SignedInUser) (guardian.DashboardGuardian, error) { newDashboard := d.ID == 0 if newDashboard { @@ -304,8 +297,7 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt if dto.Dashboard.ID == 0 { if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil { - namespaceID, userID := dto.User.GetNamespacedID() - dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err) + dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err) } } @@ -345,8 +337,7 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C if dto.Dashboard.ID == 0 { if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil { - namespaceID, userID := dto.User.GetNamespacedID() - dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err) + dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err) } } @@ -394,8 +385,7 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboar // new dashboard created if dto.Dashboard.ID == 0 { if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil { - namespaceID, userID := dto.User.GetNamespacedID() - dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err) + dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err) } } @@ -452,8 +442,7 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashbo } if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil { - namespaceID, userID := dto.User.GetNamespacedID() - dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err) + dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err) } return dash, nil @@ -473,16 +462,9 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto * inFolder := dash.FolderID > 0 var permissions []accesscontrol.SetResourcePermissionCommand - namespaceID, userIDstr := dto.User.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - - if err != nil { - return err - } - - if !provisioned && namespaceID == identity.NamespaceUser { + if !provisioned && dto.User.IsRealUser() && !dto.User.IsAnonymous { permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ - UserID: userID, Permission: dashboards.PERMISSION_ADMIN.String(), + UserID: dto.User.UserID, Permission: dashboards.PERMISSION_ADMIN.String(), }) } @@ -498,7 +480,7 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto * svc = dr.folderPermissions } - _, err = svc.SetPermissions(ctx, dto.OrgID, dash.UID, permissions...) + _, err := svc.SetPermissions(ctx, dto.OrgID, dash.UID, permissions...) if err != nil { return err } diff --git a/pkg/services/dashboards/service/dashboard_service_integration_test.go b/pkg/services/dashboards/service/dashboard_service_integration_test.go index fb888707d37..5e14b530152 100644 --- a/pkg/services/dashboards/service/dashboard_service_integration_test.go +++ b/pkg/services/dashboards/service/dashboard_service_integration_test.go @@ -15,7 +15,6 @@ import ( accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting/models" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -113,12 +112,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sqlStore) assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, "", sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When creating a new dashboard in other folder, it should create dashboard guardian for other folder with correct arguments and rsult in access denied error", @@ -136,12 +132,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.otherSavedFolder.ID, sc.dashboardGuardianMock.DashID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When creating a new dashboard by existing title in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -159,12 +152,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When creating a new dashboard by existing UID in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -183,12 +173,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When updating a dashboard by existing id in the General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -207,12 +194,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When updating a dashboard by existing id in other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -231,12 +215,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When moving a dashboard by existing ID to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -255,12 +236,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When moving a dashboard by existing id to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -279,12 +257,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When moving a dashboard by existing uid to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -303,12 +278,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) permissionScenario(t, "When moving a dashboard by existing UID to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error", @@ -327,12 +299,9 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) { err := callSaveWithError(t, cmd, sc.sqlStore) require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err) - userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID()) - require.NoError(t, err) - assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID) assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID) - assert.Equal(t, cmd.UserID, userID) + assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID) }) }) diff --git a/pkg/services/datasources/datasources.go b/pkg/services/datasources/datasources.go index accc2075887..598803ca07f 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/services/auth/identity" + "github.com/grafana/grafana/pkg/services/user" ) // DataSourceService interface for interacting with datasources. @@ -64,8 +64,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 identity.Requester, 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 identity.Requester, 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 ec0521aced7..58222a4f702 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/services/auth/identity" "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 identity.Requester, 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 identity.Requester, 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/guardian/provider.go b/pkg/services/datasources/guardian/provider.go index d2cd4d529ac..5be645ae4a1 100644 --- a/pkg/services/datasources/guardian/provider.go +++ b/pkg/services/datasources/guardian/provider.go @@ -1,12 +1,12 @@ package guardian import ( - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) type DatasourceGuardianProvider interface { - New(orgID int64, user identity.Requester, dataSources ...datasources.DataSource) DatasourceGuardian + New(orgID int64, user *user.SignedInUser, dataSources ...datasources.DataSource) DatasourceGuardian } type DatasourceGuardian interface { @@ -20,6 +20,6 @@ func ProvideGuardian() *OSSProvider { type OSSProvider struct{} -func (p *OSSProvider) New(orgID int64, user identity.Requester, dataSources ...datasources.DataSource) DatasourceGuardian { +func (p *OSSProvider) New(orgID int64, user *user.SignedInUser, dataSources ...datasources.DataSource) DatasourceGuardian { return &AllowGuardian{} } diff --git a/pkg/services/datasources/service/cache.go b/pkg/services/datasources/service/cache.go index bb56d0fd8e3..a97b9cbcadc 100644 --- a/pkg/services/datasources/service/cache.go +++ b/pkg/services/datasources/service/cache.go @@ -8,9 +8,9 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/localcache" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/datasources/guardian" + "github.com/grafana/grafana/pkg/services/user" ) const ( @@ -38,7 +38,7 @@ type CacheServiceImpl struct { func (dc *CacheServiceImpl) GetDatasource( ctx context.Context, datasourceID int64, - user identity.Requester, + user *user.SignedInUser, skipCache bool, ) (*datasources.DataSource, error) { cacheKey := idKey(datasourceID) @@ -46,7 +46,7 @@ func (dc *CacheServiceImpl) GetDatasource( if !skipCache { if cached, found := dc.CacheService.Get(cacheKey); found { ds := cached.(*datasources.DataSource) - if ds.OrgID == user.GetOrgID() { + if ds.OrgID == user.OrgID { if err := dc.canQuery(user, ds); err != nil { return nil, err } @@ -55,9 +55,9 @@ func (dc *CacheServiceImpl) GetDatasource( } } - dc.logger.FromContext(ctx).Debug("Querying for data source via SQL store", "id", datasourceID, "orgId", user.GetOrgID()) + dc.logger.FromContext(ctx).Debug("Querying for data source via SQL store", "id", datasourceID, "orgId", user.OrgID) - query := &datasources.GetDataSourceQuery{ID: datasourceID, OrgID: user.GetOrgID()} + query := &datasources.GetDataSourceQuery{ID: datasourceID, OrgID: user.OrgID} ss := SqlStore{db: dc.SQLStore, logger: dc.logger} ds, err := ss.GetDataSource(ctx, query) if err != nil { @@ -79,21 +79,21 @@ func (dc *CacheServiceImpl) GetDatasource( func (dc *CacheServiceImpl) GetDatasourceByUID( ctx context.Context, datasourceUID string, - user identity.Requester, + user *user.SignedInUser, skipCache bool, ) (*datasources.DataSource, error) { if datasourceUID == "" { return nil, fmt.Errorf("can not get data source by uid, uid is empty") } - if user.GetOrgID() == 0 { + if user.OrgID == 0 { return nil, fmt.Errorf("can not get data source by uid, orgId is missing") } - uidCacheKey := uidKey(user.GetOrgID(), datasourceUID) + uidCacheKey := uidKey(user.OrgID, datasourceUID) if !skipCache { if cached, found := dc.CacheService.Get(uidCacheKey); found { ds := cached.(*datasources.DataSource) - if ds.OrgID == user.GetOrgID() { + if ds.OrgID == user.OrgID { if err := dc.canQuery(user, ds); err != nil { return nil, err } @@ -102,8 +102,8 @@ func (dc *CacheServiceImpl) GetDatasourceByUID( } } - dc.logger.FromContext(ctx).Debug("Querying for data source via SQL store", "uid", datasourceUID, "orgId", user.GetOrgID()) - query := &datasources.GetDataSourceQuery{UID: datasourceUID, OrgID: user.GetOrgID()} + dc.logger.FromContext(ctx).Debug("Querying for data source via SQL store", "uid", datasourceUID, "orgId", user.OrgID) + query := &datasources.GetDataSourceQuery{UID: datasourceUID, OrgID: user.OrgID} ss := SqlStore{db: dc.SQLStore, logger: dc.logger} ds, err := ss.GetDataSource(ctx, query) if err != nil { @@ -128,8 +128,8 @@ func uidKey(orgID int64, uid string) string { return fmt.Sprintf("ds-orgid-uid-%d-%s", orgID, uid) } -func (dc *CacheServiceImpl) canQuery(user identity.Requester, ds *datasources.DataSource) error { - guardian := dc.dsGuardian.New(user.GetOrgID(), user, *ds) +func (dc *CacheServiceImpl) canQuery(user *user.SignedInUser, ds *datasources.DataSource) error { + guardian := dc.dsGuardian.New(user.OrgID, user, *ds) if canQuery, err := guardian.CanQuery(ds.ID); err != nil || !canQuery { if err != nil { return err diff --git a/pkg/services/folder/folderimpl/folder.go b/pkg/services/folder/folderimpl/folder.go index d8cd2f280ba..98193ab0d9f 100644 --- a/pkg/services/folder/folderimpl/folder.go +++ b/pkg/services/folder/folderimpl/folder.go @@ -12,7 +12,6 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" @@ -281,12 +280,7 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) ( dashFolder.SetUID(trimmedUID) user := cmd.SignedInUser - namespaceID, userIDstr := user.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) - } - + userID := user.UserID if userID == 0 { userID = -1 } @@ -769,18 +763,12 @@ func (s *Service) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards } } - namespaceID, userIDstr := dto.User.GetNamespacedID() - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) - } - cmd := &dashboards.SaveDashboardCommand{ Dashboard: dash.Data, Message: dto.Message, OrgID: dto.OrgID, Overwrite: dto.Overwrite, - UserID: userID, + UserID: dto.User.UserID, FolderID: dash.FolderID, IsFolder: dash.IsFolder, PluginID: dash.PluginID, @@ -795,7 +783,7 @@ func (s *Service) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards // getGuardianForSavePermissionCheck returns the guardian to be used for checking permission of dashboard // It replaces deleted Dashboard.GetDashboardIdForSavePermissionCheck() -func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user identity.Requester) (guardian.DashboardGuardian, error) { +func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user *user.SignedInUser) (guardian.DashboardGuardian, error) { newDashboard := d.ID == 0 if newDashboard { diff --git a/pkg/services/folder/model.go b/pkg/services/folder/model.go index 630a5ae5f97..cc157c3d05a 100644 --- a/pkg/services/folder/model.go +++ b/pkg/services/folder/model.go @@ -5,7 +5,6 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/slugify" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util/errutil" @@ -139,7 +138,6 @@ type GetFolderQuery struct { OrgID int64 SignedInUser *user.SignedInUser `json:"-"` - Requester identity.Requester `json:"-"` } // GetParentsQuery captures the information required by the folder service to diff --git a/pkg/services/guardian/accesscontrol_guardian.go b/pkg/services/guardian/accesscontrol_guardian.go index 0378d0d12b6..b63371abddf 100644 --- a/pkg/services/guardian/accesscontrol_guardian.go +++ b/pkg/services/guardian/accesscontrol_guardian.go @@ -6,9 +6,9 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/folder" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -16,14 +16,14 @@ var _ DashboardGuardian = new(accessControlDashboardGuardian) // NewAccessControlDashboardGuardianByDashboard creates a dashboard guardian by the provided dashboardId. func NewAccessControlDashboardGuardian( - ctx context.Context, cfg *setting.Cfg, dashboardId int64, user identity.Requester, + ctx context.Context, cfg *setting.Cfg, dashboardId int64, user *user.SignedInUser, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, ) (DashboardGuardian, error) { var dashboard *dashboards.Dashboard if dashboardId != 0 { q := &dashboards.GetDashboardQuery{ ID: dashboardId, - OrgID: user.GetOrgID(), + OrgID: user.OrgID, } qResult, err := dashboardService.GetDashboard(ctx, q) @@ -65,14 +65,14 @@ func NewAccessControlDashboardGuardian( // NewAccessControlDashboardGuardianByDashboard creates a dashboard guardian by the provided dashboardUID. func NewAccessControlDashboardGuardianByUID( - ctx context.Context, cfg *setting.Cfg, dashboardUID string, user identity.Requester, + ctx context.Context, cfg *setting.Cfg, dashboardUID string, user *user.SignedInUser, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, ) (DashboardGuardian, error) { var dashboard *dashboards.Dashboard if dashboardUID != "" { q := &dashboards.GetDashboardQuery{ UID: dashboardUID, - OrgID: user.GetOrgID(), + OrgID: user.OrgID, } qResult, err := dashboardService.GetDashboard(ctx, q) @@ -116,7 +116,7 @@ func NewAccessControlDashboardGuardianByUID( // This constructor should be preferred over the other two if the dashboard in available // since it avoids querying the database for fetching the dashboard. func NewAccessControlDashboardGuardianByDashboard( - ctx context.Context, cfg *setting.Cfg, dashboard *dashboards.Dashboard, user identity.Requester, + ctx context.Context, cfg *setting.Cfg, dashboard *dashboards.Dashboard, user *user.SignedInUser, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, ) (DashboardGuardian, error) { if dashboard != nil && dashboard.IsFolder { @@ -148,7 +148,7 @@ func NewAccessControlDashboardGuardianByDashboard( // NewAccessControlFolderGuardian creates a folder guardian by the provided folder. func NewAccessControlFolderGuardian( - ctx context.Context, cfg *setting.Cfg, f *folder.Folder, user identity.Requester, + ctx context.Context, cfg *setting.Cfg, f *folder.Folder, user *user.SignedInUser, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, ) (DashboardGuardian, error) { return &accessControlFolderGuardian{ @@ -168,7 +168,7 @@ type accessControlBaseGuardian struct { cfg *setting.Cfg ctx context.Context log log.Logger - user identity.Requester + user *user.SignedInUser ac accesscontrol.AccessControl dashboardService dashboards.DashboardService } @@ -309,13 +309,12 @@ func (a *accessControlFolderGuardian) CanCreate(folderID int64, isFolder bool) ( func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) { ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator) - namespaceID, userID := a.user.GetNamespacedID() if err != nil { id := 0 if a.dashboard != nil { id = int(a.dashboard.ID) } - a.log.Debug("Failed to evaluate access control to dashboard", "error", err, "namespaceID", namespaceID, "userId", userID, "id", id) + a.log.Debug("Failed to evaluate access control to dashboard", "error", err, "userId", a.user.UserID, "id", id) } if !ok && err == nil { @@ -323,7 +322,7 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua if a.dashboard != nil { id = int(a.dashboard.ID) } - a.log.Debug("Access denied to dashboard", "namespaceID", namespaceID, "userId", userID, "id", id, "permissions", evaluator.GoString()) + a.log.Debug("Access denied to dashboard", "userId", a.user.UserID, "id", id, "permissions", evaluator.GoString()) } return ok, err @@ -331,7 +330,6 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) { ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator) - namespaceID, userID := a.user.GetNamespacedID() if err != nil { uid := "" orgID := 0 @@ -339,7 +337,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator uid = a.folder.UID orgID = int(a.folder.OrgID) } - a.log.Debug("Failed to evaluate access control to folder", "error", err, "namespaceID", namespaceID, "userId", userID, "orgID", orgID, "uid", uid) + a.log.Debug("Failed to evaluate access control to folder", "error", err, "userId", a.user.UserID, "orgID", orgID, "uid", uid) } if !ok && err == nil { @@ -349,7 +347,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator uid = a.folder.UID orgID = int(a.folder.OrgID) } - a.log.Debug("Access denied to folder", "namespaceID", namespaceID, "userId", userID, "orgID", orgID, "uid", uid, "permissions", evaluator.GoString()) + a.log.Debug("Access denied to folder", "userId", a.user.UserID, "orgID", orgID, "uid", uid, "permissions", evaluator.GoString()) } return ok, err @@ -359,7 +357,7 @@ func (a *accessControlDashboardGuardian) loadParentFolder(folderID int64) (*dash if folderID == 0 { return &dashboards.Dashboard{UID: accesscontrol.GeneralFolderUID}, nil } - folderQuery := &dashboards.GetDashboardQuery{ID: folderID, OrgID: a.user.GetOrgID()} + folderQuery := &dashboards.GetDashboardQuery{ID: folderID, OrgID: a.user.OrgID} folderQueryResult, err := a.dashboardService.GetDashboard(a.ctx, folderQuery) if err != nil { return nil, err @@ -371,7 +369,7 @@ func (a *accessControlFolderGuardian) loadParentFolder(folderID int64) (*dashboa if folderID == 0 { return &dashboards.Dashboard{UID: accesscontrol.GeneralFolderUID}, nil } - folderQuery := &dashboards.GetDashboardQuery{ID: folderID, OrgID: a.user.GetOrgID()} + folderQuery := &dashboards.GetDashboardQuery{ID: folderID, OrgID: a.user.OrgID} folderQueryResult, err := a.dashboardService.GetDashboard(a.ctx, folderQuery) if err != nil { return nil, err diff --git a/pkg/services/guardian/guardian.go b/pkg/services/guardian/guardian.go index 827ff85c2dc..385646acacb 100644 --- a/pkg/services/guardian/guardian.go +++ b/pkg/services/guardian/guardian.go @@ -6,11 +6,11 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/team" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util/errutil" ) @@ -35,7 +35,7 @@ type DashboardGuardian interface { type dashboardGuardianImpl struct { cfg *setting.Cfg - user identity.Requester + user *user.SignedInUser dashId int64 orgId int64 acl []*dashboards.DashboardACLInfoDTO @@ -49,30 +49,30 @@ 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 identity.Requester) (DashboardGuardian, error) { +var New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { panic("no guardian factory implementation provided") } // NewByUID factory for creating a new dashboard guardian instance // When using access control this function is replaced on startup and the AccessControlDashboardGuardian is returned -var NewByUID = func(ctx context.Context, dashUID string, orgId int64, user identity.Requester) (DashboardGuardian, error) { +var NewByUID = func(ctx context.Context, dashUID string, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { panic("no guardian factory implementation provided") } // NewByDashboard factory for creating a new dashboard guardian instance // When using access control this function is replaced on startup and the AccessControlDashboardGuardian is returned -var NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user identity.Requester) (DashboardGuardian, error) { +var NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { panic("no guardian factory implementation provided") } // NewByFolder factory for creating a new folder guardian instance // When using access control this function is replaced on startup and the AccessControlDashboardGuardian is returned -var NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user identity.Requester) (DashboardGuardian, error) { +var NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { panic("no guardian factory implementation provided") } // newDashboardGuardian creates a dashboard guardian by the provided dashId. -func newDashboardGuardian(ctx context.Context, cfg *setting.Cfg, dashId int64, orgId int64, user identity.Requester, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { +func newDashboardGuardian(ctx context.Context, cfg *setting.Cfg, dashId int64, orgId int64, user *user.SignedInUser, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { if dashId != 0 { q := &dashboards.GetDashboardQuery{ ID: dashId, @@ -101,7 +101,7 @@ func newDashboardGuardian(ctx context.Context, cfg *setting.Cfg, dashId int64, o } // newDashboardGuardianByUID creates a dashboard guardian by the provided dashUID. -func newDashboardGuardianByUID(ctx context.Context, cfg *setting.Cfg, dashUID string, orgId int64, user identity.Requester, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { +func newDashboardGuardianByUID(ctx context.Context, cfg *setting.Cfg, dashUID string, orgId int64, user *user.SignedInUser, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { dashID := int64(0) if dashUID != "" { q := &dashboards.GetDashboardQuery{ @@ -135,7 +135,7 @@ func newDashboardGuardianByUID(ctx context.Context, cfg *setting.Cfg, dashUID st // newDashboardGuardianByDashboard creates a dashboard guardian by the provided dashboard. // This constructor should be preferred over the other two if the dashboard in available // since it avoids querying the database for fetching the dashboard. -func newDashboardGuardianByDashboard(ctx context.Context, cfg *setting.Cfg, dash *dashboards.Dashboard, orgId int64, user identity.Requester, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { +func newDashboardGuardianByDashboard(ctx context.Context, cfg *setting.Cfg, dash *dashboards.Dashboard, orgId int64, user *user.SignedInUser, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { return &dashboardGuardianImpl{ cfg: cfg, user: user, @@ -153,7 +153,7 @@ func newDashboardGuardianByDashboard(ctx context.Context, cfg *setting.Cfg, dash // This constructor should be preferred over the other two if the dashboard in available // since it avoids querying the database for fetching the dashboard. // The folder.ID should be the sequence ID in the dashboard table. -func newDashboardGuardianByFolder(ctx context.Context, cfg *setting.Cfg, f *folder.Folder, orgId int64, user identity.Requester, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { +func newDashboardGuardianByFolder(ctx context.Context, cfg *setting.Cfg, f *folder.Folder, orgId int64, user *user.SignedInUser, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) (*dashboardGuardianImpl, error) { return &dashboardGuardianImpl{ cfg: cfg, user: user, @@ -198,7 +198,7 @@ func (g *dashboardGuardianImpl) CanCreate(_ int64, _ bool) (bool, error) { } func (g *dashboardGuardianImpl) HasPermission(permission dashboards.PermissionType) (bool, error) { - if g.user.HasRole(org.RoleAdmin) { + if g.user.OrgRole == org.RoleAdmin { return g.logHasPermissionResult(permission, true, nil) } @@ -216,36 +216,32 @@ func (g *dashboardGuardianImpl) logHasPermissionResult(permission dashboards.Per return hasPermission, err } - var debugMessage string if hasPermission { - debugMessage = "User granted access to execute action" + g.log.Debug("User granted access to execute action", "userId", g.user.UserID, "orgId", g.orgId, "uname", g.user.Login, "dashId", g.dashId, "action", permission) } else { - debugMessage = "User denied access to execute action" + g.log.Debug("User denied access to execute action", "userId", g.user.UserID, "orgId", g.orgId, "uname", g.user.Login, "dashId", g.dashId, "action", permission) } - namespaceID, identifier := g.user.GetNamespacedID() - g.log.Debug(debugMessage, "namespaceID", namespaceID, "identifier", identifier, "orgId", g.orgId, "uname", g.user.GetLogin(), "dashId", g.dashId, "action", permission) - return hasPermission, err } func (g *dashboardGuardianImpl) checkACL(permission dashboards.PermissionType, acl []*dashboards.DashboardACLInfoDTO) (bool, error) { + orgRole := g.user.OrgRole teamACLItems := []*dashboards.DashboardACLInfoDTO{} for _, p := range acl { - userID, err := identity.IntIdentifier(g.user.GetNamespacedID()) - if err != nil { - return false, err - } - // user match - if p.UserID > 0 && p.UserID == userID && p.Permission >= permission { - return true, nil + if !g.user.IsAnonymous && p.UserID > 0 { + if p.UserID == g.user.UserID && p.Permission >= permission { + return true, nil + } } // role match - if p.Role != nil && *p.Role == g.user.GetOrgRole() && p.Permission >= permission { - return true, nil + if p.Role != nil { + if *p.Role == orgRole && p.Permission >= permission { + return true, nil + } } // remember this rule for later @@ -316,7 +312,7 @@ func (g *dashboardGuardianImpl) CheckPermissionBeforeUpdate(permission dashboard } } - if g.user.HasRole(org.RoleAdmin) { + if g.user.OrgRole == org.RoleAdmin { return true, nil } @@ -379,12 +375,7 @@ func (g *dashboardGuardianImpl) getTeams() ([]*team.TeamDTO, error) { return g.teams, nil } - userIdD, err := identity.IntIdentifier(g.user.GetNamespacedID()) - if err != nil { - return nil, err - } - - query := team.GetTeamsByUserQuery{OrgID: g.orgId, UserID: userIdD, SignedInUser: g.user} + query := team.GetTeamsByUserQuery{OrgID: g.orgId, UserID: g.user.UserID, SignedInUser: g.user} queryResult, err := g.teamService.GetTeamsByUser(g.ctx, &query) g.teams = queryResult @@ -393,7 +384,7 @@ func (g *dashboardGuardianImpl) getTeams() ([]*team.TeamDTO, error) { func (g *dashboardGuardianImpl) GetHiddenACL(cfg *setting.Cfg) ([]*dashboards.DashboardACL, error) { hiddenACL := make([]*dashboards.DashboardACL, 0) - if g.user.GetIsGrafanaAdmin() { + if g.user.IsGrafanaAdmin { return hiddenACL, nil } @@ -403,7 +394,7 @@ func (g *dashboardGuardianImpl) GetHiddenACL(cfg *setting.Cfg) ([]*dashboards.Da } for _, item := range existingPermissions { - if item.Inherited || item.UserLogin == g.user.GetLogin() { + if item.Inherited || item.UserLogin == g.user.Login { continue } @@ -425,11 +416,10 @@ func (g *dashboardGuardianImpl) GetHiddenACL(cfg *setting.Cfg) ([]*dashboards.Da // nolint:unused type FakeDashboardGuardian struct { - DashID int64 - DashUID string - // OrgID can be retrieved from the identity.Requester.GetOrgID + DashID int64 + DashUID string OrgID int64 - User identity.Requester + User *user.SignedInUser CanSaveValue bool CanEditValue bool CanViewValue bool @@ -471,21 +461,21 @@ func (g *FakeDashboardGuardian) HasPermission(permission dashboards.PermissionTy // nolint:unused func MockDashboardGuardian(mock *FakeDashboardGuardian) { - New = func(_ context.Context, dashID int64, orgId int64, user identity.Requester) (DashboardGuardian, error) { + New = func(_ context.Context, dashID int64, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { mock.OrgID = orgId mock.DashID = dashID mock.User = user return mock, nil } - NewByUID = func(_ context.Context, dashUID string, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByUID = func(_ context.Context, dashUID string, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { mock.OrgID = orgId mock.DashUID = dashUID mock.User = user return mock, nil } - NewByDashboard = func(_ context.Context, dash *dashboards.Dashboard, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByDashboard = func(_ context.Context, dash *dashboards.Dashboard, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { mock.OrgID = orgId mock.DashUID = dash.UID mock.DashID = dash.ID @@ -493,7 +483,7 @@ func MockDashboardGuardian(mock *FakeDashboardGuardian) { return mock, nil } - NewByFolder = func(_ context.Context, f *folder.Folder, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByFolder = func(_ context.Context, f *folder.Folder, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { mock.OrgID = orgId mock.DashUID = f.UID mock.DashID = f.ID diff --git a/pkg/services/guardian/provider.go b/pkg/services/guardian/provider.go index 78f478a14dd..74fd674acc0 100644 --- a/pkg/services/guardian/provider.go +++ b/pkg/services/guardian/provider.go @@ -5,10 +5,10 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/services/accesscontrol" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/team" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -28,19 +28,19 @@ func ProvideService( } func InitLegacyGuardian(cfg *setting.Cfg, store db.DB, dashSvc dashboards.DashboardService, teamSvc team.Service) { - New = func(ctx context.Context, dashId int64, orgId int64, user identity.Requester) (DashboardGuardian, error) { + New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return newDashboardGuardian(ctx, cfg, dashId, orgId, user, store, dashSvc, teamSvc) } - NewByUID = func(ctx context.Context, dashUID string, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByUID = func(ctx context.Context, dashUID string, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return newDashboardGuardianByUID(ctx, cfg, dashUID, orgId, user, store, dashSvc, teamSvc) } - NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return newDashboardGuardianByDashboard(ctx, cfg, dash, orgId, user, store, dashSvc, teamSvc) } - NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return newDashboardGuardianByFolder(ctx, cfg, f, orgId, user, store, dashSvc, teamSvc) } } @@ -48,19 +48,19 @@ func InitLegacyGuardian(cfg *setting.Cfg, store db.DB, dashSvc dashboards.Dashbo func InitAccessControlGuardian( cfg *setting.Cfg, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, ) { - New = func(ctx context.Context, dashId int64, orgId int64, user identity.Requester) (DashboardGuardian, error) { + New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return NewAccessControlDashboardGuardian(ctx, cfg, dashId, user, ac, dashboardService) } - NewByUID = func(ctx context.Context, dashUID string, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByUID = func(ctx context.Context, dashUID string, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return NewAccessControlDashboardGuardianByUID(ctx, cfg, dashUID, user, ac, dashboardService) } - NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByDashboard = func(ctx context.Context, dash *dashboards.Dashboard, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return NewAccessControlDashboardGuardianByDashboard(ctx, cfg, dash, user, ac, dashboardService) } - NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user identity.Requester) (DashboardGuardian, error) { + NewByFolder = func(ctx context.Context, f *folder.Folder, orgId int64, user *user.SignedInUser) (DashboardGuardian, error) { return NewAccessControlFolderGuardian(ctx, cfg, f, user, ac, dashboardService) } } diff --git a/pkg/services/live/features/broadcast.go b/pkg/services/live/features/broadcast.go index 51cdd46e2a4..e85741056e2 100644 --- a/pkg/services/live/features/broadcast.go +++ b/pkg/services/live/features/broadcast.go @@ -6,8 +6,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/live/model" + "github.com/grafana/grafana/pkg/services/user" ) var ( @@ -37,13 +37,13 @@ func (b *BroadcastRunner) GetHandlerForPath(_ string) (model.ChannelHandler, err } // OnSubscribe will let anyone connect to the path -func (b *BroadcastRunner) OnSubscribe(_ context.Context, u identity.Requester, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *user.SignedInUser, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { reply := model.SubscribeReply{ Presence: true, JoinLeave: true, } query := &model.GetLiveMessageQuery{ - OrgID: u.GetOrgID(), + OrgID: u.OrgID, Channel: e.Channel, } msg, ok, err := b.liveMessageStore.GetLiveMessage(query) @@ -57,9 +57,9 @@ func (b *BroadcastRunner) OnSubscribe(_ context.Context, u identity.Requester, e } // OnPublish is called when a client wants to broadcast on the websocket -func (b *BroadcastRunner) OnPublish(_ context.Context, u identity.Requester, e model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { +func (b *BroadcastRunner) OnPublish(_ context.Context, u *user.SignedInUser, e model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { query := &model.SaveLiveMessageQuery{ - OrgID: u.GetOrgID(), + OrgID: u.OrgID, Channel: e.Channel, Data: e.Data, } diff --git a/pkg/services/live/features/dashboard.go b/pkg/services/live/features/dashboard.go index 0c9ff3915bf..d98b4ddf73d 100644 --- a/pkg/services/live/features/dashboard.go +++ b/pkg/services/live/features/dashboard.go @@ -9,7 +9,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/live/model" @@ -53,7 +52,7 @@ func (h *DashboardHandler) GetHandlerForPath(_ string) (model.ChannelHandler, er } // OnSubscribe for now allows anyone to subscribe to any dashboard -func (h *DashboardHandler) OnSubscribe(ctx context.Context, user identity.Requester, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *user.SignedInUser, e model.SubscribeEvent) (model.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 @@ -67,7 +66,7 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user identity.Reques // make sure can view this dashboard if len(parts) == 2 && parts[0] == "uid" { - query := dashboards.GetDashboardQuery{UID: parts[1], OrgID: user.GetOrgID()} + query := dashboards.GetDashboardQuery{UID: parts[1], OrgID: user.OrgID} queryResult, err := h.DashboardService.GetDashboard(ctx, &query) if err != nil { logger.Error("Error getting dashboard", "query", query, "error", err) @@ -75,7 +74,7 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user identity.Reques } dash := queryResult - guard, err := guardian.NewByDashboard(ctx, dash, user.GetOrgID(), user) + guard, err := guardian.NewByDashboard(ctx, dash, user.OrgID, user) if err != nil { return model.SubscribeReply{}, backend.SubscribeStreamStatusPermissionDenied, err } @@ -95,11 +94,11 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user identity.Reques } // OnPublish is called when someone begins to edit a dashboard -func (h *DashboardHandler) OnPublish(ctx context.Context, requester identity.Requester, e model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { +func (h *DashboardHandler) OnPublish(ctx context.Context, user *user.SignedInUser, e model.PublishEvent) (model.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 !requester.HasRole(org.RoleAdmin) { + if !user.HasRole(org.RoleAdmin) { return model.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil } @@ -118,14 +117,14 @@ func (h *DashboardHandler) OnPublish(ctx context.Context, requester identity.Req // just ignore the event return model.PublishReply{}, backend.PublishStreamStatusNotFound, fmt.Errorf("ignore???") } - query := dashboards.GetDashboardQuery{UID: parts[1], OrgID: requester.GetOrgID()} + query := dashboards.GetDashboardQuery{UID: parts[1], OrgID: user.OrgID} queryResult, err := h.DashboardService.GetDashboard(ctx, &query) if err != nil { logger.Error("Unknown dashboard", "query", query) return model.PublishReply{}, backend.PublishStreamStatusNotFound, nil } - guard, err := guardian.NewByDashboard(ctx, queryResult, requester.GetOrgID(), requester) + guard, err := guardian.NewByDashboard(ctx, queryResult, user.OrgID, user) if err != nil { logger.Error("Failed to create guardian", "err", err) return model.PublishReply{}, backend.PublishStreamStatusNotFound, fmt.Errorf("internal error") @@ -142,10 +141,7 @@ func (h *DashboardHandler) OnPublish(ctx context.Context, requester identity.Req } // Tell everyone who is editing - event.User, err = user.NewUserDisplayDTOFromRequester(requester) - if err != nil { - return model.PublishReply{}, backend.PublishStreamStatusNotFound, err - } + event.User = user.ToUserDisplayDTO() msg, err := json.Marshal(event) if err != nil { diff --git a/pkg/services/live/features/plugin.go b/pkg/services/live/features/plugin.go index 373f6eaf51d..aa8ad33249d 100644 --- a/pkg/services/live/features/plugin.go +++ b/pkg/services/live/features/plugin.go @@ -7,17 +7,17 @@ import ( "github.com/centrifugal/centrifuge" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/live/model" "github.com/grafana/grafana/pkg/services/live/orgchannel" "github.com/grafana/grafana/pkg/services/live/runstream" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/user" ) //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 identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) + GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) } // PluginRunner can handle streaming operations for channels belonging to plugins. @@ -63,7 +63,7 @@ type PluginPathRunner struct { } // OnSubscribe passes control to a plugin. -func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user identity.Requester, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *user.SignedInUser, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { pCtx, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false) if err != nil { if errors.Is(err, plugincontext.ErrPluginNotFound) { @@ -86,7 +86,7 @@ func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user identity.Reques return model.SubscribeReply{}, resp.Status, nil } - submitResult, err := r.runStreamManager.SubmitStream(ctx, user, orgchannel.PrependOrgID(user.GetOrgID(), e.Channel), r.path, e.Data, pCtx, r.handler, false) + submitResult, err := r.runStreamManager.SubmitStream(ctx, user, orgchannel.PrependOrgID(user.OrgID, e.Channel), r.path, e.Data, pCtx, r.handler, false) if err != nil { logger.Error("Error submitting stream to manager", "error", err, "path", r.path) return model.SubscribeReply{}, 0, centrifuge.ErrorInternal @@ -107,7 +107,7 @@ func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user identity.Reques } // OnPublish passes control to a plugin. -func (r *PluginPathRunner) OnPublish(ctx context.Context, user identity.Requester, e model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { +func (r *PluginPathRunner) OnPublish(ctx context.Context, user *user.SignedInUser, e model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { pCtx, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false) if err != nil { if errors.Is(err, plugincontext.ErrPluginNotFound) { diff --git a/pkg/services/live/features/plugin_mock.go b/pkg/services/live/features/plugin_mock.go index 53ec2baa529..969dbb7a469 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" - identity "github.com/grafana/grafana/pkg/services/auth/identity" + user "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(arg0 context.Context, arg1 identity.Requester, arg2, arg3 string, arg4 bool) (backend.PluginContext, error) { +func (m *MockPluginContextGetter) GetPluginContext(arg0 context.Context, arg1 *user.SignedInUser, arg2, arg3 string, arg4 bool) (backend.PluginContext, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPluginContext", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(backend.PluginContext) diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index 4b3841999ee..f035acfca8a 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -32,7 +32,6 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/annotations" - "github.com/grafana/grafana/pkg/services/auth/identity" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" @@ -300,11 +299,10 @@ func ProvideService(plugCtxProvider *plugincontext.Provider, cfg *setting.Cfg, r g.websocketHandler = func(ctx *contextmodel.ReqContext) { user := ctx.SignedInUser - _, userID := user.GetNamespacedID() // Centrifuge expects Credentials in context with a current user ID. cred := ¢rifuge.Credentials{ - UserID: userID, + UserID: fmt.Sprintf("%d", user.UserID), } newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred) newCtx = livecontext.SetContextSignedUser(newCtx, user) @@ -595,7 +593,7 @@ func (g *GrafanaLive) handleOnSubscribe(ctx context.Context, client *centrifuge. return centrifuge.SubscribeReply{}, centrifuge.ErrorInternal } - if user.GetOrgID() != orgID { + if user.OrgID != orgID { logger.Info("Error subscribing: wrong orgId", "user", client.UserID(), "client", client.ID(), "channel", e.Channel) return centrifuge.SubscribeReply{}, centrifuge.ErrorPermissionDenied } @@ -605,7 +603,7 @@ func (g *GrafanaLive) handleOnSubscribe(ctx context.Context, client *centrifuge. var ruleFound bool if g.Pipeline != nil { - rule, ok, err := g.Pipeline.Get(user.GetOrgID(), channel) + rule, ok, err := g.Pipeline.Get(user.OrgID, channel) if err != nil { logger.Error("Error getting channel rule", "user", client.UserID(), "client", client.ID(), "channel", e.Channel, "error", err) return centrifuge.SubscribeReply{}, centrifuge.ErrorInternal @@ -696,13 +694,13 @@ func (g *GrafanaLive) handleOnPublish(ctx context.Context, client *centrifuge.Cl return centrifuge.PublishReply{}, centrifuge.ErrorInternal } - if user.GetOrgID() != orgID { + if user.OrgID != orgID { logger.Info("Error subscribing: wrong orgId", "user", client.UserID(), "client", client.ID(), "channel", e.Channel) return centrifuge.PublishReply{}, centrifuge.ErrorPermissionDenied } if g.Pipeline != nil { - rule, ok, err := g.Pipeline.Get(user.GetOrgID(), channel) + rule, ok, err := g.Pipeline.Get(user.OrgID, channel) if err != nil { logger.Error("Error getting channel rule", "user", client.UserID(), "client", client.ID(), "channel", e.Channel, "error", err) return centrifuge.PublishReply{}, centrifuge.ErrorInternal @@ -726,7 +724,7 @@ func (g *GrafanaLive) handleOnPublish(ctx context.Context, client *centrifuge.Cl return centrifuge.PublishReply{}, ¢rifuge.Error{Code: uint32(code), Message: text} } } - _, err := g.Pipeline.ProcessInput(client.Context(), user.GetOrgID(), channel, e.Data) + _, err := g.Pipeline.ProcessInput(client.Context(), user.OrgID, channel, e.Data) if err != nil { logger.Error("Error processing input", "user", client.UserID(), "client", client.ID(), "channel", e.Channel, "error", err) return centrifuge.PublishReply{}, centrifuge.ErrorInternal @@ -807,7 +805,7 @@ func publishStatusToHTTPError(status backend.PublishStreamStatus) (int, string) } // GetChannelHandler gives thread-safe access to the channel. -func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user identity.Requester, channel string) (model.ChannelHandler, live.Channel, error) { +func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (model.ChannelHandler, live.Channel, error) { // Parse the identifier ${scope}/${namespace}/${path} addr, err := live.ParseChannel(channel) if err != nil { @@ -848,7 +846,7 @@ func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user identity.Reque // GetChannelHandlerFactory gets a ChannelHandlerFactory for a namespace. // It gives thread-safe access to the channel. -func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user identity.Requester, scope string, namespace string) (model.ChannelHandlerFactory, error) { +func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *user.SignedInUser, scope string, namespace string) (model.ChannelHandlerFactory, error) { switch scope { case live.ScopeGrafana: return g.handleGrafanaScope(user, namespace) @@ -863,14 +861,14 @@ func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user identit } } -func (g *GrafanaLive) handleGrafanaScope(_ identity.Requester, namespace string) (model.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handleGrafanaScope(_ *user.SignedInUser, namespace string) (model.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, _ identity.Requester, namespace string) (model.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *user.SignedInUser, namespace string) (model.ChannelHandlerFactory, error) { streamHandler, err := g.getStreamPlugin(ctx, namespace) if err != nil { return nil, fmt.Errorf("can't find stream plugin: %s", namespace) @@ -884,11 +882,11 @@ func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ identity.Requeste ), nil } -func (g *GrafanaLive) handleStreamScope(u identity.Requester, namespace string) (model.ChannelHandlerFactory, error) { - return g.ManagedStreamRunner.GetOrCreateStream(u.GetOrgID(), live.ScopeStream, namespace) +func (g *GrafanaLive) handleStreamScope(u *user.SignedInUser, namespace string) (model.ChannelHandlerFactory, error) { + return g.ManagedStreamRunner.GetOrCreateStream(u.OrgID, live.ScopeStream, namespace) } -func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user identity.Requester, namespace string) (model.ChannelHandlerFactory, error) { +func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user *user.SignedInUser, namespace string) (model.ChannelHandlerFactory, error) { ds, err := g.DataSourceCache.GetDatasourceByUID(ctx, namespace, user, false) if err != nil { return nil, fmt.Errorf("error getting datasource: %w", err) @@ -931,13 +929,12 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *contextmodel.ReqContext) response.R return response.Error(http.StatusBadRequest, "invalid channel ID", nil) } - namespaceID, userID := ctx.SignedInUser.GetNamespacedID() - logger.Debug("Publish API cmd", "namespaceID", namespaceID, "userID", userID, "channel", cmd.Channel) + logger.Debug("Publish API cmd", "user", ctx.SignedInUser.UserID, "channel", cmd.Channel) user := ctx.SignedInUser channel := cmd.Channel if g.Pipeline != nil { - rule, ok, err := g.Pipeline.Get(user.GetOrgID(), channel) + rule, ok, err := g.Pipeline.Get(user.OrgID, channel) if err != nil { logger.Error("Error getting channel rule", "user", user, "channel", channel, "error", err) return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), nil) @@ -957,7 +954,7 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *contextmodel.ReqContext) response.R return response.Error(http.StatusForbidden, http.StatusText(http.StatusForbidden), nil) } } - _, err := g.Pipeline.ProcessInput(ctx.Req.Context(), user.GetOrgID(), channel, cmd.Data) + _, err := g.Pipeline.ProcessInput(ctx.Req.Context(), user.OrgID, channel, cmd.Data) if err != nil { logger.Error("Error processing input", "user", user, "channel", channel, "error", err) return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), nil) @@ -983,13 +980,13 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *contextmodel.ReqContext) response.R return response.Error(code, text, nil) } if reply.Data != nil { - err = g.Publish(ctx.SignedInUser.GetOrgID(), cmd.Channel, cmd.Data) + err = g.Publish(ctx.OrgID, cmd.Channel, cmd.Data) if err != nil { logger.Error("Error publish to channel", "error", err, "channel", cmd.Channel) return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), nil) } } - logger.Debug("Publication successful", "namespaceID", namespaceID, "userID", userID, "channel", cmd.Channel) + logger.Debug("Publication successful", "user", ctx.SignedInUser.UserID, "channel", cmd.Channel) return response.JSON(http.StatusOK, dtos.LivePublishResponse{}) } @@ -1002,9 +999,9 @@ func (g *GrafanaLive) HandleListHTTP(c *contextmodel.ReqContext) response.Respon var channels []*managedstream.ManagedChannel var err error if g.IsHA() { - channels, err = g.surveyCaller.CallManagedStreams(c.SignedInUser.GetOrgID()) + channels, err = g.surveyCaller.CallManagedStreams(c.SignedInUser.OrgID) } else { - channels, err = g.ManagedStreamRunner.GetManagedChannels(c.SignedInUser.GetOrgID()) + channels, err = g.ManagedStreamRunner.GetManagedChannels(c.SignedInUser.OrgID) } if err != nil { return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), err) @@ -1020,7 +1017,7 @@ func (g *GrafanaLive) HandleInfoHTTP(ctx *contextmodel.ReqContext) response.Resp path := web.Params(ctx.Req)["*"] if path == "grafana/dashboards/gitops" { return response.JSON(http.StatusOK, util.DynMap{ - "active": g.GrafanaScope.Dashboards.HasGitOpsObserver(ctx.SignedInUser.GetOrgID()), + "active": g.GrafanaScope.Dashboards.HasGitOpsObserver(ctx.SignedInUser.OrgID), }) } return response.JSONStreaming(404, util.DynMap{ @@ -1030,7 +1027,7 @@ func (g *GrafanaLive) HandleInfoHTTP(ctx *contextmodel.ReqContext) response.Resp // HandleChannelRulesListHTTP ... func (g *GrafanaLive) HandleChannelRulesListHTTP(c *contextmodel.ReqContext) response.Response { - result, err := g.pipelineStorage.ListChannelRules(c.Req.Context(), c.SignedInUser.GetOrgID()) + result, err := g.pipelineStorage.ListChannelRules(c.Req.Context(), c.OrgID) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to get channel rules", err) } @@ -1115,7 +1112,7 @@ func (g *GrafanaLive) HandlePipelineConvertTestHTTP(c *contextmodel.ReqContext) if err != nil { return response.Error(http.StatusInternalServerError, "Error creating pipeline", err) } - rule, ok, err := channelRuleGetter.Get(c.SignedInUser.GetOrgID(), req.Channel) + rule, ok, err := channelRuleGetter.Get(c.OrgID, req.Channel) if err != nil { return response.Error(http.StatusInternalServerError, "Error getting channel rule", err) } @@ -1125,7 +1122,7 @@ func (g *GrafanaLive) HandlePipelineConvertTestHTTP(c *contextmodel.ReqContext) if rule.Converter == nil { return response.Error(http.StatusNotFound, "No converter found", nil) } - channelFrames, err := pipe.DataToChannelFrames(c.Req.Context(), *rule, c.SignedInUser.GetOrgID(), req.Channel, []byte(req.Data)) + channelFrames, err := pipe.DataToChannelFrames(c.Req.Context(), *rule, c.OrgID, req.Channel, []byte(req.Data)) if err != nil { return response.Error(http.StatusInternalServerError, "Error converting data", err) } @@ -1145,7 +1142,7 @@ func (g *GrafanaLive) HandleChannelRulesPostHTTP(c *contextmodel.ReqContext) res if err != nil { return response.Error(http.StatusBadRequest, "Error decoding channel rule", err) } - rule, err := g.pipelineStorage.CreateChannelRule(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + rule, err := g.pipelineStorage.CreateChannelRule(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to create channel rule", err) } @@ -1168,7 +1165,7 @@ func (g *GrafanaLive) HandleChannelRulesPutHTTP(c *contextmodel.ReqContext) resp if cmd.Pattern == "" { return response.Error(http.StatusBadRequest, "Rule pattern required", nil) } - rule, err := g.pipelineStorage.UpdateChannelRule(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + rule, err := g.pipelineStorage.UpdateChannelRule(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to update channel rule", err) } @@ -1191,7 +1188,7 @@ func (g *GrafanaLive) HandleChannelRulesDeleteHTTP(c *contextmodel.ReqContext) r if cmd.Pattern == "" { return response.Error(http.StatusBadRequest, "Rule pattern required", nil) } - err = g.pipelineStorage.DeleteChannelRule(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + err = g.pipelineStorage.DeleteChannelRule(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to delete channel rule", err) } @@ -1211,7 +1208,7 @@ func (g *GrafanaLive) HandlePipelineEntitiesListHTTP(_ *contextmodel.ReqContext) // HandleWriteConfigsListHTTP ... func (g *GrafanaLive) HandleWriteConfigsListHTTP(c *contextmodel.ReqContext) response.Response { - backends, err := g.pipelineStorage.ListWriteConfigs(c.Req.Context(), c.SignedInUser.GetOrgID()) + backends, err := g.pipelineStorage.ListWriteConfigs(c.Req.Context(), c.OrgID) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to get write configs", err) } @@ -1235,7 +1232,7 @@ func (g *GrafanaLive) HandleWriteConfigsPostHTTP(c *contextmodel.ReqContext) res if err != nil { return response.Error(http.StatusBadRequest, "Error decoding write config create command", err) } - result, err := g.pipelineStorage.CreateWriteConfig(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + result, err := g.pipelineStorage.CreateWriteConfig(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to create write config", err) } @@ -1258,7 +1255,7 @@ func (g *GrafanaLive) HandleWriteConfigsPutHTTP(c *contextmodel.ReqContext) resp if cmd.UID == "" { return response.Error(http.StatusBadRequest, "UID required", nil) } - existingBackend, ok, err := g.pipelineStorage.GetWriteConfig(c.Req.Context(), c.SignedInUser.GetOrgID(), pipeline.WriteConfigGetCmd{ + existingBackend, ok, err := g.pipelineStorage.GetWriteConfig(c.Req.Context(), c.OrgID, pipeline.WriteConfigGetCmd{ UID: cmd.UID, }) if err != nil { @@ -1279,7 +1276,7 @@ func (g *GrafanaLive) HandleWriteConfigsPutHTTP(c *contextmodel.ReqContext) resp } } } - result, err := g.pipelineStorage.UpdateWriteConfig(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + result, err := g.pipelineStorage.UpdateWriteConfig(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to update write config", err) } @@ -1302,7 +1299,7 @@ func (g *GrafanaLive) HandleWriteConfigsDeleteHTTP(c *contextmodel.ReqContext) r if cmd.UID == "" { return response.Error(http.StatusBadRequest, "UID required", nil) } - err = g.pipelineStorage.DeleteWriteConfig(c.Req.Context(), c.SignedInUser.GetOrgID(), cmd) + err = g.pipelineStorage.DeleteWriteConfig(c.Req.Context(), c.OrgID, cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to delete write config", err) } diff --git a/pkg/services/live/livecontext/context.go b/pkg/services/live/livecontext/context.go index 0b4df1ef451..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/services/auth/identity" + "github.com/grafana/grafana/pkg/services/user" ) type signedUserContextKeyType int var signedUserContextKey signedUserContextKeyType -func SetContextSignedUser(ctx context.Context, user identity.Requester) 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) (identity.Requester, bool) { +func GetContextSignedUser(ctx context.Context) (*user.SignedInUser, bool) { if val := ctx.Value(signedUserContextKey); val != nil { - user, ok := val.(identity.Requester) + 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 17dc25ecaa7..8a9a9a35c99 100644 --- a/pkg/services/live/liveplugin/plugin.go +++ b/pkg/services/live/liveplugin/plugin.go @@ -7,11 +7,11 @@ import ( "github.com/centrifugal/centrifuge" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" "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/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/user" ) type ChannelLocalPublisher struct { @@ -72,9 +72,9 @@ func NewContextGetter(pluginContextProvider *plugincontext.Provider, dataSourceC } } -func (g *ContextGetter) GetPluginContext(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) { +func (g *ContextGetter) GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) { if datasourceUID == "" { - return g.pluginContextProvider.Get(ctx, pluginID, user, user.GetOrgID()) + return g.pluginContextProvider.Get(ctx, pluginID, user, user.OrgID) } ds, err := g.dataSourceCache.GetDatasourceByUID(ctx, datasourceUID, user, skipCache) diff --git a/pkg/services/live/managedstream/runner.go b/pkg/services/live/managedstream/runner.go index 393a261dd5e..b9fd21ad5e6 100644 --- a/pkg/services/live/managedstream/runner.go +++ b/pkg/services/live/managedstream/runner.go @@ -13,9 +13,9 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/live" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/live/model" "github.com/grafana/grafana/pkg/services/live/orgchannel" + "github.com/grafana/grafana/pkg/services/user" ) var ( @@ -239,9 +239,9 @@ func (s *NamespaceStream) GetHandlerForPath(_ string) (model.ChannelHandler, err return s, nil } -func (s *NamespaceStream) OnSubscribe(ctx context.Context, u identity.Requester, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { +func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *user.SignedInUser, e model.SubscribeEvent) (model.SubscribeReply, backend.SubscribeStreamStatus, error) { reply := model.SubscribeReply{} - frameJSON, ok, err := s.frameCache.GetFrame(ctx, u.GetOrgID(), e.Channel) + frameJSON, ok, err := s.frameCache.GetFrame(ctx, u.OrgID, e.Channel) if err != nil { return reply, 0, err } @@ -251,6 +251,6 @@ func (s *NamespaceStream) OnSubscribe(ctx context.Context, u identity.Requester, return reply, backend.SubscribeStreamStatusOK, nil } -func (s *NamespaceStream) OnPublish(_ context.Context, _ identity.Requester, _ model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { +func (s *NamespaceStream) OnPublish(_ context.Context, _ *user.SignedInUser, _ model.PublishEvent) (model.PublishReply, backend.PublishStreamStatus, error) { return model.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil } diff --git a/pkg/services/live/model/model.go b/pkg/services/live/model/model.go index b6b58733204..612650fae11 100644 --- a/pkg/services/live/model/model.go +++ b/pkg/services/live/model/model.go @@ -7,7 +7,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" + "github.com/grafana/grafana/pkg/services/user" ) // ChannelPublisher writes data into a channel. Note that permissions are not checked. @@ -54,10 +54,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 identity.Requester, 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 identity.Requester, 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. diff --git a/pkg/services/live/pipeline/auth.go b/pkg/services/live/pipeline/auth.go index 8d6e3efec6a..f24bdcff6aa 100644 --- a/pkg/services/live/pipeline/auth.go +++ b/pkg/services/live/pipeline/auth.go @@ -3,8 +3,8 @@ package pipeline import ( "context" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/services/user" ) type RoleCheckAuthorizer struct { @@ -15,10 +15,10 @@ func NewRoleCheckAuthorizer(role org.RoleType) *RoleCheckAuthorizer { return &RoleCheckAuthorizer{role: role} } -func (s *RoleCheckAuthorizer) CanSubscribe(_ context.Context, u identity.Requester) (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 identity.Requester) (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/pipeline.go b/pkg/services/live/pipeline/pipeline.go index 281f9fab345..2d4fb8ffcf2 100644 --- a/pkg/services/live/pipeline/pipeline.go +++ b/pkg/services/live/pipeline/pipeline.go @@ -17,8 +17,8 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "go.opentelemetry.io/otel/trace" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/live/model" + "github.com/grafana/grafana/pkg/services/user" ) const ( @@ -113,12 +113,12 @@ type Subscriber interface { // PublishAuthChecker checks whether current user can publish to a channel. type PublishAuthChecker interface { - CanPublish(ctx context.Context, u identity.Requester) (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 identity.Requester) (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. diff --git a/pkg/services/live/pipeline/subscribe_builtin.go b/pkg/services/live/pipeline/subscribe_builtin.go index f594f8d393d..14e35488ad4 100644 --- a/pkg/services/live/pipeline/subscribe_builtin.go +++ b/pkg/services/live/pipeline/subscribe_builtin.go @@ -6,9 +6,9 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/live" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/live/livecontext" "github.com/grafana/grafana/pkg/services/live/model" + "github.com/grafana/grafana/pkg/services/user" ) type BuiltinSubscriber struct { @@ -16,7 +16,7 @@ type BuiltinSubscriber struct { } type ChannelHandlerGetter interface { - GetChannelHandler(ctx context.Context, user identity.Requester, channel string) (model.ChannelHandler, live.Channel, error) + GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (model.ChannelHandler, live.Channel, error) } const SubscriberTypeBuiltin = "builtin" diff --git a/pkg/services/live/pushws/push_pipeline.go b/pkg/services/live/pushws/push_pipeline.go index 0005318bebd..c96251193c9 100644 --- a/pkg/services/live/pushws/push_pipeline.go +++ b/pkg/services/live/pushws/push_pipeline.go @@ -71,7 +71,7 @@ func (s *PipelinePushHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) "bodyLength", len(body), ) - ruleFound, err := s.pipeline.ProcessInput(r.Context(), user.GetOrgID(), channelID, body) + ruleFound, err := s.pipeline.ProcessInput(r.Context(), user.OrgID, channelID, body) if err != nil { logger.Error("Pipeline input processing error", "error", err, "body", string(body)) return diff --git a/pkg/services/live/pushws/push_stream.go b/pkg/services/live/pushws/push_stream.go index 12f6adf309d..2a9a42a781e 100644 --- a/pkg/services/live/pushws/push_stream.go +++ b/pkg/services/live/pushws/push_stream.go @@ -67,7 +67,7 @@ func (s *Handler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { break } - stream, err := s.managedStreamRunner.GetOrCreateStream(user.GetOrgID(), liveDto.ScopeStream, streamID) + stream, err := s.managedStreamRunner.GetOrCreateStream(user.OrgID, liveDto.ScopeStream, streamID) if err != nil { logger.Error("Error getting stream", "error", err) continue diff --git a/pkg/services/live/runstream/manager.go b/pkg/services/live/runstream/manager.go index 229e0601850..fc52e9ee1cb 100644 --- a/pkg/services/live/runstream/manager.go +++ b/pkg/services/live/runstream/manager.go @@ -11,8 +11,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/user" ) var ( @@ -26,7 +26,7 @@ type ChannelLocalPublisher interface { } type PluginContextGetter interface { - GetPluginContext(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) + GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) } type NumLocalSubscribersGetter interface { @@ -374,7 +374,7 @@ func (s *Manager) Run(ctx context.Context) error { type streamRequest struct { Channel string Path string - user identity.Requester + user *user.SignedInUser PluginContext backend.PluginContext StreamRunner StreamRunner Data []byte @@ -401,7 +401,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 identity.Requester, 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 e2459724ac1..2048dda7840 100644 --- a/pkg/services/live/runstream/manager_test.go +++ b/pkg/services/live/runstream/manager_test.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/user" ) @@ -72,11 +71,9 @@ 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 identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { - userID, err := identity.IntIdentifier(user.GetNamespacedID()) - require.NoError(t, err) - require.Equal(t, int64(2), userID) - require.Equal(t, int64(1), user.GetOrgID()) + 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) require.Equal(t, testPluginContext.DataSourceInstanceSettings.UID, datasourceUID) return testPluginContext, true, nil @@ -136,7 +133,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 identity.Requester, 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) @@ -208,7 +205,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 identity.Requester, 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) @@ -257,11 +254,9 @@ 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 identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { - userID, err := identity.IntIdentifier(user.GetNamespacedID()) - require.NoError(t, err) - require.Equal(t, int64(2), userID) - require.Equal(t, int64(1), user.GetOrgID()) + 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) require.Equal(t, testPluginContext.DataSourceInstanceSettings.UID, datasourceUID) return testPluginContext, true, nil @@ -301,7 +296,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 identity.Requester, 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) @@ -342,12 +337,9 @@ 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 identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { - userID, err := identity.IntIdentifier(user.GetNamespacedID()) - require.NoError(t, err) - - require.Equal(t, int64(2), userID) - require.Equal(t, int64(1), user.GetOrgID()) + 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) require.Equal(t, testPluginContext.DataSourceInstanceSettings.UID, datasourceUID) return testPluginContext, true, nil @@ -411,11 +403,9 @@ 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 identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) { - userID, err := identity.IntIdentifier(user.GetNamespacedID()) - require.NoError(t, err) - require.Equal(t, int64(2), userID) - require.Equal(t, int64(1), user.GetOrgID()) + 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) require.Equal(t, testPluginContext.DataSourceInstanceSettings.UID, datasourceUID) return testPluginContext, true, nil diff --git a/pkg/services/live/runstream/mock.go b/pkg/services/live/runstream/mock.go index a802d1c24d7..96978c317ec 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" - identity "github.com/grafana/grafana/pkg/services/auth/identity" + user "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(arg0 context.Context, arg1 identity.Requester, arg2, arg3 string, arg4 bool) (backend.PluginContext, error) { +func (m *MockPluginContextGetter) GetPluginContext(arg0 context.Context, arg1 *user.SignedInUser, arg2, arg3 string, arg4 bool) (backend.PluginContext, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPluginContext", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(backend.PluginContext) diff --git a/pkg/services/ngalert/api/lotex_ruler_test.go b/pkg/services/ngalert/api/lotex_ruler_test.go index 661377d68f3..1d3fc8e964c 100644 --- a/pkg/services/ngalert/api/lotex_ruler_test.go +++ b/pkg/services/ngalert/api/lotex_ruler_test.go @@ -9,10 +9,10 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/auth/identity" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "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" ) @@ -114,7 +114,7 @@ type fakeCacheService struct { err error } -func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ identity.Requester, _ 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 } @@ -122,7 +122,7 @@ func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ return f.datasource, nil } -func (f fakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, _ identity.Requester, 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/pluginsintegration/adapters/adapters.go b/pkg/services/pluginsintegration/adapters/adapters.go index fbe1b4acabf..9940d94fe7a 100644 --- a/pkg/services/pluginsintegration/adapters/adapters.go +++ b/pkg/services/pluginsintegration/adapters/adapters.go @@ -7,8 +7,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" ) // ModelToInstanceSettings converts a datasources.DataSource to a backend.DataSourceInstanceSettings. @@ -43,16 +43,16 @@ func ModelToInstanceSettings(ds *datasources.DataSource, decryptFn func(ds *data }, err } -// BackendUserFromSignedInUser converts Grafana's context request identity +// BackendUserFromSignedInUser converts Grafana's SignedInUser model // to the backend plugin's model. -func BackendUserFromSignedInUser(requester identity.Requester) *backend.User { - if requester == nil { +func BackendUserFromSignedInUser(su *user.SignedInUser) *backend.User { + if su == nil { return nil } return &backend.User{ - Login: requester.GetLogin(), - Name: requester.GetDisplayName(), - Email: requester.GetEmail(), - Role: string(requester.GetOrgRole()), + Login: su.Login, + Name: su.Name, + Email: su.Email, + Role: string(su.OrgRole), } } diff --git a/pkg/services/pluginsintegration/plugincontext/plugincontext.go b/pkg/services/pluginsintegration/plugincontext/plugincontext.go index 6039d03319a..34b9be7056c 100644 --- a/pkg/services/pluginsintegration/plugincontext/plugincontext.go +++ b/pkg/services/pluginsintegration/plugincontext/plugincontext.go @@ -11,10 +11,10 @@ import ( "github.com/grafana/grafana/pkg/infra/localcache" "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/pluginsintegration/adapters" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" + "github.com/grafana/grafana/pkg/services/user" ) var ErrPluginNotFound = errors.New("plugin not found") @@ -39,8 +39,8 @@ 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. -// Note: identity.Requester can be nil. -func (p *Provider) Get(ctx context.Context, pluginID string, user identity.Requester, orgID int64) (backend.PluginContext, error) { +// Note: *user.SignedInUser can be nil. +func (p *Provider) Get(ctx context.Context, pluginID string, user *user.SignedInUser, orgID int64) (backend.PluginContext, error) { plugin, exists := p.pluginStore.Plugin(ctx, pluginID) if !exists { return backend.PluginContext{}, ErrPluginNotFound @@ -50,7 +50,7 @@ func (p *Provider) Get(ctx context.Context, pluginID string, user identity.Reque PluginID: pluginID, } if user != nil { - pCtx.OrgID = user.GetOrgID() + pCtx.OrgID = user.OrgID pCtx.User = adapters.BackendUserFromSignedInUser(user) } @@ -68,7 +68,7 @@ func (p *Provider) Get(ctx context.Context, pluginID string, user identity.Reque // GetWithDataSource allows getting plugin context by its ID and PluginContext.DataSourceInstanceSettings will be // resolved and appended to the returned context. // Note: *user.SignedInUser can be nil. -func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) { +func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *user.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, error) { _, exists := p.pluginStore.Plugin(ctx, pluginID) if !exists { return backend.PluginContext{}, ErrPluginNotFound @@ -78,7 +78,7 @@ func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user PluginID: pluginID, } if user != nil { - pCtx.OrgID = user.GetOrgID() + pCtx.OrgID = user.OrgID pCtx.User = adapters.BackendUserFromSignedInUser(user) } diff --git a/pkg/services/query/query.go b/pkg/services/query/query.go index 05dbc029688..ba005572541 100644 --- a/pkg/services/query/query.go +++ b/pkg/services/query/query.go @@ -16,10 +16,10 @@ import ( "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/grafanads" @@ -61,7 +61,7 @@ func ProvideService( //go:generate mockery --name Service --structname FakeQueryService --inpackage --filename query_service_mock.go type Service interface { Run(ctx context.Context) error - QueryData(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) + QueryData(ctx context.Context, user *user.SignedInUser, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) } // Gives us compile time error if the service does not adhere to the contract of the interface @@ -85,7 +85,7 @@ func (s *ServiceImpl) Run(ctx context.Context) error { } // QueryData processes queries and returns query responses. It handles queries to single or mixed datasources, as well as expressions. -func (s *ServiceImpl) QueryData(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) { +func (s *ServiceImpl) QueryData(ctx context.Context, user *user.SignedInUser, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) { // Parse the request into parsed queries grouped by datasource uid parsedReq, err := s.parseMetricRequest(ctx, user, skipDSCache, reqDTO) if err != nil { @@ -111,7 +111,7 @@ type splitResponse struct { } // executeConcurrentQueries executes queries to multiple datasources concurrently and returns the aggregate result. -func (s *ServiceImpl) executeConcurrentQueries(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest, queriesbyDs map[string][]parsedQuery) (*backend.QueryDataResponse, error) { +func (s *ServiceImpl) executeConcurrentQueries(ctx context.Context, user *user.SignedInUser, skipDSCache bool, reqDTO dtos.MetricRequest, queriesbyDs map[string][]parsedQuery) (*backend.QueryDataResponse, error) { g, ctx := errgroup.WithContext(ctx) g.SetLimit(s.concurrentQueryLimit) // prevent too many concurrent requests rchan := make(chan splitResponse, len(queriesbyDs)) @@ -198,14 +198,14 @@ func buildErrorResponses(err error, queries []*simplejson.Json) splitResponse { } // handleExpressions handles POST /api/ds/query when there is an expression. -func (s *ServiceImpl) handleExpressions(ctx context.Context, user identity.Requester, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { +func (s *ServiceImpl) handleExpressions(ctx context.Context, user *user.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { exprReq := expr.Request{ Queries: []expr.Query{}, } if user != nil { // for passthrough authentication, SSE does not authenticate exprReq.User = user - exprReq.OrgId = user.GetOrgID() + exprReq.OrgId = user.OrgID } for _, pq := range parsedReq.getFlattenedQueries() { @@ -239,7 +239,7 @@ func (s *ServiceImpl) handleExpressions(ctx context.Context, user identity.Reque } // handleQuerySingleDatasource handles one or more queries to a single datasource -func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user identity.Requester, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { +func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user *user.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) { queries := parsedReq.getFlattenedQueries() ds := queries[0].datasource if err := s.pluginRequestValidator.Validate(ds.URL, nil); err != nil { @@ -271,7 +271,7 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden } // parseRequest parses a request into parsed queries grouped by datasource uid -func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest) (*parsedRequest, error) { +func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user *user.SignedInUser, skipDSCache bool, reqDTO dtos.MetricRequest) (*parsedRequest, error) { if len(reqDTO.Queries) == 0 { return nil, ErrNoQueriesFound } @@ -332,7 +332,7 @@ func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requ return req, req.validateRequest(ctx) } -func (s *ServiceImpl) getDataSourceFromQuery(ctx context.Context, user identity.Requester, skipDSCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) { +func (s *ServiceImpl) getDataSourceFromQuery(ctx context.Context, user *user.SignedInUser, skipDSCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) { var err error uid := query.Get("datasource").Get("uid").MustString() @@ -352,7 +352,7 @@ func (s *ServiceImpl) getDataSourceFromQuery(ctx context.Context, user identity. } if uid == grafanads.DatasourceUID { - return grafanads.DataSourceModel(user.GetOrgID()), nil + return grafanads.DataSourceModel(user.OrgID), nil } if uid != "" { diff --git a/pkg/services/query/query_service_mock.go b/pkg/services/query/query_service_mock.go index f3fc8684661..4d12dd838a4 100644 --- a/pkg/services/query/query_service_mock.go +++ b/pkg/services/query/query_service_mock.go @@ -11,7 +11,7 @@ import ( mock "github.com/stretchr/testify/mock" - identity "github.com/grafana/grafana/pkg/services/auth/identity" + user "github.com/grafana/grafana/pkg/services/user" ) // FakeQueryService is an autogenerated mock type for the Service type @@ -20,11 +20,11 @@ type FakeQueryService struct { } // QueryData provides a mock function with given fields: ctx, _a1, skipDSCache, reqDTO -func (_m *FakeQueryService) QueryData(ctx context.Context, _a1 identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) { +func (_m *FakeQueryService) QueryData(ctx context.Context, _a1 *user.SignedInUser, skipDSCache bool, reqDTO dtos.MetricRequest) (*backend.QueryDataResponse, error) { ret := _m.Called(ctx, _a1, skipDSCache, reqDTO) var r0 *backend.QueryDataResponse - if rf, ok := ret.Get(0).(func(context.Context, identity.Requester, bool, dtos.MetricRequest) *backend.QueryDataResponse); ok { + if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, bool, dtos.MetricRequest) *backend.QueryDataResponse); ok { r0 = rf(ctx, _a1, skipDSCache, reqDTO) } else { if ret.Get(0) != nil { @@ -33,7 +33,7 @@ func (_m *FakeQueryService) QueryData(ctx context.Context, _a1 identity.Requeste } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, identity.Requester, bool, dtos.MetricRequest) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, bool, dtos.MetricRequest) error); ok { r1 = rf(ctx, _a1, skipDSCache, reqDTO) } else { r1 = ret.Error(1) diff --git a/pkg/services/query/query_test.go b/pkg/services/query/query_test.go index 847b30671ee..5f0d3da55fa 100644 --- a/pkg/services/query/query_test.go +++ b/pkg/services/query/query_test.go @@ -25,7 +25,6 @@ import ( "github.com/grafana/grafana/pkg/models/roletype" "github.com/grafana/grafana/pkg/plugins" pluginFakes "github.com/grafana/grafana/pkg/plugins/manager/fakes" - "github.com/grafana/grafana/pkg/services/auth/identity" "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" @@ -525,12 +524,12 @@ type fakeDataSourceCache struct { cache []*datasources.DataSource } -func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user identity.Requester, skipCache bool) (*datasources.DataSource, error) { +func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { // deprecated: fake an error to ensure we are using GetDatasourceByUID return nil, fmt.Errorf("not found") } -func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user identity.Requester, skipCache bool) (*datasources.DataSource, error) { +func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) { for _, ds := range c.cache { if ds.UID == datasourceUID { return ds, nil diff --git a/pkg/services/user/identity.go b/pkg/services/user/identity.go index f2eaf6505af..671a97eb67a 100644 --- a/pkg/services/user/identity.go +++ b/pkg/services/user/identity.go @@ -43,9 +43,6 @@ func (u *SignedInUser) NameOrFallback() string { return u.Email } -// TODO: There's a need to remove this struct since it creates a circular dependency - -// DEPRECATED: This function uses `UserDisplayDTO` model which we want to remove func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO { return &UserDisplayDTO{ ID: u.UserID, @@ -54,16 +51,6 @@ func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO { } } -// Static function to parse a requester into a UserDisplayDTO -func NewUserDisplayDTOFromRequester(requester identity.Requester) (*UserDisplayDTO, error) { - userID, _ := identity.IntIdentifier(requester.GetNamespacedID()) - return &UserDisplayDTO{ - ID: userID, - Login: requester.GetLogin(), - Name: requester.GetDisplayName(), - }, nil -} - func (u *SignedInUser) HasRole(role roletype.RoleType) bool { if u.IsGrafanaAdmin { return true