Shared channels plugin APIs for MS Teams plugin (#25805)
New plugin APIs and hooks for accessing Shared Channels service via plugin. - RegisterPluginForSharedChannels(opts model.RegisterPluginOpts) (remoteID string, err error) - UnregisterPluginForSharedChannels(pluginID string) error - ShareChannel(sc *model.SharedChannel) (*model.SharedChannel, error) - UpdateSharedChannel(sc *model.SharedChannel) (*model.SharedChannel, error) - UnshareChannel(channelID string) (unshared bool, err error) - UpdateSharedChannelCursor(channelID, remoteID string, cusror model.GetPostsSinceForSyncCursor) error - SyncSharedChannel(channelID string) error - InviteRemoteToChannel(channelID string, remoteID string, userID string) error - UninviteRemoteFromChannel(channelID string, remoteID string) error Hooks - OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) - OnSharedChannelsPing(rc *model.RemoteCluster) bool
Этот коммит содержится в:
@@ -127,11 +127,13 @@ func (sp *ShareProvider) DoCommand(a *app.App, c request.CTX, args *model.Comman
|
||||
return responsef(args.T("api.command_share.permission_required", map[string]any{"Permission": "manage_shared_channels"}))
|
||||
}
|
||||
|
||||
if a.Srv().GetSharedChannelSyncService() == nil {
|
||||
syncService := a.Srv().GetSharedChannelSyncService()
|
||||
if syncService == nil || !syncService.Active() {
|
||||
return responsef(args.T("api.command_share.service_disabled"))
|
||||
}
|
||||
|
||||
if a.Srv().GetRemoteClusterService() == nil {
|
||||
rcService := a.Srv().GetRemoteClusterService()
|
||||
if rcService == nil || !rcService.Active() {
|
||||
return responsef(args.T("api.command_remote.service_disabled"))
|
||||
}
|
||||
|
||||
@@ -157,7 +159,7 @@ func (sp *ShareProvider) DoCommand(a *app.App, c request.CTX, args *model.Comman
|
||||
}
|
||||
|
||||
func (sp *ShareProvider) doShareChannel(a *app.App, c request.CTX, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
|
||||
// check that channel exists.
|
||||
// fetch defaults for missing channel props
|
||||
channel, errApp := a.GetChannel(c, args.ChannelId)
|
||||
if errApp != nil {
|
||||
return responsef(args.T("api.command_share.share_channel.error", map[string]any{"Error": errApp.Error()}))
|
||||
@@ -196,22 +198,15 @@ func (sp *ShareProvider) doShareChannel(a *app.App, c request.CTX, args *model.C
|
||||
CreatorId: args.UserId,
|
||||
}
|
||||
|
||||
if _, err := a.SaveSharedChannel(c, sc); err != nil {
|
||||
if _, err := a.ShareChannel(c, sc); err != nil {
|
||||
return responsef(args.T("api.command_share.share_channel.error", map[string]any{"Error": err.Error()}))
|
||||
}
|
||||
|
||||
notifyClientsForChannelUpdate(a, sc)
|
||||
|
||||
return responsef("##### " + args.T("api.command_share.channel_shared"))
|
||||
}
|
||||
|
||||
func (sp *ShareProvider) doUnshareChannel(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
|
||||
sc, appErr := a.GetSharedChannel(args.ChannelId)
|
||||
if appErr != nil {
|
||||
return responsef(args.T("api.command_share.shared_channel_unshare.error", map[string]any{"Error": appErr.Error()}))
|
||||
}
|
||||
|
||||
deleted, err := a.DeleteSharedChannel(args.ChannelId)
|
||||
deleted, err := a.UnshareChannel(args.ChannelId)
|
||||
if err != nil {
|
||||
return responsef(args.T("api.command_share.shared_channel_unshare.error", map[string]any{"Error": err.Error()}))
|
||||
}
|
||||
@@ -219,8 +214,6 @@ func (sp *ShareProvider) doUnshareChannel(a *app.App, args *model.CommandArgs, m
|
||||
return responsef(args.T("api.command_share.not_shared_channel_unshare"))
|
||||
}
|
||||
|
||||
notifyClientsForChannelUpdate(a, sc)
|
||||
|
||||
return responsef("##### " + args.T("api.command_share.shared_channel_unavailable"))
|
||||
}
|
||||
|
||||
@@ -241,7 +234,7 @@ func (sp *ShareProvider) doInviteRemote(a *app.App, c request.CTX, args *model.C
|
||||
// Check if channel is shared or not.
|
||||
hasChan, err := a.HasSharedChannel(args.ChannelId)
|
||||
if err != nil {
|
||||
return responsef(args.T("api.command_share.check_channel_exist.error", map[string]any{"Error": err.Error()}))
|
||||
return responsef(args.T("api.command_share.check_channel_exist.error", map[string]any{"ChannelID": args.ChannelId, "Error": err.Error()}))
|
||||
}
|
||||
if !hasChan {
|
||||
// If it doesn't exist, then create it.
|
||||
@@ -253,24 +246,13 @@ func (sp *ShareProvider) doInviteRemote(a *app.App, c request.CTX, args *model.C
|
||||
}()
|
||||
}
|
||||
|
||||
// don't allow invitation to shared channel originating from remote.
|
||||
// (also blocks cyclic invitations)
|
||||
if err := a.CheckCanInviteToSharedChannel(args.ChannelId); err != nil {
|
||||
return responsef(args.T("api.command_share.channel_invite_not_home.error"))
|
||||
}
|
||||
|
||||
rc, appErr := a.GetRemoteCluster(remoteID)
|
||||
if appErr != nil {
|
||||
return responsef(args.T("api.command_share.remote_id_invalid.error", map[string]any{"Error": appErr.Error()}))
|
||||
}
|
||||
|
||||
channel, errApp := a.GetChannel(c, args.ChannelId)
|
||||
if errApp != nil {
|
||||
return responsef(args.T("api.command_share.channel_invite.error", map[string]any{"Name": rc.DisplayName, "Error": errApp.Error()}))
|
||||
}
|
||||
// send channel invite to remote cluster
|
||||
if err := a.Srv().GetSharedChannelSyncService().SendChannelInvite(channel, args.UserId, rc); err != nil {
|
||||
return responsef(args.T("api.command_share.channel_invite.error", map[string]any{"Name": rc.DisplayName, "Error": err.Error()}))
|
||||
if err = a.InviteRemoteToChannel(args.ChannelId, remoteID, args.UserId); err != nil {
|
||||
return responsef(appErr.Error())
|
||||
}
|
||||
|
||||
return responsef("##### " + args.T("api.command_share.invitation_sent", map[string]any{"Name": rc.DisplayName, "SiteURL": rc.SiteURL}))
|
||||
@@ -282,15 +264,11 @@ func (sp *ShareProvider) doUninviteRemote(a *app.App, args *model.CommandArgs, m
|
||||
return responsef(args.T("api.command_share.remote_not_valid"))
|
||||
}
|
||||
|
||||
scr, err := a.GetSharedChannelRemoteByIds(args.ChannelId, remoteID)
|
||||
if err != nil || scr.ChannelId != args.ChannelId {
|
||||
return responsef(args.T("api.command_share.channel_remote_id_not_exists", map[string]any{"RemoteId": remoteID}))
|
||||
err := a.UninviteRemoteFromChannel(args.ChannelId, remoteID)
|
||||
if err != nil {
|
||||
return responsef(err.Error())
|
||||
}
|
||||
|
||||
deleted, err := a.DeleteSharedChannelRemote(scr.Id)
|
||||
if err != nil || !deleted {
|
||||
return responsef(args.T("api.command_share.could_not_uninvite.error", map[string]any{"RemoteId": remoteID, "Error": err.Error()}))
|
||||
}
|
||||
return responsef("##### " + args.T("api.command_share.remote_uninvited", map[string]any{"RemoteId": remoteID}))
|
||||
}
|
||||
|
||||
@@ -323,9 +301,3 @@ func (sp *ShareProvider) doStatus(a *app.App, args *model.CommandArgs, _ map[str
|
||||
}
|
||||
return responsef(sb.String())
|
||||
}
|
||||
|
||||
func notifyClientsForChannelUpdate(a *app.App, sharedChannel *model.SharedChannel) {
|
||||
messageWs := model.NewWebSocketEvent(model.WebsocketEventChannelConverted, sharedChannel.TeamId, "", "", nil, "")
|
||||
messageWs.Add("channel_id", sharedChannel.ChannelId)
|
||||
a.Publish(messageWs)
|
||||
}
|
||||
|
||||
@@ -26,15 +26,19 @@ func TestShareProviderDoCommand(t *testing.T) {
|
||||
|
||||
th.addPermissionToRole(model.PermissionManageSharedChannels.Id, th.BasicUser.Roles)
|
||||
|
||||
mockSyncService := app.NewMockSharedChannelService(nil)
|
||||
mockSyncService := app.NewMockSharedChannelService(nil, app.MockOptionSharedChannelServiceWithActive(true))
|
||||
th.Server.SetSharedChannelSyncService(mockSyncService)
|
||||
mockRemoteCluster, err := remotecluster.NewRemoteClusterService(th.Server)
|
||||
remoteClusterService, err := remotecluster.NewRemoteClusterService(th.Server, th.App)
|
||||
require.NoError(t, err)
|
||||
|
||||
th.Server.SetRemoteClusterService(mockRemoteCluster)
|
||||
th.Server.SetRemoteClusterService(remoteClusterService)
|
||||
testCluster := &testlib.FakeClusterInterface{}
|
||||
th.Server.Platform().SetCluster(testCluster)
|
||||
|
||||
err = remoteClusterService.Start()
|
||||
require.NoError(t, err)
|
||||
defer remoteClusterService.Shutdown()
|
||||
|
||||
commandProvider := ShareProvider{}
|
||||
channel := th.CreateChannel(th.BasicTeam, WithShared(false))
|
||||
|
||||
@@ -53,7 +57,7 @@ func TestShareProviderDoCommand(t *testing.T) {
|
||||
event, err := model.WebSocketEventFromJSON(bytes.NewReader(msg.Data))
|
||||
return err == nil && event.EventType() == model.WebsocketEventChannelConverted
|
||||
})
|
||||
assert.Len(t, channelConvertedMessages, 1)
|
||||
assert.Len(t, channelConvertedMessages, 1) // one msg for share creation
|
||||
})
|
||||
|
||||
t.Run("unshare command sends a websocket channel converted event", func(t *testing.T) {
|
||||
@@ -64,13 +68,17 @@ func TestShareProviderDoCommand(t *testing.T) {
|
||||
|
||||
mockSyncService := app.NewMockSharedChannelService(nil)
|
||||
th.Server.SetSharedChannelSyncService(mockSyncService)
|
||||
mockRemoteCluster, err := remotecluster.NewRemoteClusterService(th.Server)
|
||||
remoteClusterService, err := remotecluster.NewRemoteClusterService(th.Server, th.App)
|
||||
require.NoError(t, err)
|
||||
|
||||
th.Server.SetRemoteClusterService(mockRemoteCluster)
|
||||
th.Server.SetRemoteClusterService(remoteClusterService)
|
||||
testCluster := &testlib.FakeClusterInterface{}
|
||||
th.Server.Platform().SetCluster(testCluster)
|
||||
|
||||
err = remoteClusterService.Start()
|
||||
require.NoError(t, err)
|
||||
defer remoteClusterService.Shutdown()
|
||||
|
||||
commandProvider := ShareProvider{}
|
||||
channel := th.CreateChannel(th.BasicTeam, WithShared(true))
|
||||
args := &model.CommandArgs{
|
||||
@@ -88,6 +96,6 @@ func TestShareProviderDoCommand(t *testing.T) {
|
||||
event, err := model.WebSocketEventFromJSON(bytes.NewReader(msg.Data))
|
||||
return err == nil && event.EventType() == model.WebsocketEventChannelConverted
|
||||
})
|
||||
require.Len(t, channelConvertedMessages, 1)
|
||||
require.Len(t, channelConvertedMessages, 2) // one msg for share creation, one for unshare.
|
||||
})
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ func (th *TestHelper) createChannel(team *model.Team, channelType model.ChannelT
|
||||
|
||||
if channel.IsShared() {
|
||||
id := model.NewId()
|
||||
_, err := th.App.SaveSharedChannel(th.Context, &model.SharedChannel{
|
||||
_, err := th.App.ShareChannel(th.Context, &model.SharedChannel{
|
||||
ChannelId: channel.Id,
|
||||
TeamId: channel.TeamId,
|
||||
Home: false,
|
||||
|
||||
Ссылка в новой задаче
Block a user