summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api4/apitestlib.go4
-rw-r--r--api4/channel.go46
-rw-r--r--api4/channel_test.go88
-rw-r--r--app/channel.go25
-rw-r--r--model/client4.go11
5 files changed, 172 insertions, 2 deletions
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index 64d3f22b2..b3007ebfe 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -498,14 +498,14 @@ func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) {
func CheckInternalErrorStatus(t *testing.T, resp *model.Response) {
if resp.Error == nil {
debug.PrintStack()
- t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusNotImplemented))
+ t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusInternalServerError))
return
}
if resp.StatusCode != http.StatusInternalServerError {
debug.PrintStack()
t.Log("actual: " + strconv.Itoa(resp.StatusCode))
- t.Log("expected: " + strconv.Itoa(http.StatusNotImplemented))
+ t.Log("expected: " + strconv.Itoa(http.StatusInternalServerError))
t.Fatal("wrong status code")
}
}
diff --git a/api4/channel.go b/api4/channel.go
index bd1710975..61d9e6f53 100644
--- a/api4/channel.go
+++ b/api4/channel.go
@@ -33,6 +33,7 @@ func InitChannel() {
BaseRoutes.ChannelMembers.Handle("", ApiSessionRequired(getChannelMembers)).Methods("GET")
BaseRoutes.ChannelMembers.Handle("/ids", ApiSessionRequired(getChannelMembersByIds)).Methods("POST")
+ BaseRoutes.ChannelMembers.Handle("", ApiSessionRequired(addChannelMember)).Methods("POST")
BaseRoutes.ChannelMembersForUser.Handle("", ApiSessionRequired(getChannelMembersForUser)).Methods("GET")
BaseRoutes.ChannelMember.Handle("", ApiSessionRequired(getChannelMember)).Methods("GET")
BaseRoutes.ChannelMember.Handle("", ApiSessionRequired(removeChannelMember)).Methods("DELETE")
@@ -498,6 +499,51 @@ func updateChannelMemberRoles(c *Context, w http.ResponseWriter, r *http.Request
ReturnStatusOK(w)
}
+func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireChannelId()
+ if c.Err != nil {
+ return
+ }
+
+ member := model.ChannelMemberFromJson(r.Body)
+ if member == nil {
+ c.SetInvalidParam("channel_member")
+ return
+ }
+
+ if len(member.UserId) != 26 {
+ c.SetInvalidParam("user_id")
+ return
+ }
+
+ member.ChannelId = c.Params.ChannelId
+
+ var channel *model.Channel
+ var err *model.AppError
+ if channel, err = app.GetChannel(member.ChannelId); err != nil {
+ c.Err = err
+ return
+ }
+
+ if channel.Type == model.CHANNEL_OPEN && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS)
+ return
+ }
+
+ if channel.Type == model.CHANNEL_PRIVATE && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS)
+ return
+ }
+
+ if cm, err := app.AddChannelMember(member.UserId, channel, c.Session.UserId); err != nil {
+ c.Err = err
+ return
+ } else {
+ c.LogAudit("name=" + channel.Name + " user_id=" + cm.UserId)
+ w.Write([]byte(cm.ToJson()))
+ }
+}
+
func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireChannelId().RequireUserId()
if c.Err != nil {
diff --git a/api4/channel_test.go b/api4/channel_test.go
index 6d5b5cef3..fd72a8ba7 100644
--- a/api4/channel_test.go
+++ b/api4/channel_test.go
@@ -1118,6 +1118,94 @@ func TestUpdateChannelRoles(t *testing.T) {
CheckForbiddenStatus(t, resp)
}
+func TestAddChannelMember(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer TearDown()
+ Client := th.Client
+ user := th.BasicUser
+ user2 := th.BasicUser2
+ publicChannel := th.CreatePublicChannel()
+ privateChannel := th.CreatePrivateChannel()
+
+ cm, resp := Client.AddChannelMember(publicChannel.Id, user2.Id)
+ CheckNoError(t, resp)
+
+ if cm.ChannelId != publicChannel.Id {
+ t.Fatal("should have returned exact channel")
+ }
+
+ if cm.UserId != user2.Id {
+ t.Fatal("should have returned exact user added to public channel")
+ }
+
+ cm, resp = Client.AddChannelMember(privateChannel.Id, user2.Id)
+ CheckNoError(t, resp)
+
+ if cm.ChannelId != privateChannel.Id {
+ t.Fatal("should have returned exact channel")
+ }
+
+ if cm.UserId != user2.Id {
+ t.Fatal("should have returned exact user added to private channel")
+ }
+
+ cm, resp = Client.AddChannelMember(publicChannel.Id, "junk")
+ CheckBadRequestStatus(t, resp)
+
+ if cm != nil {
+ t.Fatal("should return nothing")
+ }
+
+ _, resp = Client.AddChannelMember(publicChannel.Id, GenerateTestId())
+ CheckNotFoundStatus(t, resp)
+
+ _, resp = Client.AddChannelMember("junk", user2.Id)
+ CheckBadRequestStatus(t, resp)
+
+ _, resp = Client.AddChannelMember(GenerateTestId(), user2.Id)
+ CheckNotFoundStatus(t, resp)
+
+ otherUser := th.CreateUser()
+ otherChannel := th.CreatePublicChannel()
+ Client.Logout()
+ Client.Login(user2.Id, user2.Password)
+
+ _, resp = Client.AddChannelMember(publicChannel.Id, otherUser.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ _, resp = Client.AddChannelMember(privateChannel.Id, otherUser.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ _, resp = Client.AddChannelMember(otherChannel.Id, otherUser.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ Client.Logout()
+ Client.Login(user.Id, user.Password)
+
+ // should fail adding user who is not a member of the team
+ _, resp = Client.AddChannelMember(otherChannel.Id, otherUser.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ Client.DeleteChannel(otherChannel.Id)
+
+ // should fail adding user to a deleted channel
+ _, resp = Client.AddChannelMember(otherChannel.Id, user2.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ Client.Logout()
+ _, resp = Client.AddChannelMember(publicChannel.Id, user2.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ _, resp = Client.AddChannelMember(privateChannel.Id, user2.Id)
+ CheckUnauthorizedStatus(t, resp)
+
+ _, resp = th.SystemAdminClient.AddChannelMember(publicChannel.Id, user2.Id)
+ CheckNoError(t, resp)
+
+ _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user2.Id)
+ CheckNoError(t, resp)
+}
+
func TestRemoveChannelMember(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
diff --git a/app/channel.go b/app/channel.go
index af7596ae1..a55805303 100644
--- a/app/channel.go
+++ b/app/channel.go
@@ -446,6 +446,31 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
return newMember, nil
}
+func AddChannelMember(userId string, channel *model.Channel, userRequestorId string) (*model.ChannelMember, *model.AppError) {
+ var user *model.User
+ var err *model.AppError
+
+ if user, err = GetUser(userId); err != nil {
+ return nil, err
+ }
+
+ var userRequestor *model.User
+ if userRequestor, err = GetUser(userRequestorId); err != nil {
+ return nil, err
+ }
+
+ cm, err := AddUserToChannel(user, channel)
+ if err != nil {
+ return nil, err
+ }
+
+ go PostAddToChannelMessage(userRequestor, user, channel)
+
+ UpdateChannelLastViewedAt([]string{channel.Id}, userRequestor.Id)
+
+ return cm, nil
+}
+
func AddDirectChannels(teamId string, user *model.User) *model.AppError {
var profiles []*model.User
if result := <-Srv.Store.User().GetProfiles(teamId, 0, 100); result.Err != nil {
diff --git a/model/client4.go b/model/client4.go
index 307d52c55..bcefe90a4 100644
--- a/model/client4.go
+++ b/model/client4.go
@@ -968,6 +968,17 @@ func (c *Client4) UpdateChannelRoles(channelId, userId, roles string) (bool, *Re
}
}
+// AddChannelMember adds user to channel and return a channel member.
+func (c *Client4) AddChannelMember(channelId, userId string) (*ChannelMember, *Response) {
+ requestBody := map[string]string{"user_id": userId}
+ if r, err := c.DoApiPost(c.GetChannelMembersRoute(channelId)+"", MapToJson(requestBody)); err != nil {
+ return nil, &Response{StatusCode: r.StatusCode, Error: 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 {