diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 1378bca679c..54f59de902d 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -422,14 +422,15 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S ctx := c.Req.Context() var err error + userID := int64(0) namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { - hs.log.Warn("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr) - return response.Error(http.StatusBadRequest, "User does not belong to a user or service account namespace", nil) - } - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) + hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr) + } else { + userID, err = identity.IntIdentifier(namespaceID, userIDstr) + if err != nil { + hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) + } } cmd.OrgID = c.SignedInUser.GetOrgID() @@ -454,7 +455,7 @@ 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(http.StatusInternalServerError, "Failed to get quota", err) } if limitReached { return response.Error(http.StatusForbidden, "Quota reached", nil) @@ -516,7 +517,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S } if liveerr != nil { - hs.log.Warn("unable to broadcast save event", "uid", dashboard.UID, "error", liveerr) + hs.log.Warn("Unable to broadcast save event", "uid", dashboard.UID, "error", liveerr) } } @@ -556,16 +557,18 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S // 401: unauthorisedError // 500: internalServerError func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Response { + userID := int64(0) + var err error namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() - - if namespaceID != identity.NamespaceUser { - return response.Error(http.StatusBadRequest, "User does not belong to a user namespace", nil) + if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { + hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr) + } else { + userID, err = identity.IntIdentifier(namespaceID, userIDstr) + if err != nil { + hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) + } } - 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()} homePage := hs.Cfg.HomePage @@ -864,7 +867,7 @@ func (hs *HTTPServer) ValidateDashboard(c *contextmodel.ReqContext) response.Res cmd := dashboards.ValidateDashboardCommand{} if err := web.Bind(c.Req, &cmd); err != nil { - return response.Error(http.StatusBadRequest, "bad request data", err) + return response.Error(http.StatusBadRequest, "Bad request data", err) } dk := hs.Kinds.Dashboard() @@ -1074,13 +1077,15 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *contextmodel.ReqContext) respon return response.Error(http.StatusNotFound, "Dashboard version not found", nil) } + userID := int64(0) namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { - return response.Error(http.StatusBadRequest, "User does not belong to a user or service namespace", nil) - } - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - return response.Error(http.StatusInternalServerError, "failed to get user id", err) + hs.log.Warn("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr) + } else { + userID, err = identity.IntIdentifier(namespaceID, userIDstr) + if err != nil { + hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) + } } saveCmd := dashboards.SaveDashboardCommand{} diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index e54aac448cb..3a5fdddbeaf 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -22,7 +22,6 @@ import ( "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" - "github.com/grafana/grafana/pkg/util/errutil" ) var ( @@ -207,15 +206,16 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d } func resolveUserID(user identity.Requester, log log.Logger) (int64, error) { + userID := int64(0) namespaceID, identifier := user.GetNamespacedID() if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { - return 0, errutil.BadRequest("account doesn't belong to the user or service namespace") + log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", identifier) } userID, err := identity.IntIdentifier(namespaceID, identifier) if err != nil { - log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", identifier, "error", err) + log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", identifier, "error", err) } return userID, nil } diff --git a/pkg/services/folder/folderimpl/folder.go b/pkg/services/folder/folderimpl/folder.go index 972d0292856..abf111d0547 100644 --- a/pkg/services/folder/folderimpl/folder.go +++ b/pkg/services/folder/folderimpl/folder.go @@ -281,14 +281,17 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) ( dashFolder.SetUID(trimmedUID) user := cmd.SignedInUser + + userID := int64(0) + var err error namespaceID, userIDstr := user.GetNamespacedID() - if namespaceID == identity.NamespaceAPIKey { - s.log.Warn("namespace API key detected, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) - userIDstr = "0" - } - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) + if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { + s.log.Debug("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) + } else { + userID, err = identity.IntIdentifier(namespaceID, userIDstr) + if err != nil { + s.log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) + } } if userID == 0 { @@ -773,14 +776,15 @@ func (s *Service) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards } } + userID := int64(0) namespaceID, userIDstr := dto.User.GetNamespacedID() - if namespaceID == identity.NamespaceAPIKey { - s.log.Warn("namespace API key detected, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) - userIDstr = "0" - } - userID, err := identity.IntIdentifier(namespaceID, userIDstr) - if err != nil { - s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) + if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { + s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) + } else { + 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{ diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index 587bf17debd..1100cad8ce6 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -300,15 +300,11 @@ func ProvideService(plugCtxProvider *plugincontext.Provider, cfg *setting.Cfg, r g.websocketHandler = func(ctx *contextmodel.ReqContext) { user := ctx.SignedInUser - namespaceID, userID := user.GetNamespacedID() - - if namespaceID != identity.NamespaceUser { - return // Only users can connect to Live - } + _, identifier := user.GetNamespacedID() // Centrifuge expects Credentials in context with a current user ID. cred := ¢rifuge.Credentials{ - UserID: userID, + UserID: identifier, } newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred) newCtx = livecontext.SetContextSignedUser(newCtx, user) diff --git a/pkg/services/user/identity.go b/pkg/services/user/identity.go index 4ce24e1b58a..f4e8b28bba1 100644 --- a/pkg/services/user/identity.go +++ b/pkg/services/user/identity.go @@ -59,11 +59,12 @@ func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO { // Static function to parse a requester into a UserDisplayDTO func NewUserDisplayDTOFromRequester(requester identity.Requester) (*UserDisplayDTO, error) { + userID := int64(0) namespaceID, identifier := requester.GetNamespacedID() - if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { - identifier = "0" + if namespaceID == identity.NamespaceUser || namespaceID == identity.NamespaceServiceAccount { + userID, _ = identity.IntIdentifier(namespaceID, identifier) } - userID, _ := identity.IntIdentifier(namespaceID, identifier) + return &UserDisplayDTO{ ID: userID, Login: requester.GetLogin(),