diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 364dd0ba805..e73e0c3f004 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -150,10 +150,10 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response // Finding creator and last updater of the dashboard updater, creator := anonString, anonString if dash.UpdatedBy > 0 { - updater = hs.getUserLogin(ctx, dash.UpdatedBy) + updater = hs.getIdentityName(ctx, dash.OrgID, dash.UpdatedBy) } if dash.CreatedBy > 0 { - creator = hs.getUserLogin(ctx, dash.CreatedBy) + creator = hs.getIdentityName(ctx, dash.OrgID, dash.CreatedBy) } annotationPermissions := &dashboardsV0.AnnotationPermission{} @@ -265,16 +265,24 @@ func (hs *HTTPServer) getAnnotationPermissionsByScope(c *contextmodel.ReqContext } } -func (hs *HTTPServer) getUserLogin(ctx context.Context, userID int64) string { - ctx, span := tracer.Start(ctx, "api.getUserLogin") +// getIdentityName returns name of either user or service account +func (hs *HTTPServer) getIdentityName(ctx context.Context, orgID, id int64) string { + ctx, span := tracer.Start(ctx, "api.getIdentityName") defer span.End() - query := user.GetUserByIDQuery{ID: userID} - user, err := hs.userService.GetByID(ctx, &query) + // We use GetSignedInUser here instead of GetByID so both user and service accounts are resolved. + ident, err := hs.userService.GetSignedInUser(ctx, &user.GetSignedInUserQuery{ + UserID: id, + OrgID: orgID, + }) if err != nil { return anonString } - return user.Login + + if ident.IsIdentityType(claims.TypeServiceAccount) { + return ident.GetName() + } + return ident.GetLogin() } func (hs *HTTPServer) getDashboardHelper(ctx context.Context, orgID int64, id int64, uid string) (*dashboards.Dashboard, response.Response) { @@ -845,7 +853,7 @@ func (hs *HTTPServer) GetDashboardVersions(c *contextmodel.ReqContext) response. if found { creator = login } else { - creator = hs.getUserLogin(c.Req.Context(), version.CreatedBy) + creator = hs.getIdentityName(c.Req.Context(), c.SignedInUser.GetOrgID(), version.CreatedBy) if creator != anonString { loginMem[version.CreatedBy] = creator } @@ -941,7 +949,7 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R creator := anonString if res.CreatedBy > 0 { - creator = hs.getUserLogin(c.Req.Context(), res.CreatedBy) + creator = hs.getIdentityName(c.Req.Context(), dash.OrgID, res.CreatedBy) } dashVersionMeta := &dashver.DashboardVersionMeta{ diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 7701260e59f..b5a840d0cf9 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -742,7 +742,7 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) { }, } getHS(&usertest.FakeUserService{ - ExpectedUser: &user.User{ID: 1, Login: "test-user"}, + ExpectedSignedInUser: &user.SignedInUser{Login: "test-user"}, }).callGetDashboardVersions(sc) assert.Equal(t, http.StatusOK, sc.resp.Code) diff --git a/pkg/api/folder.go b/pkg/api/folder.go index d57f6559578..8e1738af28d 100644 --- a/pkg/api/folder.go +++ b/pkg/api/folder.go @@ -427,10 +427,10 @@ func (hs *HTTPServer) newToFolderDto(c *contextmodel.ReqContext, f *folder.Folde // Finding creator and last updater of the folder updater, creator := anonString, anonString if f.CreatedBy > 0 { - creator = hs.getUserLogin(ctx, f.CreatedBy) + creator = hs.getIdentityName(ctx, f.OrgID, f.CreatedBy) } if f.UpdatedBy > 0 { - updater = hs.getUserLogin(ctx, f.UpdatedBy) + updater = hs.getIdentityName(ctx, f.OrgID, f.UpdatedBy) } acMetadata, _ := hs.getFolderACMetadata(c, f) @@ -1079,10 +1079,10 @@ func (fk8s *folderK8sHandler) toDTO(c *contextmodel.ReqContext, fold *folder.Fol // #TODO refactor the various conversions of the folder so that we either set created by in folder.Folder or // we convert from unstructured to folder DTO without an intermediate conversion to folder.Folder if len(createdBy) > 0 { - creator = fk8s.getUserLogin(ctx, toUID(createdBy)) + creator = fk8s.getIdentityName(ctx, toUID(createdBy)) } if len(createdBy) > 0 { - updater = fk8s.getUserLogin(ctx, toUID(createdBy)) + updater = fk8s.getIdentityName(ctx, toUID(createdBy)) } acMetadata, _ := fk8s.getFolderACMetadata(c, fold) @@ -1119,18 +1119,21 @@ func (fk8s *folderK8sHandler) toDTO(c *contextmodel.ReqContext, fold *folder.Fol }, nil } -func (fk8s *folderK8sHandler) getUserLogin(ctx context.Context, userUID string) string { +func (fk8s *folderK8sHandler) getIdentityName(ctx context.Context, uid string) string { ctx, span := tracer.Start(ctx, "api.getUserLogin") defer span.End() - query := user.GetUserByUIDQuery{ - UID: userUID, - } - user, err := fk8s.userService.GetByUID(ctx, &query) + ident, err := fk8s.userService.GetByUID(ctx, &user.GetUserByUIDQuery{ + UID: uid, + }) if err != nil { return anonString } - return user.Login + + if ident.IsServiceAccount { + return ident.Name + } + return ident.Login } func (fk8s *folderK8sHandler) getFolderACMetadata(c *contextmodel.ReqContext, f *folder.Folder) (accesscontrol.Metadata, error) { diff --git a/pkg/api/folder_test.go b/pkg/api/folder_test.go index 5277e3d196f..b676bb15696 100644 --- a/pkg/api/folder_test.go +++ b/pkg/api/folder_test.go @@ -534,6 +534,7 @@ func (m mockClientConfigProvider) DirectlyServeHTTP(w http.ResponseWriter, r *ht func TestUpdateFolderLegacyAndUnifiedStorage(t *testing.T) { testuser := &user.User{ID: 99, UID: "fdxsqt7t5ryf4a", Login: "testuser"} + testSignedInUser := &user.SignedInUser{UserID: 99, UserUID: "fdxsqt7t5ryf4a", Login: "testuser"} legacyFolder := folder.Folder{ UID: "ady4yobv315a8e", @@ -718,7 +719,8 @@ func TestUpdateFolderLegacyAndUnifiedStorage(t *testing.T) { ExpectedResult: model.HitList{}, } hs.userService = &usertest.FakeUserService{ - ExpectedUser: testuser, + ExpectedUser: testuser, + ExpectedSignedInUser: testSignedInUser, } hs.Features = featuremgmt.WithFeatures( featuresArr...,