Merge branch 'master' into mark-as-unread
Этот коммит содержится в:
@@ -69,7 +69,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
assert.Equal(t, len(roles1), len(roleNames))
|
||||
|
||||
expected1 := map[string][]string{
|
||||
"channel_user": []string{
|
||||
"channel_user": {
|
||||
model.PERMISSION_READ_CHANNEL.Id,
|
||||
model.PERMISSION_ADD_REACTION.Id,
|
||||
model.PERMISSION_REMOVE_REACTION.Id,
|
||||
@@ -86,10 +86,10 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_EDIT_POST.Id,
|
||||
},
|
||||
"channel_admin": []string{
|
||||
"channel_admin": {
|
||||
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
},
|
||||
"team_user": []string{
|
||||
"team_user": {
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -99,13 +99,13 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_INVITE_USER.Id,
|
||||
model.PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
},
|
||||
"team_post_all": []string{
|
||||
"team_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"team_post_all_public": []string{
|
||||
"team_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"team_admin": []string{
|
||||
"team_admin": {
|
||||
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_TEAM.Id,
|
||||
model.PERMISSION_IMPORT_TEAM.Id,
|
||||
@@ -120,7 +120,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
"system_user": {
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
@@ -128,18 +128,18 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
"system_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"system_post_all_public": []string{
|
||||
"system_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"system_user_access_token": []string{
|
||||
"system_user_access_token": {
|
||||
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
},
|
||||
"system_admin": []string{
|
||||
"system_admin": {
|
||||
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM.Id,
|
||||
model.PERMISSION_MANAGE_ROLES.Id,
|
||||
@@ -254,7 +254,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
|
||||
// Check the role permissions.
|
||||
expected2 := map[string][]string{
|
||||
"channel_user": []string{
|
||||
"channel_user": {
|
||||
model.PERMISSION_READ_CHANNEL.Id,
|
||||
model.PERMISSION_ADD_REACTION.Id,
|
||||
model.PERMISSION_REMOVE_REACTION.Id,
|
||||
@@ -269,10 +269,10 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_EDIT_POST.Id,
|
||||
},
|
||||
"channel_admin": []string{
|
||||
"channel_admin": {
|
||||
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
},
|
||||
"team_user": []string{
|
||||
"team_user": {
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -282,13 +282,13 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_INVITE_USER.Id,
|
||||
model.PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
},
|
||||
"team_post_all": []string{
|
||||
"team_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"team_post_all_public": []string{
|
||||
"team_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"team_admin": []string{
|
||||
"team_admin": {
|
||||
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_TEAM.Id,
|
||||
model.PERMISSION_IMPORT_TEAM.Id,
|
||||
@@ -305,7 +305,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
"system_user": {
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
@@ -313,18 +313,18 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
"system_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"system_post_all_public": []string{
|
||||
"system_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"system_user_access_token": []string{
|
||||
"system_user_access_token": {
|
||||
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
},
|
||||
"system_admin": []string{
|
||||
"system_admin": {
|
||||
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM.Id,
|
||||
model.PERMISSION_MANAGE_ROLES.Id,
|
||||
|
||||
@@ -1525,9 +1525,12 @@ func (a *App) LeaveChannel(channelId string, userId string) *model.AppError {
|
||||
func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError {
|
||||
post := &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username),
|
||||
Type: model.POST_LEAVE_CHANNEL,
|
||||
UserId: user.Id,
|
||||
// Message here embeds `@username`, not just `username`, to ensure that mentions
|
||||
// treat this as a username mention even though the user has now left the channel.
|
||||
// The client renders its own system message, ignoring this value altogether.
|
||||
Message: fmt.Sprintf(utils.T("api.channel.leave.left"), fmt.Sprintf("@%s", user.Username)),
|
||||
Type: model.POST_LEAVE_CHANNEL,
|
||||
UserId: user.Id,
|
||||
Props: model.StringInterface{
|
||||
"username": user.Username,
|
||||
},
|
||||
@@ -1595,9 +1598,12 @@ func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, chan
|
||||
func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError {
|
||||
post := &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username),
|
||||
Type: model.POST_REMOVE_FROM_CHANNEL,
|
||||
UserId: removerUserId,
|
||||
// Message here embeds `@username`, not just `username`, to ensure that mentions
|
||||
// treat this as a username mention even though the user has now left the channel.
|
||||
// The client renders its own system message, ignoring this value altogether.
|
||||
Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), fmt.Sprintf("@%s", removedUser.Username)),
|
||||
Type: model.POST_REMOVE_FROM_CHANNEL,
|
||||
UserId: removerUserId,
|
||||
Props: model.StringInterface{
|
||||
"removedUserId": removedUser.Id,
|
||||
"removedUsername": removedUser.Username,
|
||||
|
||||
@@ -39,8 +39,13 @@ func GetCommandProvider(name string) CommandProvider {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse) (*model.Post, *model.AppError) {
|
||||
post.Message = model.ParseSlackLinksToMarkdown(response.Text)
|
||||
func (a *App) CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse, skipSlackParsing bool) (*model.Post, *model.AppError) {
|
||||
if skipSlackParsing {
|
||||
post.Message = response.Text
|
||||
} else {
|
||||
post.Message = model.ParseSlackLinksToMarkdown(response.Text)
|
||||
}
|
||||
|
||||
post.CreateAt = model.GetMillis()
|
||||
|
||||
if strings.HasPrefix(post.Type, model.POST_SYSTEM_MESSAGE_PREFIX) {
|
||||
@@ -430,11 +435,16 @@ func (a *App) HandleCommandResponsePost(command *model.Command, args *model.Comm
|
||||
post.AddProp("from_webhook", "true")
|
||||
}
|
||||
|
||||
// Process Slack text replacements
|
||||
response.Text = a.ProcessSlackText(response.Text)
|
||||
response.Attachments = a.ProcessSlackAttachments(response.Attachments)
|
||||
// Do not process text if this is a code block
|
||||
skipSlackParsing := command.Trigger == "code"
|
||||
|
||||
if _, err := a.CreateCommandPost(post, args.TeamId, response); err != nil {
|
||||
// Process Slack text replacements
|
||||
if !skipSlackParsing {
|
||||
response.Text = a.ProcessSlackText(response.Text)
|
||||
response.Attachments = a.ProcessSlackAttachments(response.Attachments)
|
||||
}
|
||||
|
||||
if _, err := a.CreateCommandPost(post, args.TeamId, response, skipSlackParsing); err != nil {
|
||||
return post, err
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ func TestCreateCommandPost(t *testing.T) {
|
||||
Text: "some message",
|
||||
}
|
||||
|
||||
_, err := th.App.CreateCommandPost(post, th.BasicTeam.Id, resp)
|
||||
skipSlackParsing := false
|
||||
_, err := th.App.CreateCommandPost(post, th.BasicTeam.Id, resp, skipSlackParsing)
|
||||
if err == nil || err.Id != "api.context.invalid_param.app_error" {
|
||||
t.Fatal("should have failed - bad post type")
|
||||
}
|
||||
@@ -188,7 +189,7 @@ func TestHandleCommandResponsePost(t *testing.T) {
|
||||
|
||||
// Test Slack attachments text conversion.
|
||||
resp.Attachments = []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: "<!here>",
|
||||
},
|
||||
}
|
||||
@@ -205,7 +206,23 @@ func TestHandleCommandResponsePost(t *testing.T) {
|
||||
if err == nil || err.Id != "api.command.command_post.forbidden.app_error" {
|
||||
t.Fatal("should have failed - forbidden channel post")
|
||||
}
|
||||
|
||||
// Test that /code text is not converted with the Slack text conversion.
|
||||
command.Trigger = "code"
|
||||
resp.ChannelId = ""
|
||||
resp.Text = "<test.com|test website>"
|
||||
resp.Attachments = []*model.SlackAttachment{
|
||||
{
|
||||
Text: "<!here>",
|
||||
},
|
||||
}
|
||||
post, err = th.App.HandleCommandResponsePost(command, args, resp, builtIn)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, resp.Text, post.Message, "/code text should not be converted to Slack links")
|
||||
assert.Equal(t, "<!here>", resp.Attachments[0].Text)
|
||||
}
|
||||
|
||||
func TestHandleCommandResponse(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
@@ -240,10 +257,10 @@ func TestHandleCommandResponse(t *testing.T) {
|
||||
resp = &model.CommandResponse{
|
||||
Text: "message 1",
|
||||
ExtraResponses: []*model.CommandResponse{
|
||||
&model.CommandResponse{
|
||||
{
|
||||
Text: "message 2",
|
||||
},
|
||||
&model.CommandResponse{
|
||||
{
|
||||
Type: model.POST_SYSTEM_GENERIC,
|
||||
Text: "message 3",
|
||||
},
|
||||
@@ -257,8 +274,8 @@ func TestHandleCommandResponse(t *testing.T) {
|
||||
|
||||
resp = &model.CommandResponse{
|
||||
ExtraResponses: []*model.CommandResponse{
|
||||
&model.CommandResponse{},
|
||||
&model.CommandResponse{},
|
||||
{},
|
||||
{},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ func (a *App) trackConfig() {
|
||||
"disable_bots_when_owner_is_deactivated": *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated,
|
||||
"enable_bot_account_creation": *cfg.ServiceSettings.EnableBotAccountCreation,
|
||||
"enable_svgs": *cfg.ServiceSettings.EnableSVGs,
|
||||
"enable_latex": *cfg.ServiceSettings.EnableLatex,
|
||||
})
|
||||
|
||||
a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
func TestPluginSetting(t *testing.T) {
|
||||
settings := &model.PluginSettings{
|
||||
Plugins: map[string]map[string]interface{}{
|
||||
"test": map[string]interface{}{
|
||||
"test": {
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
@@ -31,10 +31,10 @@ func TestPluginSetting(t *testing.T) {
|
||||
|
||||
func TestPluginActivated(t *testing.T) {
|
||||
states := map[string]*model.PluginState{
|
||||
"foo": &model.PluginState{
|
||||
"foo": {
|
||||
Enable: true,
|
||||
},
|
||||
"bar": &model.PluginState{
|
||||
"bar": {
|
||||
Enable: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -64,11 +64,11 @@ func TestHandleNewNotifications(t *testing.T) {
|
||||
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test4"}, &model.Team{Name: "team"})
|
||||
job.Add(&model.User{Id: id2}, &model.Post{UserId: id1, Message: "test5"}, &model.Team{Name: "team"})
|
||||
job.handleNewNotifications()
|
||||
assert.Equal(t, job.pendingNotifications[id1][0].post.Message, "test1", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id1][1].post.Message, "test2", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id1][2].post.Message, "test4", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id2][0].post.Message, "test3", "incorrect order of received posts for user2");
|
||||
assert.Equal(t, job.pendingNotifications[id2][1].post.Message, "test5", "incorrect order of received posts for user2");
|
||||
assert.Equal(t, job.pendingNotifications[id1][0].post.Message, "test1", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id1][1].post.Message, "test2", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id1][2].post.Message, "test4", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id2][0].post.Message, "test3", "incorrect order of received posts for user2")
|
||||
assert.Equal(t, job.pendingNotifications[id2][1].post.Message, "test5", "incorrect order of received posts for user2")
|
||||
}
|
||||
|
||||
func TestCheckPendingNotifications(t *testing.T) {
|
||||
|
||||
@@ -11,6 +11,10 @@ func (a *App) GetGroup(id string) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().Get(id)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByName(name)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupByRemoteID(remoteID string, groupSource model.GroupSource) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByRemoteID(remoteID, groupSource)
|
||||
}
|
||||
@@ -19,6 +23,10 @@ func (a *App) GetGroupsBySource(groupSource model.GroupSource) ([]*model.Group,
|
||||
return a.Srv.Store.Group().GetAllBySource(groupSource)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupsByUserId(userId string) ([]*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByUser(userId)
|
||||
}
|
||||
|
||||
func (a *App) CreateGroup(group *model.Group) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().Create(group)
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ func TestImportValidateUserImportData(t *testing.T) {
|
||||
|
||||
data.Username = ptrStr("i am a username with spaces and !!!")
|
||||
err = validateUserImportData(&data)
|
||||
require.NotNil(t, err, "Validation should have failed due to invalid characters in Username.");
|
||||
require.NotNil(t, err, "Validation should have failed due to invalid characters in Username.")
|
||||
|
||||
data.Username = ptrStr("bob")
|
||||
|
||||
@@ -759,7 +759,6 @@ func TestImportValidateReactionImportData(t *testing.T) {
|
||||
err = validateReactionImportData(&data, parentCreateAt)
|
||||
require.NotNil(t, err, "Should have failed due to missing required property.")
|
||||
|
||||
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
@@ -938,13 +937,13 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
require.NotNil(t, err, "Should have failed due to 0 create-at value.")
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
reactions := []ReactionImportData{{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
replies := []ReplyImportData{{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
@@ -1240,13 +1239,13 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
require.Nil(t, err, "Validation should succeed with post flagged by members")
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
reactions := []ReactionImportData{{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
replies := []ReplyImportData{{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
|
||||
@@ -430,7 +430,7 @@ func TestSubmitInteractiveDialog(t *testing.T) {
|
||||
assert.Equal(t, "value1", val)
|
||||
|
||||
resp := model.SubmitDialogResponse{
|
||||
Error: "some generic error",
|
||||
Error: "some generic error",
|
||||
Errors: map[string]string{"name1": "some error"},
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func (a *App) GetLdapGroup(ldapGroupID string) (*model.Group, *model.AppError) {
|
||||
}
|
||||
} else {
|
||||
ae := model.NewAppError("GetLdapGroup", "ent.ldap.app_error", nil, "", http.StatusNotImplemented)
|
||||
mlog.Error(fmt.Sprintf("%v", ae.Error()))
|
||||
mlog.Error("Unable to use ldap", mlog.String("ldap_group_id", ldapGroupID), mlog.Err(ae))
|
||||
return nil, ae
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (a *App) GetAllLdapGroupsPage(page int, perPage int, opts model.LdapGroupSe
|
||||
}
|
||||
} else {
|
||||
ae := model.NewAppError("GetAllLdapGroupsPage", "ent.ldap.app_error", nil, "", http.StatusNotImplemented)
|
||||
mlog.Error(fmt.Sprintf("%v", ae.Error()))
|
||||
mlog.Error("Unable to use ldap", mlog.Err(ae))
|
||||
return nil, 0, ae
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ func (a *App) DoLogin(w http.ResponseWriter, r *http.Request, user *model.User,
|
||||
}
|
||||
|
||||
w.Header().Set(model.HEADER_TOKEN, session.Token)
|
||||
a.Session = *session
|
||||
|
||||
if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil {
|
||||
a.Srv.Go(func() {
|
||||
|
||||
@@ -95,9 +95,9 @@ func (a *App) DoEmojisPermissionsMigration() {
|
||||
return
|
||||
}
|
||||
|
||||
var role *model.Role = nil
|
||||
var systemAdminRole *model.Role = nil
|
||||
var err *model.AppError = nil
|
||||
var role *model.Role
|
||||
var systemAdminRole *model.Role
|
||||
var err *model.AppError
|
||||
|
||||
mlog.Info("Migrating emojis config to database.")
|
||||
switch *a.Config().ServiceSettings.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation {
|
||||
|
||||
@@ -100,7 +100,7 @@ func (a *App) sendNotificationEmail(notification *postNotification, user *model.
|
||||
|
||||
a.Srv.Go(func() {
|
||||
if err := a.SendNotificationMail(user.Email, html.UnescapeString(subjectText), bodyText); err != nil {
|
||||
mlog.Error(fmt.Sprint("Error to send the email", user.Email, err))
|
||||
mlog.Error("Error while sending the email", mlog.String("email", user.Email), mlog.Err(err))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -320,7 +320,7 @@ func (a *App) GetMessageForNotification(post *model.Post, translateFunc i18n.Tra
|
||||
// extract the filenames from their paths and determine what type of files are attached
|
||||
infos, err := a.Srv.Store.FileInfo().GetForPost(post.Id, true, false, true)
|
||||
if err != nil {
|
||||
mlog.Warn(fmt.Sprintf("Encountered error when getting files for notification message, post_id=%v, err=%v", post.Id, err), mlog.String("post_id", post.Id))
|
||||
mlog.Warn("Encountered error when getting files for notification message", mlog.String("post_id", post.Id), mlog.Err(err))
|
||||
}
|
||||
|
||||
filenames := make([]string, len(infos))
|
||||
|
||||
@@ -30,7 +30,6 @@ type PushNotificationsHub struct {
|
||||
}
|
||||
|
||||
type PushNotification struct {
|
||||
id string
|
||||
notificationType NotificationType
|
||||
currentSessionId string
|
||||
userId string
|
||||
@@ -368,8 +367,8 @@ func ShouldSendPushNotification(user *model.User, channelNotifyProps model.Strin
|
||||
func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned bool) bool {
|
||||
userNotifyProps := user.NotifyProps
|
||||
userNotify := userNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
channelNotify, _ := channelNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
if channelNotify == "" {
|
||||
channelNotify, ok := channelNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
if !ok || channelNotify == "" {
|
||||
channelNotify = model.CHANNEL_NOTIFY_DEFAULT
|
||||
}
|
||||
|
||||
|
||||
@@ -282,11 +282,7 @@ func getAddManageGuestsPermissionsMigration() permissionsMap {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_PROMOTE_GUEST, PERMISSION_DEMOTE_TO_GUEST},
|
||||
},
|
||||
permissionTransformation{
|
||||
On: permissionExists(PERMISSION_INVITE_USER),
|
||||
Add: []string{PERMISSION_INVITE_GUEST},
|
||||
Add: []string{PERMISSION_PROMOTE_GUEST, PERMISSION_DEMOTE_TO_GUEST, PERMISSION_INVITE_GUEST},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +445,18 @@ func (api *PluginAPI) DeleteChannelMember(channelId, userId string) *model.AppEr
|
||||
return api.app.LeaveChannel(channelId, userId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroup(groupId string) (*model.Group, *model.AppError) {
|
||||
return api.app.GetGroup(groupId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
return api.app.GetGroupByName(name)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroupsForUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
return api.app.GetGroupsByUserId(userId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
|
||||
return api.app.CreatePostMissingChannel(post, true)
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ func TestHookFileWillBeUploaded(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, response)
|
||||
assert.Equal(t, 1, len(response.FileInfos))
|
||||
|
||||
|
||||
fileId := response.FileInfos[0].Id
|
||||
fileInfo, err := th.App.GetFileInfo(fileId)
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -73,8 +73,6 @@ func (a *App) OverrideIconURLIfEmoji(post *model.Post) {
|
||||
} else {
|
||||
mlog.Warn("Failed to retrieve URL for overriden profile icon (emoji)", mlog.String("emojiName", emojiName), mlog.Err(err))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isEditPost bool) *model.Post {
|
||||
@@ -87,6 +85,11 @@ func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isE
|
||||
|
||||
post.Metadata = &model.PostMetadata{}
|
||||
|
||||
if post.DeleteAt > 0 {
|
||||
// Don't fill out metadata for deleted posts
|
||||
return post
|
||||
}
|
||||
|
||||
// Emojis and reaction counts
|
||||
if emojis, reactions, err := a.getEmojisAndReactionsForPost(post); err != nil {
|
||||
mlog.Warn("Failed to get emojis and reactions for a post", mlog.String("post_id", post.Id), mlog.Err(err))
|
||||
|
||||
@@ -307,18 +307,22 @@ func TestPreparePostForClient(t *testing.T) {
|
||||
t.Run("does not override icon URL", func(t *testing.T) {
|
||||
clientPost := prepare(false, url, emoji)
|
||||
|
||||
s, _ := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
s, ok := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, url, s)
|
||||
s, _ = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
s, ok = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, emoji, s)
|
||||
})
|
||||
|
||||
t.Run("overrides icon URL", func(t *testing.T) {
|
||||
clientPost := prepare(true, url, emoji)
|
||||
|
||||
s, _ := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
s, ok := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, overridenUrl, s)
|
||||
s, _ = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
s, ok = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, emoji, s)
|
||||
})
|
||||
|
||||
@@ -477,6 +481,36 @@ func TestPreparePostForClient(t *testing.T) {
|
||||
}, imageDimensions[server.URL+"/test-image1.png"])
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("no metadata for deleted posts", func(t *testing.T) {
|
||||
th := setup()
|
||||
defer th.TearDown()
|
||||
|
||||
fileInfo, err := th.App.DoUploadFile(time.Now(), th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, "test.txt", []byte("test"))
|
||||
require.Nil(t, err)
|
||||
|
||||
post, err := th.App.CreatePost(&model.Post{
|
||||
Message: "test",
|
||||
FileIds: []string{fileInfo.Id},
|
||||
UserId: th.BasicUser.Id,
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
}, th.BasicChannel, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.AddReactionToPost(post, th.BasicUser, "taco")
|
||||
|
||||
post, err = th.App.DeletePost(post.Id, th.BasicUser.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
// DeleteAt isn't set on the post returned by App.DeletePost
|
||||
post.DeleteAt = model.GetMillis()
|
||||
|
||||
clientPost := th.App.PreparePostForClient(post, false, false)
|
||||
|
||||
assert.NotEqual(t, nil, clientPost.Metadata, "should've populated Metadata“")
|
||||
assert.Nil(t, clientPost.Metadata.Reactions, "should not have populated Reactions")
|
||||
assert.Nil(t, clientPost.Metadata.Files, "should not have populated Files")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPreparePostForClientWithImageProxy(t *testing.T) {
|
||||
|
||||
@@ -633,7 +633,7 @@ func (a *App) OriginChecker() func(*http.Request) bool {
|
||||
|
||||
func (s *Server) checkPushNotificationServerUrl() {
|
||||
notificationServer := *s.Config().EmailSettings.PushNotificationServer
|
||||
if strings.HasPrefix(notificationServer, "http://") == true {
|
||||
if strings.HasPrefix(notificationServer, "http://") {
|
||||
mlog.Warn("Your push notification server is configured with HTTP. For improved security, update to HTTPS in your configuration.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1456,6 +1456,10 @@ func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.Srv.Store.Group().PermanentDeleteMembersByUser(user.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.Srv.Store.Post().PermanentDeleteByUser(user.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -331,10 +331,7 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
|
||||
|
||||
// If the event is destined to a specific user
|
||||
if len(msg.Broadcast.UserId) > 0 {
|
||||
if webCon.UserId == msg.Broadcast.UserId {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return webCon.UserId == msg.Broadcast.UserId
|
||||
}
|
||||
|
||||
// if the user is omitted don't send the message
|
||||
@@ -397,10 +394,5 @@ func (webCon *WebConn) IsMemberOfTeam(teamId string) bool {
|
||||
currentSession = session
|
||||
}
|
||||
|
||||
member := currentSession.GetTeamByTeamId(teamId)
|
||||
|
||||
if member != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return currentSession.GetTeamByTeamId(teamId) != nil
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestHubStopWithMultipleConnections(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(dummyWebsocketHandler(t)))
|
||||
s := httptest.NewServer(dummyWebsocketHandler(t))
|
||||
defer s.Close()
|
||||
|
||||
th.App.HubStart()
|
||||
@@ -68,7 +68,7 @@ func TestHubStopRaceCondition(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(dummyWebsocketHandler(t)))
|
||||
s := httptest.NewServer(dummyWebsocketHandler(t))
|
||||
|
||||
th.App.HubStart()
|
||||
wc1 := registerDummyWebConn(t, th.App, s.Listener.Addr(), th.BasicUser.Id)
|
||||
|
||||
@@ -389,13 +389,13 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
Message: strings.Repeat("本", maxPostSize*3/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 1000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 2000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
|
||||
},
|
||||
},
|
||||
@@ -409,10 +409,10 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
Message: strings.Repeat("本", maxPostSize/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 1000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 2000),
|
||||
},
|
||||
},
|
||||
@@ -421,7 +421,7 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
{
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
|
||||
},
|
||||
},
|
||||
|
||||
Ссылка в новой задаче
Block a user