diff --git a/pkg/api/admin_users.go b/pkg/api/admin_users.go index b4b87b06b06..f9bb2150964 100644 --- a/pkg/api/admin_users.go +++ b/pkg/api/admin_users.go @@ -65,7 +65,7 @@ func AdminUpdateUserPassword(c *models.ReqContext, form dtos.AdminUpdateUserPass userQuery := models.GetUserByIdQuery{Id: userID} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(c.Req.Context(), &userQuery); err != nil { return response.Error(500, "Could not read user from database", err) } diff --git a/pkg/api/admin_users_test.go b/pkg/api/admin_users_test.go index 75ef59a3bd7..cce77a46abe 100644 --- a/pkg/api/admin_users_test.go +++ b/pkg/api/admin_users_test.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "fmt" "testing" @@ -54,7 +55,7 @@ func TestAdminAPIEndpoint(t *testing.T) { t.Run("When a server admin attempts to logout himself from all devices", func(t *testing.T) { adminLogoutUserScenario(t, "Should not be allowed when calling POST on", "/api/admin/users/1/logout", "/api/admin/users/:id/logout", func(sc *scenarioContext) { - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { cmd.Result = &models.User{Id: testUserID} return nil }) @@ -69,7 +70,7 @@ func TestAdminAPIEndpoint(t *testing.T) { "/api/admin/users/:id/logout", func(sc *scenarioContext) { userID := int64(0) - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { userID = cmd.Id return models.ErrUserNotFound }) @@ -85,7 +86,7 @@ func TestAdminAPIEndpoint(t *testing.T) { adminRevokeUserAuthTokenScenario(t, "Should return not found when calling POST on", "/api/admin/users/200/revoke-auth-token", "/api/admin/users/:id/revoke-auth-token", cmd, func(sc *scenarioContext) { var userID int64 - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { userID = cmd.Id return models.ErrUserNotFound }) @@ -100,7 +101,7 @@ func TestAdminAPIEndpoint(t *testing.T) { adminGetUserAuthTokensScenario(t, "Should return not found when calling GET on", "/api/admin/users/200/auth-tokens", "/api/admin/users/:id/auth-tokens", func(sc *scenarioContext) { var userID int64 - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { userID = cmd.Id return models.ErrUserNotFound }) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 961f401d514..91a9f2d13cd 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -107,10 +107,10 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response { // Finding creator and last updater of the dashboard updater, creator := anonString, anonString if dash.UpdatedBy > 0 { - updater = getUserLogin(dash.UpdatedBy) + updater = getUserLogin(c.Req.Context(), dash.UpdatedBy) } if dash.CreatedBy > 0 { - creator = getUserLogin(dash.CreatedBy) + creator = getUserLogin(c.Req.Context(), dash.CreatedBy) } meta := dtos.DashboardMeta{ @@ -188,9 +188,9 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response { return response.JSON(200, dto) } -func getUserLogin(userID int64) string { +func getUserLogin(ctx context.Context, userID int64) string { query := models.GetUserByIdQuery{Id: userID} - err := bus.Dispatch(&query) + err := bus.DispatchCtx(ctx, &query) if err != nil { return anonString } @@ -562,7 +562,7 @@ func GetDashboardVersion(c *models.ReqContext) response.Response { creator := anonString if query.Result.CreatedBy > 0 { - creator = getUserLogin(query.Result.CreatedBy) + creator = getUserLogin(c.Req.Context(), query.Result.CreatedBy) } dashVersionMeta := &models.DashboardVersionMeta{ diff --git a/pkg/api/folder.go b/pkg/api/folder.go index a2cac9391dd..fda9e4fa05e 100644 --- a/pkg/api/folder.go +++ b/pkg/api/folder.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "fmt" @@ -42,7 +43,7 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response { } g := guardian.New(folder.Id, c.OrgId, c.SignedInUser) - return response.JSON(200, toFolderDto(g, folder)) + return response.JSON(200, toFolderDto(c.Req.Context(), g, folder)) } func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response { @@ -53,7 +54,7 @@ func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response { } g := guardian.New(folder.Id, c.OrgId, c.SignedInUser) - return response.JSON(200, toFolderDto(g, folder)) + return response.JSON(200, toFolderDto(c.Req.Context(), g, folder)) } func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolderCommand) response.Response { @@ -71,7 +72,7 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolder } g := guardian.New(folder.Id, c.OrgId, c.SignedInUser) - return response.JSON(200, toFolderDto(g, folder)) + return response.JSON(200, toFolderDto(c.Req.Context(), g, folder)) } func (hs *HTTPServer) UpdateFolder(c *models.ReqContext, cmd models.UpdateFolderCommand) response.Response { @@ -82,7 +83,7 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext, cmd models.UpdateFolder } g := guardian.New(cmd.Result.Id, c.OrgId, c.SignedInUser) - return response.JSON(200, toFolderDto(g, cmd.Result)) + return response.JSON(200, toFolderDto(c.Req.Context(), g, cmd.Result)) } func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // temporarily adding this function to HTTPServer, will be removed from HTTPServer when librarypanels featuretoggle is removed @@ -107,7 +108,7 @@ func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // }) } -func toFolderDto(g guardian.DashboardGuardian, folder *models.Folder) dtos.Folder { +func toFolderDto(ctx context.Context, g guardian.DashboardGuardian, folder *models.Folder) dtos.Folder { canEdit, _ := g.CanEdit() canSave, _ := g.CanSave() canAdmin, _ := g.CanAdmin() @@ -115,10 +116,10 @@ func toFolderDto(g guardian.DashboardGuardian, folder *models.Folder) dtos.Folde // Finding creator and last updater of the folder updater, creator := anonString, anonString if folder.CreatedBy > 0 { - creator = getUserLogin(folder.CreatedBy) + creator = getUserLogin(ctx, folder.CreatedBy) } if folder.UpdatedBy > 0 { - updater = getUserLogin(folder.UpdatedBy) + updater = getUserLogin(ctx, folder.UpdatedBy) } return dtos.Folder{ diff --git a/pkg/api/ldap_debug.go b/pkg/api/ldap_debug.go index 126e760b671..ab9f0d8b388 100644 --- a/pkg/api/ldap_debug.go +++ b/pkg/api/ldap_debug.go @@ -165,7 +165,7 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) response.Respon query := models.GetUserByIdQuery{Id: userId} - if err := bus.Dispatch(&query); err != nil { // validate the userId exists + if err := bus.DispatchCtx(c.Req.Context(), &query); err != nil { // validate the userId exists if errors.Is(err, models.ErrUserNotFound) { return response.Error(404, models.ErrUserNotFound.Error(), nil) } diff --git a/pkg/api/ldap_debug_test.go b/pkg/api/ldap_debug_test.go index b8d31cc1b26..80e0cb4ac8d 100644 --- a/pkg/api/ldap_debug_test.go +++ b/pkg/api/ldap_debug_test.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "net/http" "net/http/httptest" @@ -434,7 +435,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) { return nil }) - bus.AddHandler("test", func(q *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, q *models.GetUserByIdQuery) error { require.Equal(t, q.Id, int64(34)) q.Result = &models.User{Login: "ldap-daniel", Id: 34} @@ -470,7 +471,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) { return &LDAPMock{} } - bus.AddHandler("test", func(q *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, q *models.GetUserByIdQuery) error { require.Equal(t, q.Id, int64(34)) return models.ErrUserNotFound @@ -502,7 +503,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) { sc.cfg.AdminUser = "ldap-daniel" - bus.AddHandler("test", func(q *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, q *models.GetUserByIdQuery) error { require.Equal(t, q.Id, int64(34)) q.Result = &models.User{Login: "ldap-daniel", Id: 34} @@ -546,7 +547,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) { return nil }) - bus.AddHandler("test", func(q *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, q *models.GetUserByIdQuery) error { require.Equal(t, q.Id, int64(34)) q.Result = &models.User{Login: "ldap-daniel", Id: 34} @@ -687,7 +688,7 @@ func TestLDAP_AccessControl(t *testing.T) { return &LDAPMock{} } - bus.AddHandler("test", func(q *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, q *models.GetUserByIdQuery) error { q.Result = &models.User{} return nil }) diff --git a/pkg/api/user.go b/pkg/api/user.go index 8b01f67b27e..91b6a9c3fc3 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -223,7 +223,7 @@ func ChangeUserPassword(c *models.ReqContext, cmd models.ChangeUserPasswordComma userQuery := models.GetUserByIdQuery{Id: c.UserId} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(c.Req.Context(), &userQuery); err != nil { return response.Error(500, "Could not read user from database", err) } diff --git a/pkg/api/user_token.go b/pkg/api/user_token.go index 257d60c1ab7..1b813d5866a 100644 --- a/pkg/api/user_token.go +++ b/pkg/api/user_token.go @@ -26,7 +26,7 @@ func (hs *HTTPServer) RevokeUserAuthToken(c *models.ReqContext, cmd models.Revok func (hs *HTTPServer) logoutUserFromAllDevicesInternal(ctx context.Context, userID int64) response.Response { userQuery := models.GetUserByIdQuery{Id: userID} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(ctx, &userQuery); err != nil { if errors.Is(err, models.ErrUserNotFound) { return response.Error(404, "User not found", err) } @@ -46,7 +46,7 @@ func (hs *HTTPServer) logoutUserFromAllDevicesInternal(ctx context.Context, user func (hs *HTTPServer) getUserAuthTokensInternal(c *models.ReqContext, userID int64) response.Response { userQuery := models.GetUserByIdQuery{Id: userID} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(c.Req.Context(), &userQuery); err != nil { if errors.Is(err, models.ErrUserNotFound) { return response.Error(404, "User not found", err) } @@ -113,7 +113,7 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *models.ReqContext, userID int func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID int64, cmd models.RevokeAuthTokenCmd) response.Response { userQuery := models.GetUserByIdQuery{Id: userID} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(c.Req.Context(), &userQuery); err != nil { if errors.Is(err, models.ErrUserNotFound) { return response.Error(404, "User not found", err) } diff --git a/pkg/api/user_token_test.go b/pkg/api/user_token_test.go index 65883fa10dd..2a114b7cc74 100644 --- a/pkg/api/user_token_test.go +++ b/pkg/api/user_token_test.go @@ -21,7 +21,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { revokeUserAuthTokenScenario(t, "Should return not found when calling POST on", "/api/user/revoke-auth-token", "/api/user/revoke-auth-token", cmd, 200, func(sc *scenarioContext) { var userID int64 - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { userID = cmd.Id return models.ErrUserNotFound }) @@ -35,7 +35,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { t.Run("When current user gets auth tokens for a non-existing user", func(t *testing.T) { getUserAuthTokensScenario(t, "Should return not found when calling GET on", "/api/user/auth-tokens", "/api/user/auth-tokens", 200, func(sc *scenarioContext) { var userID int64 - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { userID = cmd.Id return models.ErrUserNotFound }) @@ -49,7 +49,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { t.Run("When logging out an existing user from all devices", func(t *testing.T) { logoutUserFromAllDevicesInternalScenario(t, "Should be successful", 1, func(sc *scenarioContext) { const userID int64 = 200 - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { cmd.Result = &models.User{Id: userID} return nil }) @@ -61,7 +61,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { t.Run("When logout a non-existing user from all devices", func(t *testing.T) { logoutUserFromAllDevicesInternalScenario(t, "Should return not found", testUserID, func(sc *scenarioContext) { - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { return models.ErrUserNotFound }) @@ -75,7 +75,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { token := &models.UserToken{Id: 1} revokeUserAuthTokenInternalScenario(t, "Should be successful", cmd, 200, token, func(sc *scenarioContext) { - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { cmd.Result = &models.User{Id: 200} return nil }) @@ -93,7 +93,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { token := &models.UserToken{Id: 2} revokeUserAuthTokenInternalScenario(t, "Should not be successful", cmd, testUserID, token, func(sc *scenarioContext) { - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { cmd.Result = &models.User{Id: testUserID} return nil }) @@ -110,7 +110,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) { currentToken := &models.UserToken{Id: 1} getUserAuthTokensInternalScenario(t, "Should be successful", currentToken, func(sc *scenarioContext) { - bus.AddHandler("test", func(cmd *models.GetUserByIdQuery) error { + bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.GetUserByIdQuery) error { cmd.Result = &models.User{Id: testUserID} return nil }) diff --git a/pkg/cmd/grafana-cli/commands/reset_password_command.go b/pkg/cmd/grafana-cli/commands/reset_password_command.go index 38e3a694846..6bcd1d4de84 100644 --- a/pkg/cmd/grafana-cli/commands/reset_password_command.go +++ b/pkg/cmd/grafana-cli/commands/reset_password_command.go @@ -2,6 +2,7 @@ package commands import ( "bufio" + "context" "fmt" "os" @@ -42,7 +43,7 @@ func resetPasswordCommand(c utils.CommandLine, sqlStore *sqlstore.SQLStore) erro userQuery := models.GetUserByIdQuery{Id: AdminUserId} - if err := bus.Dispatch(&userQuery); err != nil { + if err := bus.DispatchCtx(context.Background(), &userQuery); err != nil { return fmt.Errorf("could not read user from database. Error: %v", err) } diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index 409ab8e4664..e7b4270dd5a 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -18,7 +18,7 @@ import ( func (ss *SQLStore) addUserQueryAndCommandHandlers() { ss.Bus.AddHandlerCtx(ss.GetSignedInUserWithCacheCtx) - bus.AddHandler("sql", GetUserById) + bus.AddHandlerCtx("sql", GetUserById) bus.AddHandler("sql", UpdateUser) bus.AddHandler("sql", ChangeUserPassword) bus.AddHandler("sql", GetUserByLogin) @@ -280,19 +280,21 @@ func (ss *SQLStore) CreateUser(ctx context.Context, cmd models.CreateUserCommand return user, err } -func GetUserById(query *models.GetUserByIdQuery) error { - user := new(models.User) - has, err := x.Id(query.Id).Get(user) +func GetUserById(ctx context.Context, query *models.GetUserByIdQuery) error { + return withDbSession(ctx, x, func(sess *DBSession) error { + user := new(models.User) + has, err := sess.ID(query.Id).Get(user) - if err != nil { - return err - } else if !has { - return models.ErrUserNotFound - } + if err != nil { + return err + } else if !has { + return models.ErrUserNotFound + } - query.Result = user + query.Result = user - return nil + return nil + }) } func GetUserByLogin(query *models.GetUserByLoginQuery) error { diff --git a/pkg/services/sqlstore/user_test.go b/pkg/services/sqlstore/user_test.go index e69c6682c51..e8f6dd3621b 100644 --- a/pkg/services/sqlstore/user_test.go +++ b/pkg/services/sqlstore/user_test.go @@ -27,7 +27,7 @@ func TestUserDataAccess(t *testing.T) { require.NoError(t, err) query := models.GetUserByIdQuery{Id: user.Id} - err = GetUserById(&query) + err = GetUserById(context.Background(), &query) require.Nil(t, err) require.Equal(t, query.Result.Email, "usertest@test.com") @@ -37,7 +37,7 @@ func TestUserDataAccess(t *testing.T) { require.False(t, query.Result.IsDisabled) query = models.GetUserByIdQuery{Id: user.Id} - err = GetUserById(&query) + err = GetUserById(context.Background(), &query) require.Nil(t, err) require.Equal(t, query.Result.Email, "usertest@test.com") @@ -60,7 +60,7 @@ func TestUserDataAccess(t *testing.T) { require.Nil(t, err) query := models.GetUserByIdQuery{Id: user.Id} - err = GetUserById(&query) + err = GetUserById(context.Background(), &query) require.Nil(t, err) require.Equal(t, query.Result.Email, "usertest@test.com") @@ -94,7 +94,7 @@ func TestUserDataAccess(t *testing.T) { require.Nil(t, err) query := models.GetUserByIdQuery{Id: user.Id} - err = GetUserById(&query) + err = GetUserById(context.Background(), &query) require.Nil(t, err) require.Equal(t, query.Result.Email, "usertest@test.com") @@ -612,7 +612,7 @@ func TestUserDataAccess(t *testing.T) { require.Equal(t, updatePermsError, models.ErrLastGrafanaAdmin) query := models.GetUserByIdQuery{Id: user.Id} - getUserError := GetUserById(&query) + getUserError := GetUserById(context.Background(), &query) require.Nil(t, getUserError) require.True(t, query.Result.IsAdmin)