Depublishing some app layer methods (#29559)

* Depublishing some app layer methods

* Fixing errors

* Addressing PR review comment

* Using goimports formatting now
Этот коммит содержится в:
Jesús Espino
2024-12-12 20:15:38 +01:00
коммит произвёл GitHub
родитель c19e0ea0e7
Коммит 31351a48b0
17 изменённых файлов: 136 добавлений и 150 удалений

Просмотреть файл

@@ -75,11 +75,11 @@ func (s *Server) QueryLogs(rctx request.CTX, page, perPage int, logFilter *model
if len(serverNames) > 0 { if len(serverNames) > 0 {
for _, nodeName := range serverNames { for _, nodeName := range serverNames {
if nodeName == "default" { if nodeName == "default" {
appErr = AddLocalLogs(rctx, logData, s, page, perPage, nodeName, logFilter) appErr = addLocalLogs(rctx, logData, s, page, perPage, nodeName, logFilter)
} }
} }
} else { } else {
appErr = AddLocalLogs(rctx, logData, s, page, perPage, serverName, logFilter) appErr = addLocalLogs(rctx, logData, s, page, perPage, serverName, logFilter)
} }
if appErr != nil { if appErr != nil {
return nil, appErr return nil, appErr
@@ -105,7 +105,7 @@ func (s *Server) QueryLogs(rctx request.CTX, page, perPage int, logFilter *model
return logData, nil return logData, nil
} }
func AddLocalLogs(rctx request.CTX, logData map[string][]string, s *Server, page, perPage int, serverName string, logFilter *model.LogFilter) *model.AppError { func addLocalLogs(rctx request.CTX, logData map[string][]string, s *Server, page, perPage int, serverName string, logFilter *model.LogFilter) *model.AppError {
currentServerLogs, err := s.GetLogsSkipSend(rctx, page, perPage, logFilter) currentServerLogs, err := s.GetLogsSkipSend(rctx, page, perPage, logFilter)
if err != nil { if err != nil {
return err return err

Просмотреть файл

@@ -1245,7 +1245,7 @@ func (a *App) UpdateChannelMemberSchemeRoles(c request.CTX, channelID string, us
// If the migration is not completed, we also need to check the default channel_admin/channel_user roles are not present in the roles field. // If the migration is not completed, we also need to check the default channel_admin/channel_user roles are not present in the roles field.
if err = a.IsPhase2MigrationCompleted(); err != nil { if err = a.IsPhase2MigrationCompleted(); err != nil {
member.ExplicitRoles = RemoveRoles([]string{model.ChannelGuestRoleId, model.ChannelUserRoleId, model.ChannelAdminRoleId}, member.ExplicitRoles) member.ExplicitRoles = removeRoles([]string{model.ChannelGuestRoleId, model.ChannelUserRoleId, model.ChannelAdminRoleId}, member.ExplicitRoles)
} }
return a.updateChannelMember(c, member) return a.updateChannelMember(c, member)
@@ -3585,7 +3585,7 @@ func (a *App) GetGroupMessageMembersCommonTeams(c request.CTX, channelID string)
Active: true, Active: true,
}) })
var userIDs = make([]string, len(users)) userIDs := make([]string, len(users))
for i := 0; i < len(users); i++ { for i := 0; i < len(users); i++ {
userIDs[i] = users[i].Id userIDs[i] = users[i].Id
} }

Просмотреть файл

@@ -302,7 +302,7 @@ func (a *App) exportRoles(ctx request.CTX, job *model.Job, writer io.Writer, sch
for _, role := range allRoles { for _, role := range allRoles {
// We skip any roles that will be included as part of custom schemes. // We skip any roles that will be included as part of custom schemes.
if !schemeRoles[role.Name] { if !schemeRoles[role.Name] {
if err := a.exportWriteLine(writer, ImportLineFromRole(role)); err != nil { if err := a.exportWriteLine(writer, importLineFromRole(role)); err != nil {
return err return err
} }
cnt++ cnt++
@@ -354,7 +354,7 @@ func (a *App) exportSchemes(ctx request.CTX, job *model.Job, writer io.Writer, s
schemeRolesMap[scheme.DefaultChannelGuestRole] = true schemeRolesMap[scheme.DefaultChannelGuestRole] = true
} }
if err := a.exportWriteLine(writer, ImportLineFromScheme(scheme, rolesMap)); err != nil { if err := a.exportWriteLine(writer, importLineFromScheme(scheme, rolesMap)); err != nil {
return err return err
} }
} }
@@ -394,7 +394,7 @@ func (a *App) exportAllTeams(ctx request.CTX, job *model.Job, writer io.Writer)
} }
teamNames[team.Name] = true teamNames[team.Name] = true
teamLine := ImportLineFromTeam(team) teamLine := importLineFromTeam(team)
if err := a.exportWriteLine(writer, teamLine); err != nil { if err := a.exportWriteLine(writer, teamLine); err != nil {
return nil, err return nil, err
} }
@@ -409,7 +409,6 @@ func (a *App) exportAllChannels(ctx request.CTX, job *model.Job, writer io.Write
cnt := 0 cnt := 0
for { for {
channels, err := a.Srv().Store().Channel().GetAllChannelsForExportAfter(1000, afterId) channels, err := a.Srv().Store().Channel().GetAllChannelsForExportAfter(1000, afterId)
if err != nil { if err != nil {
return model.NewAppError("exportAllChannels", "app.channel.get_all.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return model.NewAppError("exportAllChannels", "app.channel.get_all.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
@@ -432,7 +431,7 @@ func (a *App) exportAllChannels(ctx request.CTX, job *model.Job, writer io.Write
continue continue
} }
channelLine := ImportLineFromChannel(channel) channelLine := importLineFromChannel(channel)
if err := a.exportWriteLine(writer, channelLine); err != nil { if err := a.exportWriteLine(writer, channelLine); err != nil {
return err return err
} }
@@ -448,7 +447,6 @@ func (a *App) exportAllUsers(ctx request.CTX, job *model.Job, writer io.Writer,
profilePictures := []string{} profilePictures := []string{}
for { for {
users, err := a.Srv().Store().User().GetAllAfter(1000, afterId) users, err := a.Srv().Store().User().GetAllAfter(1000, afterId)
if err != nil { if err != nil {
return profilePictures, model.NewAppError("exportAllUsers", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return profilePictures, model.NewAppError("exportAllUsers", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
@@ -467,7 +465,7 @@ func (a *App) exportAllUsers(ctx request.CTX, job *model.Job, writer io.Writer,
continue continue
} }
// Gathering here the exportable preferences to pass them on to ImportLineFromUser // Gathering here the exportable preferences to pass them on to importLineFromUser
exportedPrefs := make(map[string]*string) exportedPrefs := make(map[string]*string)
allPrefs, err := a.GetPreferencesForUser(ctx, user.Id) allPrefs, err := a.GetPreferencesForUser(ctx, user.Id)
if err != nil { if err != nil {
@@ -505,7 +503,7 @@ func (a *App) exportAllUsers(ctx request.CTX, job *model.Job, writer io.Writer,
} }
} }
userLine := ImportLineFromUser(user, exportedPrefs) userLine := importLineFromUser(user, exportedPrefs)
if includeProfilePictures { if includeProfilePictures {
var pp string var pp string
@@ -575,7 +573,7 @@ func (a *App) exportAllBots(ctx request.CTX, job *model.Job, writer io.Writer, i
ownerUsername = owner.Username ownerUsername = owner.Username
} }
botLine := ImportLineFromBot(bot, ownerUsername) botLine := importLineFromBot(bot, ownerUsername)
if includeProfilePictures { if includeProfilePictures {
pp, err := a.GetProfileImagePath(model.UserFromBot(bot)) pp, err := a.GetProfileImagePath(model.UserFromBot(bot))
@@ -605,7 +603,6 @@ func (a *App) buildUserTeamAndChannelMemberships(c request.CTX, userID string, i
var memberships []imports.UserTeamImportData var memberships []imports.UserTeamImportData
members, err := a.Srv().Store().Team().GetTeamMembersForExport(userID) members, err := a.Srv().Store().Team().GetTeamMembersForExport(userID)
if err != nil { if err != nil {
return nil, model.NewAppError("buildUserTeamAndChannelMemberships", "app.team.get_members.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return nil, model.NewAppError("buildUserTeamAndChannelMemberships", "app.team.get_members.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
@@ -616,7 +613,7 @@ func (a *App) buildUserTeamAndChannelMemberships(c request.CTX, userID string, i
continue continue
} }
memberData := ImportUserTeamDataFromTeamMember(member) memberData := importUserTeamDataFromTeamMember(member)
// Do the Channel Memberships. // Do the Channel Memberships.
channelMembers, err := a.buildUserChannelMemberships(c, userID, member.TeamId, includeArchivedChannels) channelMembers, err := a.buildUserChannelMemberships(c, userID, member.TeamId, includeArchivedChannels)
@@ -652,7 +649,7 @@ func (a *App) buildUserChannelMemberships(c request.CTX, userID string, teamID s
memberships := make([]imports.UserChannelImportData, len(members)) memberships := make([]imports.UserChannelImportData, len(members))
for i, member := range members { for i, member := range members {
memberships[i] = *ImportUserChannelDataFromChannelMemberAndPreferences(member, &preferences) memberships[i] = *importUserChannelDataFromChannelMemberAndPreferences(member, &preferences)
} }
return &memberships, nil return &memberships, nil
} }
@@ -710,7 +707,7 @@ func (a *App) exportAllPosts(ctx request.CTX, job *model.Job, writer io.Writer,
continue continue
} }
postLine := ImportLineForPost(post) postLine := importLineForPost(post)
replies, replyAttachments, err := a.buildPostReplies(ctx, post.Id, withAttachments) replies, replyAttachments, err := a.buildPostReplies(ctx, post.Id, withAttachments)
if err != nil { if err != nil {
@@ -768,7 +765,7 @@ func (a *App) buildPostReplies(ctx request.CTX, postID string, withAttachments b
} }
for _, reply := range replyPosts { for _, reply := range replyPosts {
replyImportObject := ImportReplyFromPost(reply) replyImportObject := importReplyFromPost(reply)
if reply.HasReactions { if reply.HasReactions {
var appErr *model.AppError var appErr *model.AppError
replyImportObject.Reactions, appErr = a.BuildPostReactions(ctx, reply.Id) replyImportObject.Reactions, appErr = a.BuildPostReactions(ctx, reply.Id)
@@ -802,7 +799,7 @@ func (a *App) buildThreadFollowers(_ request.CTX, postID string) ([]imports.Thre
} }
for _, member := range threadFollowers { for _, member := range threadFollowers {
followers = append(followers, *ImportFollowerFromThreadMember(member)) followers = append(followers, *importFollowerFromThreadMember(member))
} }
return followers, nil return followers, nil
@@ -826,7 +823,7 @@ func (a *App) BuildPostReactions(ctx request.CTX, postID string) (*[]ReactionImp
} }
return nil, model.NewAppError("BuildPostReactions", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return nil, model.NewAppError("BuildPostReactions", "app.user.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
reactionsOfPost = append(reactionsOfPost, *ImportReactionFromPost(user, reaction)) reactionsOfPost = append(reactionsOfPost, *importReactionFromPost(user, reaction))
} }
return &reactionsOfPost, nil return &reactionsOfPost, nil
@@ -852,7 +849,6 @@ func (a *App) exportCustomEmoji(c request.CTX, job *model.Job, writer io.Writer,
cnt := 0 cnt := 0
for { for {
customEmojiList, err := a.GetEmojiList(c, pageNumber, 100, model.EmojiSortByName) customEmojiList, err := a.GetEmojiList(c, pageNumber, 100, model.EmojiSortByName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -886,7 +882,7 @@ func (a *App) exportCustomEmoji(c request.CTX, job *model.Job, writer io.Writer,
emojiPaths = append(emojiPaths, filePath) emojiPaths = append(emojiPaths, filePath)
} }
emojiImportObject := ImportLineFromEmoji(emoji, filePath) emojiImportObject := importLineFromEmoji(emoji, filePath)
if err := a.exportWriteLine(writer, emojiImportObject); err != nil { if err := a.exportWriteLine(writer, emojiImportObject); err != nil {
return nil, err return nil, err
} }
@@ -968,7 +964,7 @@ func (a *App) exportAllDirectChannels(ctx request.CTX, job *model.Job, writer io
return err return err
} }
channelLine := ImportLineFromDirectChannel(channel, favoritedBy, shownBy) channelLine := importLineFromDirectChannel(channel, favoritedBy, shownBy)
if err := a.exportWriteLine(writer, channelLine); err != nil { if err := a.exportWriteLine(writer, channelLine); err != nil {
return err return err
} }
@@ -1107,7 +1103,7 @@ func (a *App) exportAllDirectPosts(ctx request.CTX, job *model.Job, writer io.Wr
attachments = append(attachments, replyAttachments...) attachments = append(attachments, replyAttachments...)
} }
postLine := ImportLineForDirectPost(post) postLine := importLineForDirectPost(post)
postLine.DirectPost.Replies = &replies postLine.DirectPost.Replies = &replies
if len(postAttachments) > 0 { if len(postAttachments) > 0 {
postLine.DirectPost.Attachments = &postAttachments postLine.DirectPost.Attachments = &postAttachments

Просмотреть файл

@@ -10,7 +10,7 @@ import (
"github.com/mattermost/mattermost/server/v8/channels/app/imports" "github.com/mattermost/mattermost/server/v8/channels/app/imports"
) )
func ImportLineFromTeam(team *model.TeamForExport) *imports.LineImportData { func importLineFromTeam(team *model.TeamForExport) *imports.LineImportData {
return &imports.LineImportData{ return &imports.LineImportData{
Type: "team", Type: "team",
Team: &imports.TeamImportData{ Team: &imports.TeamImportData{
@@ -24,7 +24,7 @@ func ImportLineFromTeam(team *model.TeamForExport) *imports.LineImportData {
} }
} }
func ImportLineFromChannel(channel *model.ChannelForExport) *imports.LineImportData { func importLineFromChannel(channel *model.ChannelForExport) *imports.LineImportData {
return &imports.LineImportData{ return &imports.LineImportData{
Type: "channel", Type: "channel",
Channel: &imports.ChannelImportData{ Channel: &imports.ChannelImportData{
@@ -40,7 +40,7 @@ func ImportLineFromChannel(channel *model.ChannelForExport) *imports.LineImportD
} }
} }
func ImportLineFromDirectChannel(channel *model.DirectChannelForExport, favoritedBy, shownBy []string) *imports.LineImportData { func importLineFromDirectChannel(channel *model.DirectChannelForExport, favoritedBy, shownBy []string) *imports.LineImportData {
channelMembers := channel.Members channelMembers := channel.Members
if len(channelMembers) == 1 { if len(channelMembers) == 1 {
channelMembers = []*model.ChannelMemberForExport{channelMembers[0], channelMembers[0]} channelMembers = []*model.ChannelMemberForExport{channelMembers[0], channelMembers[0]}
@@ -134,7 +134,7 @@ func importDirectChannelMembersFromChannelMembers(members []*model.ChannelMember
return importedMembers return importedMembers
} }
func ImportLineFromUser(user *model.User, exportedPrefs map[string]*string) *imports.LineImportData { func importLineFromUser(user *model.User, exportedPrefs map[string]*string) *imports.LineImportData {
// Bulk Importer doesn't accept "empty string" for AuthService. // Bulk Importer doesn't accept "empty string" for AuthService.
var authService *string var authService *string
if user.AuthService != "" { if user.AuthService != "" {
@@ -177,7 +177,7 @@ func ImportLineFromUser(user *model.User, exportedPrefs map[string]*string) *imp
} }
} }
func ImportLineFromBot(bot *model.Bot, ownerUsername string) *imports.LineImportData { func importLineFromBot(bot *model.Bot, ownerUsername string) *imports.LineImportData {
return &imports.LineImportData{ return &imports.LineImportData{
Type: "bot", Type: "bot",
Bot: &imports.BotImportData{ Bot: &imports.BotImportData{
@@ -190,7 +190,7 @@ func ImportLineFromBot(bot *model.Bot, ownerUsername string) *imports.LineImport
} }
} }
func ImportUserTeamDataFromTeamMember(member *model.TeamMemberForExport) *imports.UserTeamImportData { func importUserTeamDataFromTeamMember(member *model.TeamMemberForExport) *imports.UserTeamImportData {
rolesList := strings.Fields(member.Roles) rolesList := strings.Fields(member.Roles)
if member.SchemeAdmin { if member.SchemeAdmin {
rolesList = append(rolesList, model.TeamAdminRoleId) rolesList = append(rolesList, model.TeamAdminRoleId)
@@ -208,7 +208,7 @@ func ImportUserTeamDataFromTeamMember(member *model.TeamMemberForExport) *import
} }
} }
func ImportUserChannelDataFromChannelMemberAndPreferences(member *model.ChannelMemberForExport, preferences *model.Preferences) *imports.UserChannelImportData { func importUserChannelDataFromChannelMemberAndPreferences(member *model.ChannelMemberForExport, preferences *model.Preferences) *imports.UserChannelImportData {
rolesList := strings.Fields(member.Roles) rolesList := strings.Fields(member.Roles)
if member.SchemeAdmin { if member.SchemeAdmin {
rolesList = append(rolesList, model.ChannelAdminRoleId) rolesList = append(rolesList, model.ChannelAdminRoleId)
@@ -257,7 +257,7 @@ func ImportUserChannelDataFromChannelMemberAndPreferences(member *model.ChannelM
} }
} }
func ImportLineForPost(post *model.PostForExport) *imports.LineImportData { func importLineForPost(post *model.PostForExport) *imports.LineImportData {
f := []string(post.FlaggedBy) f := []string(post.FlaggedBy)
return &imports.LineImportData{ return &imports.LineImportData{
Type: "post", Type: "post",
@@ -276,7 +276,7 @@ func ImportLineForPost(post *model.PostForExport) *imports.LineImportData {
} }
} }
func ImportLineForDirectPost(post *model.DirectPostForExport) *imports.LineImportData { func importLineForDirectPost(post *model.DirectPostForExport) *imports.LineImportData {
channelMembers := *post.ChannelMembers channelMembers := *post.ChannelMembers
if len(channelMembers) == 1 { if len(channelMembers) == 1 {
channelMembers = []string{channelMembers[0], channelMembers[0]} channelMembers = []string{channelMembers[0], channelMembers[0]}
@@ -298,7 +298,7 @@ func ImportLineForDirectPost(post *model.DirectPostForExport) *imports.LineImpor
} }
} }
func ImportReplyFromPost(post *model.ReplyForExport) *imports.ReplyImportData { func importReplyFromPost(post *model.ReplyForExport) *imports.ReplyImportData {
f := []string(post.FlaggedBy) f := []string(post.FlaggedBy)
return &imports.ReplyImportData{ return &imports.ReplyImportData{
User: &post.Username, User: &post.Username,
@@ -311,7 +311,7 @@ func ImportReplyFromPost(post *model.ReplyForExport) *imports.ReplyImportData {
} }
} }
func ImportReactionFromPost(user *model.User, reaction *model.Reaction) *imports.ReactionImportData { func importReactionFromPost(user *model.User, reaction *model.Reaction) *imports.ReactionImportData {
return &imports.ReactionImportData{ return &imports.ReactionImportData{
User: &user.Username, User: &user.Username,
EmojiName: &reaction.EmojiName, EmojiName: &reaction.EmojiName,
@@ -319,7 +319,7 @@ func ImportReactionFromPost(user *model.User, reaction *model.Reaction) *imports
} }
} }
func ImportLineFromEmoji(emoji *model.Emoji, filePath string) *imports.LineImportData { func importLineFromEmoji(emoji *model.Emoji, filePath string) *imports.LineImportData {
return &imports.LineImportData{ return &imports.LineImportData{
Type: "emoji", Type: "emoji",
Emoji: &imports.EmojiImportData{ Emoji: &imports.EmojiImportData{
@@ -329,7 +329,7 @@ func ImportLineFromEmoji(emoji *model.Emoji, filePath string) *imports.LineImpor
} }
} }
func ImportRoleDataFromRole(role *model.Role) *imports.RoleImportData { func importRoleDataFromRole(role *model.Role) *imports.RoleImportData {
return &imports.RoleImportData{ return &imports.RoleImportData{
Name: &role.Name, Name: &role.Name,
DisplayName: &role.DisplayName, DisplayName: &role.DisplayName,
@@ -339,14 +339,14 @@ func ImportRoleDataFromRole(role *model.Role) *imports.RoleImportData {
} }
} }
func ImportLineFromRole(role *model.Role) *imports.LineImportData { func importLineFromRole(role *model.Role) *imports.LineImportData {
return &imports.LineImportData{ return &imports.LineImportData{
Type: "role", Type: "role",
Role: ImportRoleDataFromRole(role), Role: importRoleDataFromRole(role),
} }
} }
func ImportLineFromScheme(scheme *model.Scheme, rolesMap map[string]*model.Role) *imports.LineImportData { func importLineFromScheme(scheme *model.Scheme, rolesMap map[string]*model.Role) *imports.LineImportData {
data := &imports.SchemeImportData{ data := &imports.SchemeImportData{
Name: &scheme.Name, Name: &scheme.Name,
DisplayName: &scheme.DisplayName, DisplayName: &scheme.DisplayName,
@@ -355,15 +355,15 @@ func ImportLineFromScheme(scheme *model.Scheme, rolesMap map[string]*model.Role)
} }
if scheme.Scope == model.SchemeScopeTeam { if scheme.Scope == model.SchemeScopeTeam {
data.DefaultTeamAdminRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultTeamAdminRole]) data.DefaultTeamAdminRole = importRoleDataFromRole(rolesMap[scheme.DefaultTeamAdminRole])
data.DefaultTeamUserRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultTeamUserRole]) data.DefaultTeamUserRole = importRoleDataFromRole(rolesMap[scheme.DefaultTeamUserRole])
data.DefaultTeamGuestRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultTeamGuestRole]) data.DefaultTeamGuestRole = importRoleDataFromRole(rolesMap[scheme.DefaultTeamGuestRole])
} }
if scheme.Scope == model.SchemeScopeTeam || scheme.Scope == model.SchemeScopeChannel { if scheme.Scope == model.SchemeScopeTeam || scheme.Scope == model.SchemeScopeChannel {
data.DefaultChannelAdminRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultChannelAdminRole]) data.DefaultChannelAdminRole = importRoleDataFromRole(rolesMap[scheme.DefaultChannelAdminRole])
data.DefaultChannelUserRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultChannelUserRole]) data.DefaultChannelUserRole = importRoleDataFromRole(rolesMap[scheme.DefaultChannelUserRole])
data.DefaultChannelGuestRole = ImportRoleDataFromRole(rolesMap[scheme.DefaultChannelGuestRole]) data.DefaultChannelGuestRole = importRoleDataFromRole(rolesMap[scheme.DefaultChannelGuestRole])
} }
return &imports.LineImportData{ return &imports.LineImportData{
@@ -372,7 +372,7 @@ func ImportLineFromScheme(scheme *model.Scheme, rolesMap map[string]*model.Role)
} }
} }
func ImportFollowerFromThreadMember(threadMember *model.ThreadMembershipForExport) *imports.ThreadFollowerImportData { func importFollowerFromThreadMember(threadMember *model.ThreadMembershipForExport) *imports.ThreadFollowerImportData {
return &imports.ThreadFollowerImportData{ return &imports.ThreadFollowerImportData{
User: &threadMember.Username, User: &threadMember.Username,
LastViewed: &threadMember.LastViewed, LastViewed: &threadMember.LastViewed,

Просмотреть файл

@@ -399,8 +399,10 @@ func (a *App) findTeamIdForFilename(rctx request.CTX, post *model.Post, id, file
return "" return ""
} }
var fileMigrationLock sync.Mutex var (
var oldFilenameMatchExp = regexp.MustCompile(`^\/([a-z\d]{26})\/([a-z\d]{26})\/([a-z\d]{26})\/([^\/]+)$`) fileMigrationLock sync.Mutex
oldFilenameMatchExp = regexp.MustCompile(`^\/([a-z\d]{26})\/([a-z\d]{26})\/([a-z\d]{26})\/([^\/]+)$`)
)
// Parse the path from the Filename of the form /{channelID}/{userID}/{uid}/{nameWithExtension} // Parse the path from the Filename of the form /{channelID}/{userID}/{uid}/{nameWithExtension}
func parseOldFilenames(rctx request.CTX, filenames []string, channelID, userID string) [][]string { func parseOldFilenames(rctx request.CTX, filenames []string, channelID, userID string) [][]string {
@@ -1397,7 +1399,6 @@ func populateZipfile(w *zip.Writer, fileDatas []model.FileData) error {
Method: zip.Deflate, Method: zip.Deflate,
Modified: time.Now(), Modified: time.Now(),
}) })
if err != nil { if err != nil {
return err return err
} }

Просмотреть файл

@@ -55,7 +55,7 @@ func (a *App) AuthenticateUserForLogin(c request.CTX, id, loginId, password, mfa
} }
}() }()
if password == "" && !IsCWSLogin(a, cwsToken) { if password == "" && !isCWSLogin(a, cwsToken) {
return nil, model.NewAppError("AuthenticateUserForLogin", "api.user.login.blank_pwd.app_error", nil, "", http.StatusBadRequest) return nil, model.NewAppError("AuthenticateUserForLogin", "api.user.login.blank_pwd.app_error", nil, "", http.StatusBadRequest)
} }
@@ -66,7 +66,7 @@ func (a *App) AuthenticateUserForLogin(c request.CTX, id, loginId, password, mfa
// CWS login allow to use the one-time token to login the users when they're redirected to their // CWS login allow to use the one-time token to login the users when they're redirected to their
// installation for the first time // installation for the first time
if IsCWSLogin(a, cwsToken) { if isCWSLogin(a, cwsToken) {
if err = checkUserNotBot(user); err != nil { if err = checkUserNotBot(user); err != nil {
return nil, err return nil, err
} }
@@ -349,6 +349,6 @@ func GetProtocol(r *http.Request) string {
return "http" return "http"
} }
func IsCWSLogin(a *App, token string) bool { func isCWSLogin(a *App, token string) bool {
return a.License().IsCloud() && token != "" return a.License().IsCloud() && token != ""
} }

Просмотреть файл

@@ -18,11 +18,11 @@ const (
// A MentionableID stores the ID of a single User/Group with information about which type of object it refers to. // A MentionableID stores the ID of a single User/Group with information about which type of object it refers to.
type MentionableID string type MentionableID string
func MentionableUserID(userID string) MentionableID { func mentionableUserID(userID string) MentionableID {
return MentionableID(fmt.Sprint(mentionableUserPrefix, userID)) return MentionableID(fmt.Sprint(mentionableUserPrefix, userID))
} }
func MentionableGroupID(groupID string) MentionableID { func mentionableGroupID(groupID string) MentionableID {
return MentionableID(fmt.Sprint(mentionableGroupPrefix, groupID)) return MentionableID(fmt.Sprint(mentionableGroupPrefix, groupID))
} }
@@ -48,7 +48,7 @@ func (id MentionableID) AsGroupID() (groupID string, ok bool) {
type MentionKeywords map[string][]MentionableID type MentionKeywords map[string][]MentionableID
func (k MentionKeywords) AddUser(profile *model.User, channelNotifyProps map[string]string, status *model.Status, allowChannelMentions bool) MentionKeywords { func (k MentionKeywords) AddUser(profile *model.User, channelNotifyProps map[string]string, status *model.Status, allowChannelMentions bool) MentionKeywords {
mentionableID := MentionableUserID(profile.Id) mentionableID := mentionableUserID(profile.Id)
userMention := "@" + strings.ToLower(profile.Username) userMention := "@" + strings.ToLower(profile.Username)
k[userMention] = append(k[userMention], mentionableID) k[userMention] = append(k[userMention], mentionableID)
@@ -87,7 +87,7 @@ func (k MentionKeywords) AddUser(profile *model.User, channelNotifyProps map[str
} }
func (k MentionKeywords) AddUserKeyword(userID string, keyword string) MentionKeywords { func (k MentionKeywords) AddUserKeyword(userID string, keyword string) MentionKeywords {
k[keyword] = append(k[keyword], MentionableUserID(userID)) k[keyword] = append(k[keyword], mentionableUserID(userID))
return k return k
} }
@@ -95,7 +95,7 @@ func (k MentionKeywords) AddUserKeyword(userID string, keyword string) MentionKe
func (k MentionKeywords) AddGroup(group *model.Group) MentionKeywords { func (k MentionKeywords) AddGroup(group *model.Group) MentionKeywords {
if group.Name != nil { if group.Name != nil {
keyword := "@" + *group.Name keyword := "@" + *group.Name
k[keyword] = append(k[keyword], MentionableGroupID(group.Id)) k[keyword] = append(k[keyword], mentionableGroupID(group.Id))
} }
return k return k

Просмотреть файл

@@ -15,13 +15,13 @@ func mapsToMentionKeywords(userKeywords map[string][]string, groups map[string]*
for keyword, ids := range userKeywords { for keyword, ids := range userKeywords {
for _, id := range ids { for _, id := range ids {
keywords[keyword] = append(keywords[keyword], MentionableUserID(id)) keywords[keyword] = append(keywords[keyword], mentionableUserID(id))
} }
} }
for _, group := range groups { for _, group := range groups {
keyword := "@" + *group.Name keyword := "@" + *group.Name
keywords[keyword] = append(keywords[keyword], MentionableGroupID(group.Id)) keywords[keyword] = append(keywords[keyword], mentionableGroupID(group.Id))
} }
return keywords return keywords
@@ -38,7 +38,7 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, nil, false) keywords.AddUser(user, channelNotifyProps, nil, false)
assert.Contains(t, keywords["@user"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@user"], mentionableUserID(user.Id))
}) })
t.Run("should add custom mention keywords", func(t *testing.T) { t.Run("should add custom mention keywords", func(t *testing.T) {
@@ -54,9 +54,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, nil, false) keywords.AddUser(user, channelNotifyProps, nil, false)
assert.Contains(t, keywords["apple"], MentionableUserID(user.Id)) assert.Contains(t, keywords["apple"], mentionableUserID(user.Id))
assert.Contains(t, keywords["banana"], MentionableUserID(user.Id)) assert.Contains(t, keywords["banana"], mentionableUserID(user.Id))
assert.Contains(t, keywords["orange"], MentionableUserID(user.Id)) assert.Contains(t, keywords["orange"], mentionableUserID(user.Id))
}) })
t.Run("should not add empty custom keywords", func(t *testing.T) { t.Run("should not add empty custom keywords", func(t *testing.T) {
@@ -90,9 +90,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, nil, false) keywords.AddUser(user, channelNotifyProps, nil, false)
assert.Contains(t, keywords["William"], MentionableUserID(user.Id)) assert.Contains(t, keywords["William"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["william"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["william"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["Robert"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["Robert"], mentionableUserID(user.Id))
}) })
t.Run("should not add case sensitive first name if enabled but empty First Name", func(t *testing.T) { t.Run("should not add case sensitive first name if enabled but empty First Name", func(t *testing.T) {
@@ -110,7 +110,7 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, nil, false) keywords.AddUser(user, channelNotifyProps, nil, false)
assert.NotContains(t, keywords[""], MentionableUserID(user.Id)) assert.NotContains(t, keywords[""], mentionableUserID(user.Id))
}) })
t.Run("should not add case sensitive first name if disabled", func(t *testing.T) { t.Run("should not add case sensitive first name if disabled", func(t *testing.T) {
@@ -128,9 +128,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, nil, false) keywords.AddUser(user, channelNotifyProps, nil, false)
assert.NotContains(t, keywords["William"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["William"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["william"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["william"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["Robert"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["Robert"], mentionableUserID(user.Id))
}) })
t.Run("should add @channel/@all/@here when allowed", func(t *testing.T) { t.Run("should add @channel/@all/@here when allowed", func(t *testing.T) {
@@ -149,9 +149,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, true) keywords.AddUser(user, channelNotifyProps, status, true)
assert.Contains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.Contains(t, keywords["@all"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@all"], mentionableUserID(user.Id))
assert.Contains(t, keywords["@here"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should not add @channel/@all/@here when not allowed", func(t *testing.T) { t.Run("should not add @channel/@all/@here when not allowed", func(t *testing.T) {
@@ -170,9 +170,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, false) keywords.AddUser(user, channelNotifyProps, status, false)
assert.NotContains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@all"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@all"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@here"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should not add @channel/@all/@here when disabled for user", func(t *testing.T) { t.Run("should not add @channel/@all/@here when disabled for user", func(t *testing.T) {
@@ -191,9 +191,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, true) keywords.AddUser(user, channelNotifyProps, status, true)
assert.NotContains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@all"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@all"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@here"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should not add @channel/@all/@here when disabled for channel", func(t *testing.T) { t.Run("should not add @channel/@all/@here when disabled for channel", func(t *testing.T) {
@@ -214,9 +214,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, true) keywords.AddUser(user, channelNotifyProps, status, true)
assert.NotContains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@all"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@all"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@here"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should not add @channel/@all/@here when channel is muted and channel mention setting is not updated by user", func(t *testing.T) { t.Run("should not add @channel/@all/@here when channel is muted and channel mention setting is not updated by user", func(t *testing.T) {
@@ -238,9 +238,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, true) keywords.AddUser(user, channelNotifyProps, status, true)
assert.NotContains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@all"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@all"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@here"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should not add @here when when user is not online", func(t *testing.T) { t.Run("should not add @here when when user is not online", func(t *testing.T) {
@@ -259,9 +259,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords := MentionKeywords{} keywords := MentionKeywords{}
keywords.AddUser(user, channelNotifyProps, status, true) keywords.AddUser(user, channelNotifyProps, status, true)
assert.Contains(t, keywords["@channel"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@channel"], mentionableUserID(user.Id))
assert.Contains(t, keywords["@all"], MentionableUserID(user.Id)) assert.Contains(t, keywords["@all"], mentionableUserID(user.Id))
assert.NotContains(t, keywords["@here"], MentionableUserID(user.Id)) assert.NotContains(t, keywords["@here"], mentionableUserID(user.Id))
}) })
t.Run("should add for multiple users", func(t *testing.T) { t.Run("should add for multiple users", func(t *testing.T) {
@@ -284,9 +284,9 @@ func TestMentionKeywords_AddUserProfile(t *testing.T) {
keywords.AddUser(user1, map[string]string{}, nil, true) keywords.AddUser(user1, map[string]string{}, nil, true)
keywords.AddUser(user2, map[string]string{}, nil, true) keywords.AddUser(user2, map[string]string{}, nil, true)
assert.Contains(t, keywords["@user1"], MentionableUserID(user1.Id)) assert.Contains(t, keywords["@user1"], mentionableUserID(user1.Id))
assert.Contains(t, keywords["@user2"], MentionableUserID(user2.Id)) assert.Contains(t, keywords["@user2"], mentionableUserID(user2.Id))
assert.Contains(t, keywords["@all"], MentionableUserID(user1.Id)) assert.Contains(t, keywords["@all"], mentionableUserID(user1.Id))
assert.Contains(t, keywords["@all"], MentionableUserID(user2.Id)) assert.Contains(t, keywords["@all"], mentionableUserID(user2.Id))
}) })
} }

Просмотреть файл

@@ -395,7 +395,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
continue continue
} }
//If email verification is required and user email is not verified don't send email. // If email verification is required and user email is not verified don't send email.
if *a.Config().EmailSettings.RequireEmailVerification && !profileMap[id].EmailVerified { if *a.Config().EmailSettings.RequireEmailVerification && !profileMap[id].EmailVerified {
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypeEmail, model.NotificationReasonEmailNotVerified, model.NotificationNoPlatform) a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypeEmail, model.NotificationReasonEmailNotVerified, model.NotificationNoPlatform)
a.NotificationsLog().Debug("Email not verified", a.NotificationsLog().Debug("Email not verified",
@@ -619,7 +619,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
status = &model.Status{UserId: id, Status: model.StatusOffline, Manual: false, LastActivityAt: 0, ActiveChannel: ""} status = &model.Status{UserId: id, Status: model.StatusOffline, Manual: false, LastActivityAt: 0, ActiveChannel: ""}
} }
if statusReason := DoesStatusAllowPushNotification(profileMap[id].NotifyProps, status, post.ChannelId, true); statusReason == "" { if statusReason := doesStatusAllowPushNotification(profileMap[id].NotifyProps, status, post.ChannelId, true); statusReason == "" {
a.sendPushNotification( a.sendPushNotification(
notification, notification,
profileMap[id], profileMap[id],
@@ -696,7 +696,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
userNotificationLevel := profile.NotifyProps[model.DesktopNotifyProp] userNotificationLevel := profile.NotifyProps[model.DesktopNotifyProp]
channelNotificationLevel := channelMemberNotifyPropsMap[id][model.DesktopNotifyProp] channelNotificationLevel := channelMemberNotifyPropsMap[id][model.DesktopNotifyProp]
if ShouldAckWebsocketNotification(channel.Type, userNotificationLevel, channelNotificationLevel) { if shouldAckWebsocketNotification(channel.Type, userNotificationLevel, channelNotificationLevel) {
usersToAck = append(usersToAck, id) usersToAck = append(usersToAck, id)
} }
} }
@@ -1755,7 +1755,7 @@ func shouldChannelMemberNotifyCRT(userNotifyProps model.StringMap, channelMember
return return
} }
func ShouldAckWebsocketNotification(channelType model.ChannelType, userNotificationLevel, channelNotificationLevel string) bool { func shouldAckWebsocketNotification(channelType model.ChannelType, userNotificationLevel, channelNotificationLevel string) bool {
if channelNotificationLevel == model.ChannelNotifyAll { if channelNotificationLevel == model.ChannelNotifyAll {
// Should ACK on if we notify for all messages in the channel // Should ACK on if we notify for all messages in the channel
return true return true

Просмотреть файл

@@ -68,7 +68,8 @@ type PushNotification struct {
} }
func (a *App) sendPushNotificationSync(c request.CTX, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string, func (a *App) sendPushNotificationSync(c request.CTX, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string,
explicitMention bool, channelWideMention bool, replyToThreadType string) *model.AppError { explicitMention bool, channelWideMention bool, replyToThreadType string,
) *model.AppError {
cfg := a.Config() cfg := a.Config()
msg, appErr := a.BuildPushNotificationMessage( msg, appErr := a.BuildPushNotificationMessage(
c, c,
@@ -169,7 +170,6 @@ func (a *App) sendPushNotificationToAllSessions(rctx request.CTX, msg *model.Pus
AckId: tmpMessage.AckId, AckId: tmpMessage.AckId,
DeviceId: tmpMessage.DeviceId, DeviceId: tmpMessage.DeviceId,
}).SignedString(a.AsymmetricSigningKey()) }).SignedString(a.AsymmetricSigningKey())
if err != nil { if err != nil {
a.NotificationsLog().Error("Notification error", a.NotificationsLog().Error("Notification error",
mlog.String("ackId", tmpMessage.AckId), mlog.String("ackId", tmpMessage.AckId),
@@ -256,7 +256,8 @@ func (a *App) sendPushNotification(notification *PostNotification, user *model.U
} }
func (a *App) getPushNotificationMessage(contentsConfig, postMessage string, explicitMention, channelWideMention, func (a *App) getPushNotificationMessage(contentsConfig, postMessage string, explicitMention, channelWideMention,
hasFiles bool, senderName string, channelType model.ChannelType, replyToThreadType string, userLocale i18n.TranslateFunc) string { hasFiles bool, senderName string, channelType model.ChannelType, replyToThreadType string, userLocale i18n.TranslateFunc,
) string {
// If the post only has images then push an appropriate message // If the post only has images then push an appropriate message
if postMessage == "" && hasFiles { if postMessage == "" && hasFiles {
if channelType == model.ChannelTypeDirect { if channelType == model.ChannelTypeDirect {
@@ -603,7 +604,7 @@ func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps mo
return true return true
} }
if notifyPropsAllowedReason := DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, wasMentioned, isGM); notifyPropsAllowedReason != "" { if notifyPropsAllowedReason := doesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, wasMentioned, isGM); notifyPropsAllowedReason != "" {
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, notifyPropsAllowedReason, model.NotificationNoPlatform) a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, notifyPropsAllowedReason, model.NotificationNoPlatform)
a.NotificationsLog().Debug("Notification not sent - notify props", a.NotificationsLog().Debug("Notification not sent - notify props",
mlog.String("type", model.NotificationTypePush), mlog.String("type", model.NotificationTypePush),
@@ -616,7 +617,7 @@ func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps mo
return false return false
} }
if statusAllowedReason := DoesStatusAllowPushNotification(user.NotifyProps, status, post.ChannelId, false); statusAllowedReason != "" { if statusAllowedReason := doesStatusAllowPushNotification(user.NotifyProps, status, post.ChannelId, false); statusAllowedReason != "" {
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, statusAllowedReason, model.NotificationNoPlatform) a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, statusAllowedReason, model.NotificationNoPlatform)
a.NotificationsLog().Debug("Notification not sent - status", a.NotificationsLog().Debug("Notification not sent - status",
mlog.String("type", model.NotificationTypePush), mlog.String("type", model.NotificationTypePush),
@@ -633,7 +634,7 @@ func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps mo
return true return true
} }
func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned, isGM bool) model.NotificationReason { func doesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned, isGM bool) model.NotificationReason {
userNotifyProps := user.NotifyProps userNotifyProps := user.NotifyProps
userNotify := userNotifyProps[model.PushNotifyProp] userNotify := userNotifyProps[model.PushNotifyProp]
channelNotify, ok := channelNotifyProps[model.PushNotifyProp] channelNotify, ok := channelNotifyProps[model.PushNotifyProp]
@@ -674,16 +675,16 @@ func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps m
return "" return ""
} }
func DoesStatusAllowPushNotification(userNotifyProps model.StringMap, status *model.Status, channelID string, isCRT bool) model.NotificationReason { func doesStatusAllowPushNotification(userNotifyProps model.StringMap, status *model.Status, channelID string, isCRT bool) model.NotificationReason {
// If User status is DND or OOO return false right away // If User status is DND or OOO return false right away
if status.Status == model.StatusDnd || status.Status == model.StatusOutOfOffice { if status.Status == model.StatusDnd || status.Status == model.StatusOutOfOffice {
return model.NotificationReasonUserStatus return model.NotificationReasonUserStatus
} }
pushStatus, ok := userNotifyProps[model.PushStatusNotifyProp] pushStatus, ok := userNotifyProps[model.PushStatusNotifyProp]
sendOnlineNotification := status.ActiveChannel != channelID || //We are in a different channel sendOnlineNotification := status.ActiveChannel != channelID || // We are in a different channel
model.GetMillis()-status.LastActivityAt > model.StatusChannelTimeout || //It has been a while since we were last active on this channel model.GetMillis()-status.LastActivityAt > model.StatusChannelTimeout || // It has been a while since we were last active on this channel
isCRT //Is CRT, so being active in a channel doesn't mean you are seeing thread activity isCRT // Is CRT, so being active in a channel doesn't mean you are seeing thread activity
if (pushStatus == model.StatusOnline || !ok) && sendOnlineNotification { if (pushStatus == model.StatusOnline || !ok) && sendOnlineNotification {
return "" return ""
@@ -701,7 +702,8 @@ func DoesStatusAllowPushNotification(userNotifyProps model.StringMap, status *mo
} }
func (a *App) BuildPushNotificationMessage(c request.CTX, contentsConfig string, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string, func (a *App) BuildPushNotificationMessage(c request.CTX, contentsConfig string, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string,
explicitMention bool, channelWideMention bool, replyToThreadType string) (*model.PushNotification, *model.AppError) { explicitMention bool, channelWideMention bool, replyToThreadType string,
) (*model.PushNotification, *model.AppError) {
var msg *model.PushNotification var msg *model.PushNotification
notificationInterface := a.ch.Notification notificationInterface := a.ch.Notification
@@ -795,7 +797,8 @@ func (a *App) buildIdLoadedPushNotificationMessage(c request.CTX, channel *model
} }
func (a *App) buildFullPushNotificationMessage(c request.CTX, contentsConfig string, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string, func (a *App) buildFullPushNotificationMessage(c request.CTX, contentsConfig string, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string,
explicitMention bool, channelWideMention bool, replyToThreadType string) *model.PushNotification { explicitMention bool, channelWideMention bool, replyToThreadType string,
) *model.PushNotification {
msg := &model.PushNotification{ msg := &model.PushNotification{
Category: model.CategoryCanReply, Category: model.CategoryCanReply,
Version: model.PushMessageV2, Version: model.PushMessageV2,

Просмотреть файл

@@ -425,7 +425,7 @@ func TestDoesNotifyPropsAllowPushNotification(t *testing.T) {
if tc.isMuted { if tc.isMuted {
channelNotifyProps[model.MarkUnreadNotifyProp] = model.ChannelMarkUnreadMention channelNotifyProps[model.MarkUnreadNotifyProp] = model.ChannelMarkUnreadMention
} }
assert.Equal(t, tc.expected, DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, tc.wasMentioned, tc.isGM)) assert.Equal(t, tc.expected, doesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, tc.wasMentioned, tc.isGM))
}) })
} }
} }
@@ -640,7 +640,7 @@ func TestDoesStatusAllowPushNotification(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
userNotifyProps := make(map[string]string) userNotifyProps := make(map[string]string)
userNotifyProps["push_status"] = tc.userNotifySetting userNotifyProps["push_status"] = tc.userNotifySetting
assert.Equal(t, tc.expected, DoesStatusAllowPushNotification(userNotifyProps, tc.status, tc.channelID, tc.isCRT)) assert.Equal(t, tc.expected, doesStatusAllowPushNotification(userNotifyProps, tc.status, tc.channelID, tc.isCRT))
}) })
} }
} }

Просмотреть файл

@@ -1624,7 +1624,7 @@ func TestGetMentionKeywords(t *testing.T) {
"mention_keys": "User,@User,MENTION", "mention_keys": "User,@User,MENTION",
}, },
} }
mentionableUser1ID := MentionableUserID(user1.Id) mentionableUser1ID := mentionableUserID(user1.Id)
channelMemberNotifyPropsMap1Off := map[string]model.StringMap{ channelMemberNotifyPropsMap1Off := map[string]model.StringMap{
user1.Id: { user1.Id: {
@@ -1655,7 +1655,7 @@ func TestGetMentionKeywords(t *testing.T) {
"first_name": "true", "first_name": "true",
}, },
} }
mentionableUser2ID := MentionableUserID(user2.Id) mentionableUser2ID := mentionableUserID(user2.Id)
channelMemberNotifyPropsMap2Off := map[string]model.StringMap{ channelMemberNotifyPropsMap2Off := map[string]model.StringMap{
user2.Id: { user2.Id: {
@@ -1680,7 +1680,7 @@ func TestGetMentionKeywords(t *testing.T) {
"channel": "true", "channel": "true",
}, },
} }
mentionableUser3ID := MentionableUserID(user3.Id) mentionableUser3ID := mentionableUserID(user3.Id)
// Channel-wide mentions are not ignored on channel level // Channel-wide mentions are not ignored on channel level
channelMemberNotifyPropsMap3Off := map[string]model.StringMap{ channelMemberNotifyPropsMap3Off := map[string]model.StringMap{
@@ -1746,7 +1746,7 @@ func TestGetMentionKeywords(t *testing.T) {
"channel": "true", "channel": "true",
}, },
} }
mentionableUser4ID := MentionableUserID(user4.Id) mentionableUser4ID := mentionableUserID(user4.Id)
// Channel-wide mentions are not ignored on channel level // Channel-wide mentions are not ignored on channel level
channelMemberNotifyPropsMap4Off := map[string]model.StringMap{ channelMemberNotifyPropsMap4Off := map[string]model.StringMap{
@@ -1933,7 +1933,7 @@ func TestGetMentionKeywords(t *testing.T) {
assert.Equal(t, 1, len(keywords), "should've returned one mention keyword") assert.Equal(t, 1, len(keywords), "should've returned one mention keyword")
ids, ok = keywords["@user"] ids, ok = keywords["@user"]
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, MentionableUserID(userNoMentionKeys.Id), ids[0], "should've returned mention key of @user") assert.Equal(t, mentionableUserID(userNoMentionKeys.Id), ids[0], "should've returned mention key of @user")
} }
func TestGetMentionKeywords_Groups(t *testing.T) { func TestGetMentionKeywords_Groups(t *testing.T) {
@@ -1942,8 +1942,8 @@ func TestGetMentionKeywords_Groups(t *testing.T) {
userID1 := model.NewId() userID1 := model.NewId()
userID2 := model.NewId() userID2 := model.NewId()
mentionableUserID1 := MentionableUserID(userID1) mentionableUserID1 := mentionableUserID(userID1)
mentionableUserID2 := MentionableUserID(userID2) mentionableUserID2 := mentionableUserID(userID2)
for name, tc := range map[string]struct { for name, tc := range map[string]struct {
Profiles map[string]*model.User Profiles map[string]*model.User
@@ -3094,13 +3094,13 @@ func TestRemoveNotifications(t *testing.T) {
func TestShouldAckWebsocketNotification(t *testing.T) { func TestShouldAckWebsocketNotification(t *testing.T) {
t.Run("should return true if channel notify level is ALL", func(t *testing.T) { t.Run("should return true if channel notify level is ALL", func(t *testing.T) {
assert.True(t, ShouldAckWebsocketNotification(model.ChannelTypeOpen, model.UserNotifyNone, model.ChannelNotifyAll)) assert.True(t, shouldAckWebsocketNotification(model.ChannelTypeOpen, model.UserNotifyNone, model.ChannelNotifyAll))
}) })
t.Run("should return true if user notify level is ALL and the channel is unchanged", func(t *testing.T) { t.Run("should return true if user notify level is ALL and the channel is unchanged", func(t *testing.T) {
assert.True(t, ShouldAckWebsocketNotification(model.ChannelTypeOpen, model.UserNotifyAll, model.ChannelNotifyDefault)) assert.True(t, shouldAckWebsocketNotification(model.ChannelTypeOpen, model.UserNotifyAll, model.ChannelNotifyDefault))
}) })
t.Run("should return true if its a group channel, and the level is mention", func(t *testing.T) { t.Run("should return true if its a group channel, and the level is mention", func(t *testing.T) {
assert.True(t, ShouldAckWebsocketNotification(model.ChannelTypeGroup, model.UserNotifyMention, model.ChannelNotifyDefault)) assert.True(t, shouldAckWebsocketNotification(model.ChannelTypeGroup, model.UserNotifyMention, model.ChannelNotifyDefault))
assert.True(t, ShouldAckWebsocketNotification(model.ChannelTypeGroup, model.UserNotifyNone, model.ChannelNotifyMention)) assert.True(t, shouldAckWebsocketNotification(model.ChannelTypeGroup, model.UserNotifyNone, model.ChannelNotifyMention))
}) })
} }

Просмотреть файл

@@ -271,7 +271,7 @@ func (a *App) sendUpdatedRoleEvent(role *model.Role) *model.AppError {
return nil return nil
} }
func RemoveRoles(rolesToRemove []string, roles string) string { func removeRoles(rolesToRemove []string, roles string) string {
roleList := strings.Fields(roles) roleList := strings.Fields(roles)
newRoles := make([]string, 0) newRoles := make([]string, 0)

Просмотреть файл

@@ -1366,7 +1366,6 @@ func (s *Server) doReportUserCountForCloudSubscriptionJob() {
appInstance := New(ServerConnector(s.Channels())) appInstance := New(ServerConnector(s.Channels()))
_, err := appInstance.SendSubscriptionHistoryEvent("") _, err := appInstance.SendSubscriptionHistoryEvent("")
if err != nil { if err != nil {
mlog.Error("an error occurred during daily user count reporting", mlog.Err(err)) mlog.Error("an error occurred during daily user count reporting", mlog.Err(err))
} }
@@ -1415,7 +1414,7 @@ func (s *Server) doLicenseExpirationCheck() {
return return
} }
//send email to admin(s) // send email to admin(s)
for _, user := range users { for _, user := range users {
user := user user := user
if user.Email == "" { if user.Email == "" {
@@ -1435,7 +1434,7 @@ func (s *Server) doLicenseExpirationCheck() {
}) })
} }
//remove the license // remove the license
s.RemoveLicense() s.RemoveLicense()
} }
@@ -1461,10 +1460,6 @@ func (s *Server) TotalWebsocketConnections() int {
return s.Platform().TotalWebsocketConnections() return s.Platform().TotalWebsocketConnections()
} }
func (s *Server) ClusterHealthScore() int {
return s.platform.Cluster().HealthScore()
}
func (ch *Channels) ClientConfigHash() string { func (ch *Channels) ClientConfigHash() string {
return ch.srv.Platform().ClientConfigHash() return ch.srv.Platform().ClientConfigHash()
} }
@@ -1700,15 +1695,7 @@ func (s *Server) GetMetrics() einterfaces.MetricsInterface {
return s.platform.Metrics() return s.platform.Metrics()
} }
// SetRemoteClusterService sets the `RemoteClusterService` to be used by the server. // setSharedChannelSyncService sets the `SharedChannelSyncService` to be used by the server.
// For testing only.
func (s *Server) SetRemoteClusterService(remoteClusterService remotecluster.RemoteClusterServiceIFace) {
s.serviceMux.Lock()
defer s.serviceMux.Unlock()
s.remoteClusterService = remoteClusterService
}
// SetSharedChannelSyncService sets the `SharedChannelSyncService` to be used by the server.
// For testing only. // For testing only.
func (s *Server) SetSharedChannelSyncService(sharedChannelService SharedChannelServiceIFace) { func (s *Server) SetSharedChannelSyncService(sharedChannelService SharedChannelServiceIFace) {
s.serviceMux.Lock() s.serviceMux.Lock()

Просмотреть файл

@@ -496,7 +496,7 @@ func (a *App) UpdateTeamMemberSchemeRoles(c request.CTX, teamID string, userID s
// If the migration is not completed, we also need to check the default team_admin/team_user roles are not present in the roles field. // If the migration is not completed, we also need to check the default team_admin/team_user roles are not present in the roles field.
if err = a.IsPhase2MigrationCompleted(); err != nil { if err = a.IsPhase2MigrationCompleted(); err != nil {
member.ExplicitRoles = RemoveRoles([]string{model.TeamGuestRoleId, model.TeamUserRoleId, model.TeamAdminRoleId}, member.ExplicitRoles) member.ExplicitRoles = removeRoles([]string{model.TeamGuestRoleId, model.TeamUserRoleId, model.TeamAdminRoleId}, member.ExplicitRoles)
} }
member, nErr := a.Srv().Store().Team().UpdateMember(c, member) member, nErr := a.Srv().Store().Team().UpdateMember(c, member)
@@ -1096,12 +1096,11 @@ func (a *App) AddTeamMemberByInviteId(c request.CTX, inviteId, userID string) (*
func (a *App) GetTeamUnread(teamID, userID string) (*model.TeamUnread, *model.AppError) { func (a *App) GetTeamUnread(teamID, userID string) (*model.TeamUnread, *model.AppError) {
channelUnreads, err := a.Srv().Store().Team().GetChannelUnreadsForTeam(teamID, userID) channelUnreads, err := a.Srv().Store().Team().GetChannelUnreadsForTeam(teamID, userID)
if err != nil { if err != nil {
return nil, model.NewAppError("GetTeamUnread", "app.team.get_unread.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return nil, model.NewAppError("GetTeamUnread", "app.team.get_unread.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
var teamUnread = &model.TeamUnread{ teamUnread := &model.TeamUnread{
MsgCount: 0, MsgCount: 0,
MentionCount: 0, MentionCount: 0,
MentionCountRoot: 0, MentionCountRoot: 0,

Просмотреть файл

@@ -224,7 +224,7 @@ func (a *App) doOutgoingWebhookRequest(url string, body io.Reader, contentType s
return &hookResp, nil return &hookResp, nil
} }
func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.AppError) { func splitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.AppError) {
splits := make([]*model.Post, 0) splits := make([]*model.Post, 0)
remainingText := post.Message remainingText := post.Message
@@ -238,7 +238,7 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
} }
if utf8.RuneCountInString(model.StringInterfaceToJSON(base.GetProps())) > model.PostPropsMaxUserRunes { if utf8.RuneCountInString(model.StringInterfaceToJSON(base.GetProps())) > model.PostPropsMaxUserRunes {
return nil, model.NewAppError("SplitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]any{"Max": model.PostPropsMaxUserRunes}, "", http.StatusBadRequest) return nil, model.NewAppError("splitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]any{"Max": model.PostPropsMaxUserRunes}, "", http.StatusBadRequest)
} }
for utf8.RuneCountInString(remainingText) > maxPostSize { for utf8.RuneCountInString(remainingText) > maxPostSize {
@@ -287,7 +287,7 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
truncationNeeded := runeCount - model.PostPropsMaxUserRunes truncationNeeded := runeCount - model.PostPropsMaxUserRunes
textRuneCount := utf8.RuneCountInString(attachment.Text) textRuneCount := utf8.RuneCountInString(attachment.Text)
if textRuneCount < truncationNeeded { if textRuneCount < truncationNeeded {
return nil, model.NewAppError("SplitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]any{"Max": model.PostPropsMaxUserRunes}, "", http.StatusBadRequest) return nil, model.NewAppError("splitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]any{"Max": model.PostPropsMaxUserRunes}, "", http.StatusBadRequest)
} }
x := 0 x := 0
for index := range attachment.Text { for index := range attachment.Text {
@@ -360,7 +360,7 @@ func (a *App) CreateWebhookPost(c request.CTX, userID string, channel *model.Cha
} }
} }
splits, err := SplitWebhookPost(post, a.MaxPostSize()) splits, err := splitWebhookPost(post, a.MaxPostSize())
if err != nil { if err != nil {
return nil, err return nil, err
} }

Просмотреть файл

@@ -430,6 +430,7 @@ func TestCreateWebhookPostWithPriority(t *testing.T) {
assert.Equal(t, *conditions.PersistentNotifications, *post.GetPriority().PersistentNotifications) assert.Equal(t, *conditions.PersistentNotifications, *post.GetPriority().PersistentNotifications)
} }
} }
func TestCreateWebhookPostLinks(t *testing.T) { func TestCreateWebhookPostLinks(t *testing.T) {
th := Setup(t).InitBasic() th := Setup(t).InitBasic()
defer th.TearDown() defer th.TearDown()
@@ -538,7 +539,7 @@ func TestSplitWebhookPost(t *testing.T) {
}, },
} { } {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
splits, err := SplitWebhookPost(tc.Post, maxPostSize) splits, err := splitWebhookPost(tc.Post, maxPostSize)
if tc.Expected == nil { if tc.Expected == nil {
require.NotNil(t, err) require.NotNil(t, err)
} else { } else {
@@ -617,7 +618,7 @@ func TestSplitWebhookPostAttachments(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
splits, err := SplitWebhookPost(tc.post, maxPostSize) splits, err := splitWebhookPost(tc.post, maxPostSize)
if tc.expected == nil { if tc.expected == nil {
require.NotNil(t, err) require.NotNil(t, err)
} else { } else {
@@ -726,7 +727,6 @@ func TestTriggerOutGoingWebhookWithUsernameAndIconURL(t *testing.T) {
getTestCases := func() map[string]TestCaseOutgoing { getTestCases := func() map[string]TestCaseOutgoing {
webHookResponse := "sample response text from test server" webHookResponse := "sample response text from test server"
testCasesOutgoing := map[string]TestCaseOutgoing{ testCasesOutgoing := map[string]TestCaseOutgoing{
"Should override username and Icon": { "Should override username and Icon": {
EnablePostUsernameOverride: true, EnablePostUsernameOverride: true,
EnablePostIconOverride: true, EnablePostIconOverride: true,