From 116849842be59bc6960df415f23155ec8e767f06 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Fri, 6 Apr 2018 17:08:57 -0400 Subject: MM-8678: add CUD support for channel members via plugins (#8565) * add CUD support for channel members via plugins This effectively exposes AddChannelMember, UpdateChannelMemberRoles, UpdateChannelMemberNotifyProps and LeaveChannel via the plugin API. It also modifies the semantics of AddChannelMember to explicitly allow for an empty user requestor, left as such for now via the plugin API. * change the signature of AddChannelMember to accept a channel id instead of a channel --- app/channel.go | 12 ++++++++---- app/channel_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ app/plugin_api.go | 25 +++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/channel.go b/app/channel.go index 6e11d4e5d..40f21c3a9 100644 --- a/app/channel.go +++ b/app/channel.go @@ -652,8 +652,10 @@ func (a *App) AddChannelMember(userId string, channel *model.Channel, userReques } var userRequestor *model.User - if userRequestor, err = a.GetUser(userRequestorId); err != nil { - return nil, err + if userRequestorId != "" { + if userRequestor, err = a.GetUser(userRequestorId); err != nil { + return nil, err + } } cm, err := a.AddUserToChannel(user, channel) @@ -661,7 +663,7 @@ func (a *App) AddChannelMember(userId string, channel *model.Channel, userReques return nil, err } - if userId == userRequestorId { + if userRequestorId == "" || userId == userRequestorId { a.postJoinChannelMessage(user, channel) } else { a.Go(func() { @@ -669,7 +671,9 @@ func (a *App) AddChannelMember(userId string, channel *model.Channel, userReques }) } - a.UpdateChannelLastViewedAt([]string{channel.Id}, userRequestor.Id) + if userRequestor != nil { + a.UpdateChannelLastViewedAt([]string{channel.Id}, userRequestor.Id) + } return cm, nil } diff --git a/app/channel_test.go b/app/channel_test.go index 69efaeca7..a4e0806a6 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -340,3 +340,44 @@ func TestRemoveUserFromChannelUpdatesChannelMemberHistoryRecord(t *testing.T) { assert.Equal(t, publicChannel.Id, histories[0].ChannelId) assert.NotNil(t, histories[0].LeaveTime) } + +func TestAddChannelMemberNoUserRequestor(t *testing.T) { + th := Setup().InitBasic() + defer th.TearDown() + + // create a user and add it to a channel + user := th.CreateUser() + if _, err := th.App.AddTeamMember(th.BasicTeam.Id, user.Id); err != nil { + t.Fatal("Failed to add user to team. Error: " + err.Message) + } + + groupUserIds := make([]string, 0) + groupUserIds = append(groupUserIds, th.BasicUser.Id) + groupUserIds = append(groupUserIds, user.Id) + + channel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN) + userRequestorId := "" + postRootId := "" + if _, err := th.App.AddChannelMember(user.Id, channel, userRequestorId, postRootId); err != nil { + t.Fatal("Failed to add user to channel. Error: " + err.Message) + } + + // there should be a ChannelMemberHistory record for the user + histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistoryResult) + assert.Len(t, histories, 2) + channelMemberHistoryUserIds := make([]string, 0) + for _, history := range histories { + assert.Equal(t, channel.Id, history.ChannelId) + channelMemberHistoryUserIds = append(channelMemberHistoryUserIds, history.UserId) + } + assert.Equal(t, groupUserIds, channelMemberHistoryUserIds) + + postList := store.Must(th.App.Srv.Store.Post().GetPosts(channel.Id, 0, 1, false)).(*model.PostList) + if assert.Len(t, postList.Order, 1) { + post := postList.Posts[postList.Order[0]] + + assert.Equal(t, model.POST_JOIN_CHANNEL, post.Type) + assert.Equal(t, user.Id, post.UserId) + assert.Equal(t, user.Username, post.Props["username"]) + } +} diff --git a/app/plugin_api.go b/app/plugin_api.go index 21b828368..b09a0c419 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -124,10 +124,35 @@ func (api *PluginAPI) UpdateChannel(channel *model.Channel) (*model.Channel, *mo return api.app.UpdateChannel(channel) } +func (api *PluginAPI) AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { + // For now, don't allow overriding these via the plugin API. + userRequestorId := "" + postRootId := "" + + channel, err := api.GetChannel(channelId) + if err != nil { + return nil, err + } + + return api.app.AddChannelMember(userId, channel, userRequestorId, postRootId) +} + func (api *PluginAPI) GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { return api.app.GetChannelMember(channelId, userId) } +func (api *PluginAPI) UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError) { + return api.app.UpdateChannelMemberRoles(channelId, userId, newRoles) +} + +func (api *PluginAPI) UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError) { + return api.app.UpdateChannelMemberNotifyProps(notifications, channelId, userId) +} + +func (api *PluginAPI) DeleteChannelMember(channelId, userId string) *model.AppError { + return api.app.LeaveChannel(channelId, userId) +} + func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) { return api.app.CreatePostMissingChannel(post, true) } -- cgit v1.2.3-1-g7c22