MM-30882: Fix read-after-write issue for demoting user (#16911)
* MM-30882: Fix read-after-write issue for demoting user In (*App).DemoteUserToGuest, we would demote a user, and then immediately read it back to do future operations from the user. This reading back of the user had the effect of sticking the old value into the cache after which it would never be updated. There was another issue along with this, which was when the invalidation message would broadcast across the cluster, it would hit the cache invalidation problem where an unrelated store call would miss the cache because it was invalidated, and then again read from replica and stick the old value. To fix all these, we return the new value directly from the store method to avoid having the app to read it again. And we add a map in the localcache layer which tracks invalidations made, and then switch to use master if it's true. The core change is fairly limited, but due to changing the store method signatures, a lot of code needed to be updated to pass "context.Background". Therefore the PR just "appears" to be big, but the main changes are limited to app/user.go, sqlstore/user_store.go and user_layer.go https://mattermost.atlassian.net/browse/MM-30882 ```release-note Fix an issue where demoting a user to guest would not take effect in an environment with read replicas. ``` * Fix concurrent map access * Fixing mistakes * fix tests
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
49907d3081
Коммит
021c90f29f
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -55,7 +56,7 @@ func (a *App) CreateBot(bot *model.Bot) (*model.Bot, *model.AppError) {
|
||||
}
|
||||
|
||||
// Get the owner of the bot, if one exists. If not, don't send a message
|
||||
ownerUser, err := a.Srv().Store.User().Get(bot.OwnerId)
|
||||
ownerUser, err := a.Srv().Store.User().Get(context.Background(), bot.OwnerId)
|
||||
var nfErr *store.ErrNotFound
|
||||
if err != nil && !errors.As(err, &nfErr) {
|
||||
return nil, model.NewAppError("CreateBot", "app.user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -156,7 +157,7 @@ func (a *App) PatchBot(botUserId string, botPatch *model.BotPatch) (*model.Bot,
|
||||
|
||||
bot.Patch(botPatch)
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(botUserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), botUserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -233,7 +234,7 @@ func (a *App) GetBots(options *model.BotGetOptions) (model.BotList, *model.AppEr
|
||||
|
||||
// UpdateBotActive marks a bot as active or inactive, along with its corresponding user.
|
||||
func (a *App) UpdateBotActive(botUserId string, active bool) (*model.Bot, *model.AppError) {
|
||||
user, nErr := a.Srv().Store.User().Get(botUserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), botUserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -67,7 +68,7 @@ func (a *App) JoinDefaultChannels(teamID string, user *model.User, shouldBeAdmin
|
||||
var requestor *model.User
|
||||
var nErr error
|
||||
if userRequestorId != "" {
|
||||
requestor, nErr = a.Srv().Store.User().Get(userRequestorId)
|
||||
requestor, nErr = a.Srv().Store.User().Get(context.Background(), userRequestorId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -264,7 +265,7 @@ func (a *App) CreateChannel(channel *model.Channel, addMember bool) (*model.Chan
|
||||
}
|
||||
|
||||
if addMember {
|
||||
user, nErr := a.Srv().Store.User().Get(channel.CreatorId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), channel.CreatorId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -386,7 +387,7 @@ func (a *App) handleCreationEvent(userID, otherUserID string, channel *model.Cha
|
||||
}
|
||||
|
||||
func (a *App) createDirectChannel(userID, otherUserID string) (*model.Channel, *model.AppError) {
|
||||
users, err := a.Srv().Store.User().GetMany([]string{userID, otherUserID})
|
||||
users, err := a.Srv().Store.User().GetMany(context.Background(), []string{userID, otherUserID})
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
@@ -520,7 +521,7 @@ func (a *App) createGroupChannel(userIDs []string) (*model.Channel, *model.AppEr
|
||||
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(userIDs, nil, true)
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, nil, true)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("createGroupChannel", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
@@ -599,7 +600,7 @@ func (a *App) GetGroupChannel(userIDs []string) (*model.Channel, *model.AppError
|
||||
return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(userIDs, nil, true)
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, nil, true)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("GetGroupChannel", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
@@ -745,7 +746,7 @@ func (a *App) RestoreChannel(channel *model.Channel, userID string) (*model.Chan
|
||||
message.Add("channel_id", channel.Id)
|
||||
a.Publish(message)
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(userID)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -1236,7 +1237,7 @@ func (a *App) DeleteChannel(channel *model.Channel, userID string) *model.AppErr
|
||||
var user *model.User
|
||||
if userID != "" {
|
||||
var nErr error
|
||||
user, nErr = a.Srv().Store.User().Get(userID)
|
||||
user, nErr = a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -1492,7 +1493,7 @@ func (a *App) AddDirectChannels(teamID string, user *model.User) *model.AppError
|
||||
}
|
||||
|
||||
func (a *App) PostUpdateChannelHeaderMessage(userID string, channel *model.Channel, oldChannelHeader, newChannelHeader string) *model.AppError {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
return model.NewAppError("PostUpdateChannelHeaderMessage", "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
@@ -1526,7 +1527,7 @@ func (a *App) PostUpdateChannelHeaderMessage(userID string, channel *model.Chann
|
||||
}
|
||||
|
||||
func (a *App) PostUpdateChannelPurposeMessage(userID string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
return model.NewAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
@@ -1559,7 +1560,7 @@ func (a *App) PostUpdateChannelPurposeMessage(userID string, channel *model.Chan
|
||||
}
|
||||
|
||||
func (a *App) PostUpdateChannelDisplayNameMessage(userID string, channel *model.Channel, oldChannelDisplayName, newChannelDisplayName string) *model.AppError {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
@@ -1905,7 +1906,7 @@ func (a *App) JoinChannel(channel *model.Channel, userID string) *model.AppError
|
||||
userChan := make(chan store.StoreResult, 1)
|
||||
memberChan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
userChan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(userChan)
|
||||
}()
|
||||
@@ -2014,7 +2015,7 @@ func (a *App) LeaveChannel(channelId string, userID string) *model.AppError {
|
||||
|
||||
uc := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
uc <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uc)
|
||||
}()
|
||||
@@ -2176,7 +2177,7 @@ func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *mo
|
||||
}
|
||||
|
||||
func (a *App) removeUserFromChannel(userIDToRemove string, removerUserId string, channel *model.Channel) *model.AppError {
|
||||
user, nErr := a.Srv().Store.User().Get(userIDToRemove)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), userIDToRemove)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
@@ -1910,7 +1911,7 @@ func TestMarkChannelsAsViewedPanic(t *testing.T) {
|
||||
|
||||
mockStore := th.App.Srv().Store.(*mocks.Store)
|
||||
mockUserStore := mocks.UserStore{}
|
||||
mockUserStore.On("Get", "userID").Return(nil, model.NewAppError("SqlUserStore.Get", "app.user.get.app_error", nil, "user_id=userID", http.StatusInternalServerError))
|
||||
mockUserStore.On("Get", context.Background(), "userID").Return(nil, model.NewAppError("SqlUserStore.Get", "app.user.get.app_error", nil, "user_id=userID", http.StatusInternalServerError))
|
||||
mockChannelStore := mocks.ChannelStore{}
|
||||
mockChannelStore.On("Get", "channelID", true).Return(&model.Channel{}, nil)
|
||||
mockChannelStore.On("GetMember", "channelID", "userID").Return(&model.ChannelMember{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -368,7 +369,7 @@ func (a *App) tryExecuteCustomCommand(args *model.CommandArgs, trigger string, m
|
||||
|
||||
userChan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(args.UserId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), args.UserId)
|
||||
userChan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(userChan)
|
||||
}()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
@@ -194,7 +195,7 @@ func (job *EmailBatchingJob) checkPendingNotifications(now time.Time, handler fu
|
||||
}
|
||||
|
||||
func (es *EmailService) sendBatchedEmailNotification(userID string, notifications []*batchedNotification) {
|
||||
user, err := es.srv.Store.User().Get(userID)
|
||||
user, err := es.srv.Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
mlog.Warn("Unable to find recipient for batched email notification")
|
||||
return
|
||||
@@ -205,7 +206,7 @@ func (es *EmailService) sendBatchedEmailNotification(userID string, notification
|
||||
|
||||
var contents string
|
||||
for _, notification := range notifications {
|
||||
sender, err := es.srv.Store.User().Get(notification.post.UserId)
|
||||
sender, err := es.srv.Store.User().Get(context.Background(), notification.post.UserId)
|
||||
if err != nil {
|
||||
mlog.Warn("Unable to find sender of post for batched email notification")
|
||||
continue
|
||||
|
||||
@@ -5,6 +5,7 @@ package app
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -483,7 +484,7 @@ func (a *App) BuildPostReactions(postId string) (*[]ReactionImportData, *model.A
|
||||
}
|
||||
|
||||
for _, reaction := range reactions {
|
||||
user, err := a.Srv().Store.User().Get(reaction.UserId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), reaction.UserId)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
if errors.As(err, &nfErr) { // this is a valid case, the user that reacted might've been deleted by now
|
||||
|
||||
@@ -19,6 +19,7 @@ package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -84,7 +85,7 @@ func (a *App) DoPostActionWithCookie(postId, actionId, userID, selectedOption st
|
||||
|
||||
userChan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(upstreamRequest.UserId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), upstreamRequest.UserId)
|
||||
userChan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(userChan)
|
||||
}()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -28,7 +29,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
|
||||
pchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
props, err := a.Srv().Store.User().GetAllProfilesInChannel(channel.Id, true)
|
||||
props, err := a.Srv().Store.User().GetAllProfilesInChannel(context.Background(), channel.Id, true)
|
||||
pchan <- store.StoreResult{Data: props, NErr: err}
|
||||
close(pchan)
|
||||
}()
|
||||
|
||||
@@ -5,6 +5,7 @@ package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
b64 "encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -288,7 +289,7 @@ func (a *App) GetOAuthAccessTokenForCodeFlow(clientId, grantType, redirectUri, c
|
||||
return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.redirect_uri.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
user, nErr = a.Srv().Store.User().Get(authData.UserId)
|
||||
user, nErr = a.Srv().Store.User().Get(context.Background(), authData.UserId)
|
||||
if nErr != nil {
|
||||
return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.internal_user.app_error", nil, "", http.StatusNotFound)
|
||||
}
|
||||
@@ -347,7 +348,7 @@ func (a *App) GetOAuthAccessTokenForCodeFlow(clientId, grantType, redirectUri, c
|
||||
return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.refresh_token.app_error", nil, "", http.StatusNotFound)
|
||||
}
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(accessData.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), accessData.UserId)
|
||||
if nErr != nil {
|
||||
return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.internal_user.app_error", nil, "", http.StatusNotFound)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -53,7 +54,7 @@ func (a *App) CreatePostAsUser(post *model.Post, currentSessionId string, setOnl
|
||||
}
|
||||
|
||||
if err.Id == "api.post.create_post.town_square_read_only" {
|
||||
user, nErr := a.Srv().Store.User().Get(post.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), post.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -191,7 +192,7 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
|
||||
}()
|
||||
}
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(post.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), post.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -427,7 +428,7 @@ func (a *App) SetSessionExpireInDays(session *model.Session, days int) {
|
||||
|
||||
func (a *App) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) {
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(token.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), token.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -476,7 +477,7 @@ func (a *App) createSessionForUserAccessToken(tokenString string) (*model.Sessio
|
||||
return nil, model.NewAppError("createSessionForUserAccessToken", "app.user_access_token.invalid_or_missing", nil, "inactive_token", http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(token.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), token.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
|
||||
@@ -5,6 +5,7 @@ package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"regexp"
|
||||
@@ -88,7 +89,7 @@ func replaceUserIds(userStore store.UserStore, text string) string {
|
||||
userIDs = append(userIDs, match[1])
|
||||
}
|
||||
|
||||
if users, err := userStore.GetProfileByIds(userIDs, nil, true); err == nil {
|
||||
if users, err := userStore.GetProfileByIds(context.Background(), userIDs, nil, true); err == nil {
|
||||
for _, user := range users {
|
||||
text = strings.Replace(text, "<@"+user.Id+">", "@"+user.Username, -1)
|
||||
}
|
||||
|
||||
14
app/team.go
14
app/team.go
@@ -489,7 +489,7 @@ func (a *App) AddUserToTeam(teamID string, userID string, userRequestorId string
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
@@ -566,7 +566,7 @@ func (a *App) AddUserToTeamByToken(userID string, tokenID string) (*model.Team,
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
@@ -641,7 +641,7 @@ func (a *App) AddUserToTeamByInviteId(inviteId string, userID string) (*model.Te
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
@@ -1163,7 +1163,7 @@ func (a *App) RemoveUserFromTeam(teamID string, userID string, requestorId strin
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
@@ -1206,7 +1206,7 @@ func (a *App) RemoveTeamMemberFromTeam(teamMember *model.TeamMember, requestorId
|
||||
message.Add("team_id", teamMember.TeamId)
|
||||
a.Publish(message)
|
||||
|
||||
user, nErr := a.Srv().Store.User().Get(teamMember.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), teamMember.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -1368,7 +1368,7 @@ func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string) (*model.User,
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(senderId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), senderId)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
@@ -1499,7 +1499,7 @@ func (a *App) prepareInviteGuestsToChannels(teamID string, guestsInvite *model.G
|
||||
}()
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(senderId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), senderId)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
|
||||
26
app/user.go
26
app/user.go
@@ -5,6 +5,7 @@ package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -432,7 +433,7 @@ func (a *App) IsUsernameTaken(name string) bool {
|
||||
}
|
||||
|
||||
func (a *App) GetUser(userID string) (*model.User, *model.AppError) {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -683,7 +684,7 @@ func (a *App) GetChannelGroupUsers(channelID string) ([]*model.User, *model.AppE
|
||||
func (a *App) GetUsersByIds(userIDs []string, options *store.UserGetByIdsOpts) ([]*model.User, *model.AppError) {
|
||||
allowFromCache := options.ViewRestrictions == nil
|
||||
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(userIDs, options, allowFromCache)
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, options, allowFromCache)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("GetUsersByIds", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
@@ -739,7 +740,7 @@ func (a *App) GenerateMfaSecret(userID string) (*model.MfaSecret, *model.AppErro
|
||||
}
|
||||
|
||||
func (a *App) ActivateMfa(userID, token string) *model.AppError {
|
||||
user, err := a.Srv().Store.User().Get(userID)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), userID)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -1212,7 +1213,7 @@ func (a *App) sendUpdatedUserEvent(user model.User) {
|
||||
}
|
||||
|
||||
func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) {
|
||||
prev, err := a.Srv().Store.User().Get(user.Id)
|
||||
prev, err := a.Srv().Store.User().Get(context.Background(), user.Id)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -2058,7 +2059,7 @@ func (a *App) FilterNonGroupChannelMembers(userIDs []string, channel *model.Chan
|
||||
// and returns the list of normal users present in userIDs but not in groupUsers.
|
||||
func (a *App) filterNonGroupUsers(userIDs []string, groupUsers []*model.User) ([]string, error) {
|
||||
nonMemberIds := []string{}
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(userIDs, nil, false)
|
||||
users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, nil, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2223,19 +2224,14 @@ func (a *App) PromoteGuestToUser(user *model.User, requestorId string) *model.Ap
|
||||
// DemoteUserToGuest Convert user's roles and all his mermbership's roles from
|
||||
// regular user roles to guest roles.
|
||||
func (a *App) DemoteUserToGuest(user *model.User) *model.AppError {
|
||||
nErr := a.Srv().Store.User().DemoteUserToGuest(user.Id)
|
||||
demotedUser, nErr := a.Srv().Store.User().DemoteUserToGuest(user.Id)
|
||||
a.InvalidateCacheForUser(user.Id)
|
||||
if nErr != nil {
|
||||
return model.NewAppError("DemoteUserToGuest", "app.user.demote_user_to_guest.user_update.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
demotedUser, err := a.GetUser(user.Id)
|
||||
if err != nil {
|
||||
mlog.Warn("Failed to get user on demote user to guest", mlog.Err(err))
|
||||
} else {
|
||||
a.sendUpdatedUserEvent(*demotedUser)
|
||||
a.UpdateSessionsIsGuest(demotedUser.Id, demotedUser.IsGuest())
|
||||
}
|
||||
a.sendUpdatedUserEvent(*demotedUser)
|
||||
a.UpdateSessionsIsGuest(demotedUser.Id, demotedUser.IsGuest())
|
||||
|
||||
teamMembers, err := a.GetTeamMembersForUser(user.Id)
|
||||
if err != nil {
|
||||
@@ -2248,6 +2244,7 @@ func (a *App) DemoteUserToGuest(user *model.User) *model.AppError {
|
||||
channelMembers, err := a.GetChannelMembersForUser(member.TeamId, user.Id)
|
||||
if err != nil {
|
||||
mlog.Warn("Failed to get channel members for users on demote user to guest", mlog.Err(err))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, member := range *channelMembers {
|
||||
@@ -2260,7 +2257,6 @@ func (a *App) DemoteUserToGuest(user *model.User) *model.AppError {
|
||||
}
|
||||
|
||||
a.ClearSessionCacheForUser(user.Id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2308,7 +2304,7 @@ func (a *App) GetKnownUsers(userID string) ([]string, *model.AppError) {
|
||||
|
||||
// ConvertBotToUser converts a bot to user.
|
||||
func (a *App) ConvertBotToUser(bot *model.Bot, userPatch *model.UserPatch, sysadmin bool) (*model.User, *model.AppError) {
|
||||
user, nErr := a.Srv().Store.User().Get(bot.UserId)
|
||||
user, nErr := a.Srv().Store.User().Get(context.Background(), bot.UserId)
|
||||
if nErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -674,7 +675,7 @@ func (a *App) HandleIncomingWebhook(hookID string, req *model.IncomingWebhookReq
|
||||
|
||||
uchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
user, err := a.Srv().Store.User().Get(hook.UserId)
|
||||
user, err := a.Srv().Store.User().Get(context.Background(), hook.UserId)
|
||||
uchan <- store.StoreResult{Data: user, NErr: err}
|
||||
close(uchan)
|
||||
}()
|
||||
|
||||
Ссылка в новой задаче
Block a user