diff options
-rw-r--r-- | api/channel.go | 2 | ||||
-rw-r--r-- | api4/channel.go | 31 | ||||
-rw-r--r-- | api4/channel_test.go | 18 | ||||
-rw-r--r-- | app/channel.go | 11 | ||||
-rw-r--r-- | model/client4.go | 11 |
5 files changed, 59 insertions, 14 deletions
diff --git a/api/channel.go b/api/channel.go index f41a588ee..2782f9636 100644 --- a/api/channel.go +++ b/api/channel.go @@ -649,7 +649,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) { } c.App.Go(func() { - c.App.PostAddToChannelMessage(oUser, nUser, channel) + c.App.PostAddToChannelMessage(oUser, nUser, channel, "") }) c.App.UpdateChannelLastViewedAt([]string{id}, oUser.Id) diff --git a/api4/channel.go b/api4/channel.go index 5a3920a0a..f96942a4f 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -783,21 +783,36 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - member := model.ChannelMemberFromJson(r.Body) - if member == nil { - c.SetInvalidParam("channel_member") + props := model.StringInterfaceFromJson(r.Body) + userId, ok := props["user_id"].(string) + if !ok || len(userId) != 26 { + c.SetInvalidParam("user_id") return } - if len(member.UserId) != 26 { - c.SetInvalidParam("user_id") + member := &model.ChannelMember{ + ChannelId: c.Params.ChannelId, + UserId: userId, + } + + postRootId, ok := props["post_root_id"].(string) + if ok && len(postRootId) != 0 && len(postRootId) != 26 { + c.SetInvalidParam("post_root_id") return } - member.ChannelId = c.Params.ChannelId + var err *model.AppError + if ok && len(postRootId) == 26 { + if rootPost, err := c.App.GetSinglePost(postRootId); err != nil { + c.Err = err + return + } else if rootPost.ChannelId != member.ChannelId { + c.SetInvalidParam("post_root_id") + return + } + } var channel *model.Channel - var err *model.AppError if channel, err = c.App.GetChannel(member.ChannelId); err != nil { c.Err = err return @@ -828,7 +843,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - if cm, err := c.App.AddChannelMember(member.UserId, channel, c.Session.UserId); err != nil { + if cm, err := c.App.AddChannelMember(member.UserId, channel, c.Session.UserId, postRootId); err != nil { c.Err = err return } else { diff --git a/api4/channel_test.go b/api4/channel_test.go index af47aca95..d341837c8 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -1740,6 +1740,24 @@ func TestAddChannelMember(t *testing.T) { t.Fatal("should have returned exact user added to private channel") } + post := &model.Post{ChannelId: publicChannel.Id, Message: "a" + GenerateTestId() + "a"} + rpost, err := Client.CreatePost(post) + if err == nil { + t.Fatal("should have created a post") + } + + Client.RemoveUserFromChannel(publicChannel.Id, user.Id) + _, resp = Client.AddChannelMemberWithRootId(publicChannel.Id, user.Id, rpost.Id) + CheckNoError(t, resp) + CheckCreatedStatus(t, resp) + + Client.RemoveUserFromChannel(publicChannel.Id, user.Id) + _, resp = Client.AddChannelMemberWithRootId(publicChannel.Id, user.Id, "junk") + CheckBadRequestStatus(t, resp) + + _, resp = Client.AddChannelMemberWithRootId(publicChannel.Id, user.Id, GenerateTestId()) + CheckNotFoundStatus(t, resp) + Client.RemoveUserFromChannel(publicChannel.Id, user.Id) _, resp = Client.AddChannelMember(publicChannel.Id, user.Id) CheckNoError(t, resp) diff --git a/app/channel.go b/app/channel.go index 465f2cc80..4ccc12004 100644 --- a/app/channel.go +++ b/app/channel.go @@ -61,7 +61,7 @@ func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole s l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } } else { - if err := a.PostAddToChannelMessage(requestor, user, townSquare); err != nil { + if err := a.PostAddToChannelMessage(requestor, user, townSquare, ""); err != nil { l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } } @@ -86,7 +86,7 @@ func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole s l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } } else { - if err := a.PostAddToChannelMessage(requestor, user, offTopic); err != nil { + if err := a.PostAddToChannelMessage(requestor, user, offTopic, ""); err != nil { l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } } @@ -555,7 +555,7 @@ func (a *App) AddUserToChannel(user *model.User, channel *model.Channel) (*model return newMember, nil } -func (a *App) AddChannelMember(userId string, channel *model.Channel, userRequestorId string) (*model.ChannelMember, *model.AppError) { +func (a *App) AddChannelMember(userId string, channel *model.Channel, userRequestorId string, postRootId string) (*model.ChannelMember, *model.AppError) { if result := <-a.Srv.Store.Channel().GetMember(channel.Id, userId); result.Err != nil { if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { return nil, result.Err @@ -585,7 +585,7 @@ func (a *App) AddChannelMember(userId string, channel *model.Channel, userReques a.postJoinChannelMessage(user, channel) } else { a.Go(func() { - a.PostAddToChannelMessage(userRequestor, user, channel) + a.PostAddToChannelMessage(userRequestor, user, channel, postRootId) }) } @@ -986,12 +986,13 @@ func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) return nil } -func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel) *model.AppError { +func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { post := &model.Post{ ChannelId: channel.Id, Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username), Type: model.POST_ADD_TO_CHANNEL, UserId: user.Id, + RootId: postRootId, Props: model.StringInterface{ "username": user.Username, "addedUsername": addedUser.Username, diff --git a/model/client4.go b/model/client4.go index bcd41638b..916e9d6de 100644 --- a/model/client4.go +++ b/model/client4.go @@ -1663,6 +1663,17 @@ func (c *Client4) AddChannelMember(channelId, userId string) (*ChannelMember, *R } } +// AddChannelMemberWithRootId adds user to channel and return a channel member. Post add to channel message has the postRootId. +func (c *Client4) AddChannelMemberWithRootId(channelId, userId, postRootId string) (*ChannelMember, *Response) { + requestBody := map[string]string{"user_id": userId, "post_root_id": postRootId} + if r, err := c.DoApiPost(c.GetChannelMembersRoute(channelId)+"", MapToJson(requestBody)); err != nil { + return nil, BuildErrorResponse(r, err) + } else { + defer closeBody(r) + return ChannelMemberFromJson(r.Body), BuildResponse(r) + } +} + // RemoveUserFromChannel will delete the channel member object for a user, effectively removing the user from a channel. func (c *Client4) RemoveUserFromChannel(channelId, userId string) (bool, *Response) { if r, err := c.DoApiDelete(c.GetChannelMemberRoute(channelId, userId)); err != nil { |