summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/channel.go12
-rw-r--r--app/channel_test.go41
-rw-r--r--app/plugin_api.go25
-rw-r--r--plugin/api.go12
-rw-r--r--plugin/plugintest/api.go39
-rw-r--r--plugin/rpcplugin/api.go103
-rw-r--r--plugin/rpcplugin/api_test.go23
7 files changed, 250 insertions, 5 deletions
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)
}
diff --git a/plugin/api.go b/plugin/api.go
index 437188f6e..d62c2f069 100644
--- a/plugin/api.go
+++ b/plugin/api.go
@@ -77,9 +77,21 @@ type API interface {
// UpdateChannel updates a channel.
UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
+ // AddChannelMember creates a channel membership for a user.
+ AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
+
// GetChannelMember gets a channel membership for a user.
GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
+ // UpdateChannelMemberRoles updates a user's roles for a channel.
+ UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError)
+
+ // UpdateChannelMemberNotifications updates a user's notification properties for a channel.
+ UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError)
+
+ // DeleteChannelMember deletes a channel membership for a user.
+ DeleteChannelMember(channelId, userId string) *model.AppError
+
// CreatePost creates a post.
CreatePost(post *model.Post) (*model.Post, *model.AppError)
diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go
index 75174a9a6..8f9f4a604 100644
--- a/plugin/plugintest/api.go
+++ b/plugin/plugintest/api.go
@@ -223,6 +223,16 @@ func (m *API) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppE
return channelOut, err
}
+func (m *API) AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) {
+ ret := m.Called(channelId, userId)
+ if f, ok := ret.Get(0).(func(_, _ string) (*model.ChannelMember, *model.AppError)); ok {
+ return f(channelId, userId)
+ }
+ member, _ := ret.Get(0).(*model.ChannelMember)
+ err, _ := ret.Get(1).(*model.AppError)
+ return member, err
+}
+
func (m *API) GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) {
ret := m.Called(channelId, userId)
if f, ok := ret.Get(0).(func(_, _ string) (*model.ChannelMember, *model.AppError)); ok {
@@ -233,6 +243,35 @@ func (m *API) GetChannelMember(channelId, userId string) (*model.ChannelMember,
return member, err
}
+func (m *API) UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError) {
+ ret := m.Called(channelId, userId, newRoles)
+ if f, ok := ret.Get(0).(func(_, _, _ string) (*model.ChannelMember, *model.AppError)); ok {
+ return f(channelId, userId, newRoles)
+ }
+ member, _ := ret.Get(0).(*model.ChannelMember)
+ err, _ := ret.Get(1).(*model.AppError)
+ return member, err
+}
+
+func (m *API) UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError) {
+ ret := m.Called(channelId, userId, notifications)
+ if f, ok := ret.Get(0).(func(_, _ string, _ map[string]string) (*model.ChannelMember, *model.AppError)); ok {
+ return f(channelId, userId, notifications)
+ }
+ member, _ := ret.Get(0).(*model.ChannelMember)
+ err, _ := ret.Get(1).(*model.AppError)
+ return member, err
+}
+
+func (m *API) DeleteChannelMember(channelId, userId string) *model.AppError {
+ ret := m.Called(channelId, userId)
+ if f, ok := ret.Get(0).(func(_, _ string) *model.AppError); ok {
+ return f(channelId, userId)
+ }
+ err, _ := ret.Get(0).(*model.AppError)
+ return err
+}
+
func (m *API) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
ret := m.Called(post)
if f, ok := ret.Get(0).(func(*model.Post) (*model.Post, *model.AppError)); ok {
diff --git a/plugin/rpcplugin/api.go b/plugin/rpcplugin/api.go
index d87f65b55..c81bbb7c5 100644
--- a/plugin/rpcplugin/api.go
+++ b/plugin/rpcplugin/api.go
@@ -163,11 +163,33 @@ type APIGetGroupChannelArgs struct {
UserIds []string
}
+type APIAddChannelMemberArgs struct {
+ ChannelId string
+ UserId string
+}
+
type APIGetChannelMemberArgs struct {
ChannelId string
UserId string
}
+type APIUpdateChannelMemberRolesArgs struct {
+ ChannelId string
+ UserId string
+ NewRoles string
+}
+
+type APIUpdateChannelMemberNotificationsArgs struct {
+ ChannelId string
+ UserId string
+ Notifications map[string]string
+}
+
+type APIDeleteChannelMemberArgs struct {
+ ChannelId string
+ UserId string
+}
+
type APIChannelReply struct {
Channel *model.Channel
Error *model.AppError
@@ -239,6 +261,15 @@ func (api *LocalAPI) UpdateChannel(args *model.Channel, reply *APIChannelReply)
return nil
}
+func (api *LocalAPI) AddChannelMember(args *APIAddChannelMemberArgs, reply *APIChannelMemberReply) error {
+ member, err := api.api.AddChannelMember(args.ChannelId, args.UserId)
+ *reply = APIChannelMemberReply{
+ ChannelMember: member,
+ Error: err,
+ }
+ return nil
+}
+
func (api *LocalAPI) GetChannelMember(args *APIGetChannelMemberArgs, reply *APIChannelMemberReply) error {
member, err := api.api.GetChannelMember(args.ChannelId, args.UserId)
*reply = APIChannelMemberReply{
@@ -248,6 +279,32 @@ func (api *LocalAPI) GetChannelMember(args *APIGetChannelMemberArgs, reply *APIC
return nil
}
+func (api *LocalAPI) UpdateChannelMemberRoles(args *APIUpdateChannelMemberRolesArgs, reply *APIChannelMemberReply) error {
+ member, err := api.api.UpdateChannelMemberRoles(args.ChannelId, args.UserId, args.NewRoles)
+ *reply = APIChannelMemberReply{
+ ChannelMember: member,
+ Error: err,
+ }
+ return nil
+}
+
+func (api *LocalAPI) UpdateChannelMemberNotifications(args *APIUpdateChannelMemberNotificationsArgs, reply *APIChannelMemberReply) error {
+ member, err := api.api.UpdateChannelMemberNotifications(args.ChannelId, args.UserId, args.Notifications)
+ *reply = APIChannelMemberReply{
+ ChannelMember: member,
+ Error: err,
+ }
+ return nil
+}
+
+func (api *LocalAPI) DeleteChannelMember(args *APIDeleteChannelMemberArgs, reply *APIErrorReply) error {
+ err := api.api.DeleteChannelMember(args.ChannelId, args.UserId)
+ *reply = APIErrorReply{
+ Error: err,
+ }
+ return nil
+}
+
type APIPostReply struct {
Post *model.Post
Error *model.AppError
@@ -520,6 +577,17 @@ func (api *RemoteAPI) UpdateChannel(channel *model.Channel) (*model.Channel, *mo
return reply.Channel, reply.Error
}
+func (api *RemoteAPI) AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) {
+ var reply APIChannelMemberReply
+ if err := api.client.Call("LocalAPI.AddChannelMember", &APIAddChannelMemberArgs{
+ ChannelId: channelId,
+ UserId: userId,
+ }, &reply); err != nil {
+ return nil, model.NewAppError("RemoteAPI.AddChannelMember", "plugin.rpcplugin.invocation.error", nil, "err="+err.Error(), http.StatusInternalServerError)
+ }
+ return reply.ChannelMember, reply.Error
+}
+
func (api *RemoteAPI) GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) {
var reply APIChannelMemberReply
if err := api.client.Call("LocalAPI.GetChannelMember", &APIGetChannelMemberArgs{
@@ -531,6 +599,41 @@ func (api *RemoteAPI) GetChannelMember(channelId, userId string) (*model.Channel
return reply.ChannelMember, reply.Error
}
+func (api *RemoteAPI) UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError) {
+ var reply APIChannelMemberReply
+ if err := api.client.Call("LocalAPI.UpdateChannelMemberRoles", &APIUpdateChannelMemberRolesArgs{
+ ChannelId: channelId,
+ UserId: userId,
+ NewRoles: newRoles,
+ }, &reply); err != nil {
+ return nil, model.NewAppError("RemoteAPI.UpdateChannelMemberRoles", "plugin.rpcplugin.invocation.error", nil, "err="+err.Error(), http.StatusInternalServerError)
+ }
+ return reply.ChannelMember, reply.Error
+}
+
+func (api *RemoteAPI) UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError) {
+ var reply APIChannelMemberReply
+ if err := api.client.Call("LocalAPI.UpdateChannelMemberNotifications", &APIUpdateChannelMemberNotificationsArgs{
+ ChannelId: channelId,
+ UserId: userId,
+ Notifications: notifications,
+ }, &reply); err != nil {
+ return nil, model.NewAppError("RemoteAPI.UpdateChannelMemberNotifications", "plugin.rpcplugin.invocation.error", nil, "err="+err.Error(), http.StatusInternalServerError)
+ }
+ return reply.ChannelMember, reply.Error
+}
+
+func (api *RemoteAPI) DeleteChannelMember(channelId, userId string) *model.AppError {
+ var reply APIErrorReply
+ if err := api.client.Call("LocalAPI.DeleteChannelMember", &APIDeleteChannelMemberArgs{
+ ChannelId: channelId,
+ UserId: userId,
+ }, &reply); err != nil {
+ return model.NewAppError("RemoteAPI.DeleteChannelMember", "plugin.rpcplugin.invocation.error", nil, "err="+err.Error(), http.StatusInternalServerError)
+ }
+ return reply.Error
+}
+
func (api *RemoteAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
var reply APIPostReply
if err := api.client.Call("LocalAPI.CreatePost", post, &reply); err != nil {
diff --git a/plugin/rpcplugin/api_test.go b/plugin/rpcplugin/api_test.go
index 7fe7a0ff9..d7b3733ea 100644
--- a/plugin/rpcplugin/api_test.go
+++ b/plugin/rpcplugin/api_test.go
@@ -128,11 +128,32 @@ func TestAPI(t *testing.T) {
assert.Equal(t, testChannel, channel)
assert.Nil(t, err)
+ api.On("AddChannelMember", testChannel.Id, "theuserid").Return(testChannelMember, nil).Once()
+ member, err := remote.AddChannelMember(testChannel.Id, "theuserid")
+ assert.Equal(t, testChannelMember, member)
+ assert.Nil(t, err)
+
api.On("GetChannelMember", "thechannelid", "theuserid").Return(testChannelMember, nil).Once()
- member, err := remote.GetChannelMember("thechannelid", "theuserid")
+ member, err = remote.GetChannelMember("thechannelid", "theuserid")
+ assert.Equal(t, testChannelMember, member)
+ assert.Nil(t, err)
+
+ api.On("UpdateChannelMemberRoles", testChannel.Id, "theuserid", model.CHANNEL_ADMIN_ROLE_ID).Return(testChannelMember, nil).Once()
+ member, err = remote.UpdateChannelMemberRoles(testChannel.Id, "theuserid", model.CHANNEL_ADMIN_ROLE_ID)
assert.Equal(t, testChannelMember, member)
assert.Nil(t, err)
+ notifications := map[string]string{}
+ notifications[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_MARK_UNREAD_MENTION
+ api.On("UpdateChannelMemberNotifications", testChannel.Id, "theuserid", notifications).Return(testChannelMember, nil).Once()
+ member, err = remote.UpdateChannelMemberNotifications(testChannel.Id, "theuserid", notifications)
+ assert.Equal(t, testChannelMember, member)
+ assert.Nil(t, err)
+
+ api.On("DeleteChannelMember", "thechannelid", "theuserid").Return(nil).Once()
+ err = remote.DeleteChannelMember("thechannelid", "theuserid")
+ assert.Nil(t, err)
+
api.On("CreateUser", mock.AnythingOfType("*model.User")).Return(func(u *model.User) (*model.User, *model.AppError) {
u.Id = "theuserid"
return u, nil