MM-33903 rename slash commands & permission (#17494)

- rename slash commands
    - "remote" -> "secure-connection"
    - "share" -> "share-channel"
- change status icons to text (translated)
- remove channel invite "Description" field
- rename permission "manage_remote_clusters" -> "manage_secure_connections"
Этот коммит содержится в:
Doug Lauder
2021-04-30 14:59:29 -04:00
коммит произвёл GitHub
родитель a7e6eef836
Коммит e2b9cb98aa
20 изменённых файлов: 243 добавлений и 331 удалений

Просмотреть файл

@@ -182,7 +182,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
"system_admin": allPermissionIDs, "system_admin": allPermissionIDs,
} }
assert.Contains(t, allPermissionIDs, model.PERMISSION_MANAGE_SHARED_CHANNELS.Id, "manage_shared_channels permission not found") assert.Contains(t, allPermissionIDs, model.PERMISSION_MANAGE_SHARED_CHANNELS.Id, "manage_shared_channels permission not found")
assert.Contains(t, allPermissionIDs, model.PERMISSION_MANAGE_REMOTE_CLUSTERS.Id, "manage_remote_clusters permission not found") assert.Contains(t, allPermissionIDs, model.PERMISSION_MANAGE_SECURE_CONNECTIONS.Id, "manage_secure_connections permission not found")
// Check the migration matches what's expected. // Check the migration matches what's expected.
for name, permissions := range expected1 { for name, permissions := range expected1 {

Просмотреть файл

@@ -70,7 +70,8 @@ const (
PermissionReadPrivateChannelGroups = "read_private_channel_groups" PermissionReadPrivateChannelGroups = "read_private_channel_groups"
PermissionEditBrand = "edit_brand" PermissionEditBrand = "edit_brand"
PermissionManageSharedChannels = "manage_shared_channels" PermissionManageSharedChannels = "manage_shared_channels"
PermissionManageRemoteClusters = "manage_remote_clusters" PermissionManageSecureConnections = "manage_secure_connections"
PermissionManageRemoteClusters = "manage_remote_clusters" // deprecated; use `manage_secure_connections`
) )
func isRole(roleName string) func(*model.Role, map[string]map[string]bool) bool { func isRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
@@ -525,13 +526,24 @@ func (a *App) getBillingPermissionsMigration() (permissionsMap, error) {
}, nil }, nil
} }
func (a *App) getAddManageRemoteClustersPermissionsMigration() (permissionsMap, error) { func (a *App) getAddManageSecureConnectionsPermissionsMigration() (permissionsMap, error) {
return permissionsMap{ transformations := []permissionTransformation{}
// add the new permission to system admin
transformations = append(transformations,
permissionTransformation{ permissionTransformation{
On: isRole(model.SYSTEM_ADMIN_ROLE_ID), On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
Add: []string{PermissionManageRemoteClusters}, Add: []string{PermissionManageSecureConnections},
}, })
}, nil
// remote the decprecated permission from system admin
transformations = append(transformations,
permissionTransformation{
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
Remove: []string{PermissionManageRemoteClusters},
})
return transformations, nil
} }
func (a *App) getAddDownloadComplianceExportResult() (permissionsMap, error) { func (a *App) getAddDownloadComplianceExportResult() (permissionsMap, error) {
@@ -910,7 +922,7 @@ func (a *App) DoPermissionsMigrations() error {
{Key: model.MIGRATION_KEY_ADD_SYSTEM_CONSOLE_PERMISSIONS, Migration: a.getAddSystemConsolePermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_SYSTEM_CONSOLE_PERMISSIONS, Migration: a.getAddSystemConsolePermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_CONVERT_CHANNEL_PERMISSIONS, Migration: a.getAddConvertChannelPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_CONVERT_CHANNEL_PERMISSIONS, Migration: a.getAddConvertChannelPermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS, Migration: a.getAddManageSharedChannelsPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS, Migration: a.getAddManageSharedChannelsPermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS, Migration: a.getAddManageRemoteClustersPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_MANAGE_SECURE_CONNECTIONS_PERMISSIONS, Migration: a.getAddManageSecureConnectionsPermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS, Migration: a.getSystemRolesPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS, Migration: a.getSystemRolesPermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_BILLING_PERMISSIONS, Migration: a.getBillingPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_BILLING_PERMISSIONS, Migration: a.getBillingPermissionsMigration},
{Key: model.MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS, Migration: a.getAddDownloadComplianceExportResult}, {Key: model.MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS, Migration: a.getAddDownloadComplianceExportResult},

Просмотреть файл

@@ -10,19 +10,20 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/shared/i18n"
) )
func TestAddRemoteCluster(t *testing.T) { func TestAddRemoteCluster(t *testing.T) {
t.Run("adding remote cluster with duplicate site url and remote team id", func(t *testing.T) { th := Setup(t).InitBasic()
th := Setup(t).InitBasic() defer th.TearDown()
defer th.TearDown()
t.Run("adding remote cluster with duplicate site url and remote team id", func(t *testing.T) {
remoteCluster := &model.RemoteCluster{ remoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test1",
SiteURL: "http://localhost:8065", SiteURL: "http://www1.example.com:8065",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }
@@ -33,19 +34,16 @@ func TestAddRemoteCluster(t *testing.T) {
remoteCluster.RemoteId = model.NewId() remoteCluster.RemoteId = model.NewId()
_, err = th.App.AddRemoteCluster(remoteCluster) _, err = th.App.AddRemoteCluster(remoteCluster)
require.NotNil(t, err, "Adding a duplicate remote cluster should error") require.NotNil(t, err, "Adding a duplicate remote cluster should error")
assert.Contains(t, err.Error(), "Remote cluster has already been added.") assert.Contains(t, err.Error(), i18n.T("api.remote_cluster.save_not_unique.app_error"))
}) })
t.Run("adding remote cluster with duplicate site url or remote team id is allowed", func(t *testing.T) { t.Run("adding remote cluster with duplicate site url or remote team id is allowed", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
remoteCluster := &model.RemoteCluster{ remoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test2",
SiteURL: "http://localhost:8065", SiteURL: "http://www2.exmaple.com:8065",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }
@@ -70,26 +68,26 @@ func TestAddRemoteCluster(t *testing.T) {
} }
func TestUpdateRemoteCluster(t *testing.T) { func TestUpdateRemoteCluster(t *testing.T) {
t.Run("update remote cluster with an already existing site url and team id", func(t *testing.T) { th := Setup(t).InitBasic()
th := Setup(t).InitBasic() defer th.TearDown()
defer th.TearDown()
t.Run("update remote cluster with an already existing site url and team id", func(t *testing.T) {
remoteCluster := &model.RemoteCluster{ remoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test3",
SiteURL: "http://localhost:8065", SiteURL: "http://www3.exmaple.com:8065",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }
otherRemoteCluster := &model.RemoteCluster{ otherRemoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test4",
SiteURL: "http://localhost:8066", SiteURL: "http://www4.example.com:8066",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }
@@ -104,29 +102,26 @@ func TestUpdateRemoteCluster(t *testing.T) {
savedRemoteClustered.RemoteTeamId = remoteCluster.RemoteTeamId savedRemoteClustered.RemoteTeamId = remoteCluster.RemoteTeamId
_, err = th.App.UpdateRemoteCluster(savedRemoteClustered) _, err = th.App.UpdateRemoteCluster(savedRemoteClustered)
require.NotNil(t, err, "Updating remote cluster with duplicate site url should error") require.NotNil(t, err, "Updating remote cluster with duplicate site url should error")
assert.Contains(t, err.Error(), "Remote cluster with the same url already exists.") assert.Contains(t, err.Error(), i18n.T("api.remote_cluster.update_not_unique.app_error"))
}) })
t.Run("update remote cluster with an already existing site url or team id, is allowed", func(t *testing.T) { t.Run("update remote cluster with an already existing site url or team id, is allowed", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
remoteCluster := &model.RemoteCluster{ remoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test5",
SiteURL: "http://localhost:8065", SiteURL: "http://www5.example.com:8065",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }
otherRemoteCluster := &model.RemoteCluster{ otherRemoteCluster := &model.RemoteCluster{
RemoteTeamId: model.NewId(), RemoteTeamId: model.NewId(),
Name: "test", Name: "test6",
SiteURL: "http://localhost:8066", SiteURL: "http://www6.example.com:8065",
Token: "test", Token: model.NewId(),
RemoteToken: "test", RemoteToken: model.NewId(),
Topics: "", Topics: "",
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
} }

Просмотреть файл

@@ -117,7 +117,7 @@ func handleInvitation(s *Server, syncService SharedChannelServiceIFace, event *m
return errors.Wrap(err, fmt.Sprintf("couldn't find remote cluster %s, for creating shared channel invitation for a DM", *participant.RemoteId)) return errors.Wrap(err, fmt.Sprintf("couldn't find remote cluster %s, for creating shared channel invitation for a DM", *participant.RemoteId))
} }
return syncService.SendChannelInvite(channel, creator.Id, "", rc, sharedchannel.WithDirectParticipantID(creator.Id), sharedchannel.WithDirectParticipantID(participant.Id)) return syncService.SendChannelInvite(channel, creator.Id, rc, sharedchannel.WithDirectParticipantID(creator.Id), sharedchannel.WithDirectParticipantID(participant.Id))
} }
func getUserFromEvent(s *Server, event *model.WebSocketEvent, key string) (*model.User, error) { func getUserFromEvent(s *Server, event *model.WebSocketEvent, key string) (*model.User, error) {

Просмотреть файл

@@ -13,7 +13,7 @@ type SharedChannelServiceIFace interface {
Shutdown() error Shutdown() error
Start() error Start() error
NotifyChannelChanged(channelId string) NotifyChannelChanged(channelId string)
SendChannelInvite(channel *model.Channel, userId string, description string, rc *model.RemoteCluster, options ...sharedchannel.InviteOption) error SendChannelInvite(channel *model.Channel, userId string, rc *model.RemoteCluster, options ...sharedchannel.InviteOption) error
Active() bool Active() bool
} }
@@ -56,7 +56,7 @@ func (mrcs *mockSharedChannelService) Active() bool {
return mrcs.active return mrcs.active
} }
func (mrcs *mockSharedChannelService) SendChannelInvite(channel *model.Channel, userId string, description string, rc *model.RemoteCluster, options ...sharedchannel.InviteOption) error { func (mrcs *mockSharedChannelService) SendChannelInvite(channel *model.Channel, userId string, rc *model.RemoteCluster, options ...sharedchannel.InviteOption) error {
mrcs.numInvitations += 1 mrcs.numInvitations += 1
return nil return nil
} }

Просмотреть файл

@@ -15,14 +15,14 @@ import (
) )
const ( const (
AvailableRemoteActions = "invite, accept, remove, status" AvailableRemoteActions = "create, accept, remove, status"
) )
type RemoteProvider struct { type RemoteProvider struct {
} }
const ( const (
CommandTriggerRemote = "remote" CommandTriggerRemote = "secure-connection"
) )
func init() { func init() {
@@ -37,23 +37,23 @@ func (rp *RemoteProvider) GetCommand(a *app.App, T i18n.TranslateFunc) *model.Co
remote := model.NewAutocompleteData(rp.GetTrigger(), "[action]", T("api.command_remote.remote_add_remove.help", map[string]interface{}{"Actions": AvailableRemoteActions})) remote := model.NewAutocompleteData(rp.GetTrigger(), "[action]", T("api.command_remote.remote_add_remove.help", map[string]interface{}{"Actions": AvailableRemoteActions}))
invite := model.NewAutocompleteData("invite", "", T("api.command_remote.invite.help")) create := model.NewAutocompleteData("create", "", T("api.command_remote.invite.help"))
invite.AddNamedTextArgument("password", T("api.command_remote.invite_password.help"), T("api.command_remote.invite_password.hint"), "", true) create.AddNamedTextArgument("name", T("api.command_remote.name.help"), T("api.command_remote.name.hint"), "", true)
invite.AddNamedTextArgument("name", T("api.command_remote.name.help"), T("api.command_remote.name.hint"), "", true) create.AddNamedTextArgument("displayname", T("api.command_remote.displayname.help"), T("api.command_remote.displayname.hint"), "", false)
invite.AddNamedTextArgument("displayname", T("api.command_remote.displayname.help"), T("api.command_remote.displayname.hint"), "", false) create.AddNamedTextArgument("password", T("api.command_remote.invite_password.help"), T("api.command_remote.invite_password.hint"), "", true)
accept := model.NewAutocompleteData("accept", "", T("api.command_remote.accept.help")) accept := model.NewAutocompleteData("accept", "", T("api.command_remote.accept.help"))
accept.AddNamedTextArgument("password", T("api.command_remote.invite_password.help"), T("api.command_remote.invite_password.hint"), "", true)
accept.AddNamedTextArgument("name", T("api.command_remote.name.help"), T("api.command_remote.name.hint"), "", true) accept.AddNamedTextArgument("name", T("api.command_remote.name.help"), T("api.command_remote.name.hint"), "", true)
accept.AddNamedTextArgument("displayname", T("api.command_remote.displayname.help"), T("api.command_remote.displayname.hint"), "", false) accept.AddNamedTextArgument("displayname", T("api.command_remote.displayname.help"), T("api.command_remote.displayname.hint"), "", false)
accept.AddNamedTextArgument("password", T("api.command_remote.invite_password.help"), T("api.command_remote.invite_password.hint"), "", true)
accept.AddNamedTextArgument("invite", T("api.command_remote.invitation.help"), T("api.command_remote.invitation.hint"), "", true) accept.AddNamedTextArgument("invite", T("api.command_remote.invitation.help"), T("api.command_remote.invitation.hint"), "", true)
remove := model.NewAutocompleteData("remove", "", T("api.command_remote.remove.help")) remove := model.NewAutocompleteData("remove", "", T("api.command_remote.remove.help"))
remove.AddNamedDynamicListArgument("remoteId", T("api.command_remote.remove_remote_id.help"), "builtin:remote", true) remove.AddNamedDynamicListArgument("connectionID", T("api.command_remote.remove_remote_id.help"), "builtin:"+CommandTriggerRemote, true)
status := model.NewAutocompleteData("status", "", T("api.command_remote.status.help")) status := model.NewAutocompleteData("status", "", T("api.command_remote.status.help"))
remote.AddCommand(invite) remote.AddCommand(create)
remote.AddCommand(accept) remote.AddCommand(accept)
remote.AddCommand(remove) remote.AddCommand(remove)
remote.AddCommand(status) remote.AddCommand(status)
@@ -69,8 +69,8 @@ func (rp *RemoteProvider) GetCommand(a *app.App, T i18n.TranslateFunc) *model.Co
} }
func (rp *RemoteProvider) DoCommand(a *app.App, args *model.CommandArgs, message string) *model.CommandResponse { func (rp *RemoteProvider) DoCommand(a *app.App, args *model.CommandArgs, message string) *model.CommandResponse {
if !a.HasPermissionTo(args.UserId, model.PERMISSION_MANAGE_SHARED_CHANNELS) { if !a.HasPermissionTo(args.UserId, model.PERMISSION_MANAGE_SECURE_CONNECTIONS) {
return responsef(args.T("api.command_remote.permission_required", map[string]interface{}{"Permission": "manage_shared_channels"})) return responsef(args.T("api.command_remote.permission_required", map[string]interface{}{"Permission": "manage_secure_connections"}))
} }
margs := parseNamedArgs(args.Command) margs := parseNamedArgs(args.Command)
@@ -80,8 +80,8 @@ func (rp *RemoteProvider) DoCommand(a *app.App, args *model.CommandArgs, message
} }
switch action { switch action {
case "invite": case "create":
return rp.doInvite(a, args, margs) return rp.doCreate(a, args, margs)
case "accept": case "accept":
return rp.doAccept(a, args, margs) return rp.doAccept(a, args, margs)
case "remove": case "remove":
@@ -94,19 +94,19 @@ func (rp *RemoteProvider) DoCommand(a *app.App, args *model.CommandArgs, message
} }
func (rp *RemoteProvider) GetAutoCompleteListItems(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error) { func (rp *RemoteProvider) GetAutoCompleteListItems(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error) {
if !a.HasPermissionTo(commandArgs.UserId, model.PERMISSION_MANAGE_SHARED_CHANNELS) { if !a.HasPermissionTo(commandArgs.UserId, model.PERMISSION_MANAGE_SECURE_CONNECTIONS) {
return nil, errors.New("You require `manage_shared_channels` permission to manage remote clusters.") return nil, errors.New("You require `manage_secure_connections` permission to manage secure connections.")
} }
if arg.Name == "remoteId" && strings.Contains(parsed, " remove ") { if arg.Name == "connectionID" && strings.Contains(parsed, " remove ") {
return getRemoteClusterAutocompleteListItems(a, true) return getRemoteClusterAutocompleteListItems(a, true)
} }
return nil, fmt.Errorf("`%s` is not a dynamic argument", arg.Name) return nil, fmt.Errorf("`%s` is not a dynamic argument", arg.Name)
} }
// doInvite creates and displays an encrypted invite that can be used by a remote site to establish a simple trust. // doCreate creates and displays an encrypted invite that can be used by a remote site to establish a simple trust.
func (rp *RemoteProvider) doInvite(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse { func (rp *RemoteProvider) doCreate(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
password := margs["password"] password := margs["password"]
if password == "" { if password == "" {
return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "password"})) return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "password"}))
@@ -153,7 +153,7 @@ func (rp *RemoteProvider) doInvite(a *app.App, args *model.CommandArgs, margs ma
encoded := base64.URLEncoding.EncodeToString(encrypted) encoded := base64.URLEncoding.EncodeToString(encrypted)
return responsef("##### " + args.T("api.command_remote.invitation_created") + "\n" + return responsef("##### " + args.T("api.command_remote.invitation_created") + "\n" +
args.T("api.command_remote.invite_summary", map[string]interface{}{"Command": "/remote accept", "Invitation": encoded, "SiteURL": invite.SiteURL})) args.T("api.command_remote.invite_summary", map[string]interface{}{"Command": "/secure-connection accept", "Invitation": encoded, "SiteURL": invite.SiteURL}))
} }
// doAccept accepts an invitation generated by a remote site. // doAccept accepts an invitation generated by a remote site.
@@ -209,7 +209,7 @@ func (rp *RemoteProvider) doAccept(a *app.App, args *model.CommandArgs, margs ma
// doRemove removes a remote cluster from the database, effectively revoking the trust relationship. // doRemove removes a remote cluster from the database, effectively revoking the trust relationship.
func (rp *RemoteProvider) doRemove(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse { func (rp *RemoteProvider) doRemove(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
id, ok := margs["remoteId"] id, ok := margs["connectionID"]
if !ok { if !ok {
return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "remoteId"})) return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "remoteId"}))
} }
@@ -238,23 +238,16 @@ func (rp *RemoteProvider) doStatus(a *app.App, args *model.CommandArgs, _ map[st
} }
var sb strings.Builder var sb strings.Builder
fmt.Fprintf(&sb, args.T("api.command_remote.remote_table_header")+"| \n") fmt.Fprintf(&sb, args.T("api.command_remote.remote_table_header")+" \n")
fmt.Fprintf(&sb, "| ---- | -------- | ---------- | :-------------: | :----: | ---------- |\n") // | Secure Connection | Display name | ConnectionID | Site URL | Invite accepted | Online | Last ping |
fmt.Fprintf(&sb, "| :---- | :---- | :---- | :---- | :---- | :---- | :---- | \n")
for _, rc := range list { for _, rc := range list {
accepted := ":white_check_mark:" accepted := formatBool(args.T, rc.SiteURL != "")
if rc.SiteURL == "" { online := formatBool(args.T, isOnline(rc.LastPingAt))
accepted = ":x:" lastPing := formatTimestamp(rc.LastPingAt)
}
online := ":white_check_mark:" fmt.Fprintf(&sb, "| %s | %s | %s | %s | %s | %s | %s |\n", rc.Name, rc.DisplayName, rc.RemoteId, rc.SiteURL, accepted, online, lastPing)
if !isOnline(rc.LastPingAt) {
online = ":skull_and_crossbones:"
}
lastPing := formatTimestamp(model.GetTimeForMillis(rc.LastPingAt))
fmt.Fprintf(&sb, "| %s | %s | %s | %s | %s | %s | %s |\n", rc.Name, rc.DisplayName, rc.SiteURL, rc.RemoteId, accepted, online, lastPing)
} }
return responsef(sb.String()) return responsef(sb.String())
} }

Просмотреть файл

@@ -17,8 +17,8 @@ type ShareProvider struct {
} }
const ( const (
CommandTriggerShare = "share" CommandTriggerShare = "share-channel"
AvailableShareActions = "share_channel, unshare_channel, invite_remove, uninvite_remote, status" AvailableShareActions = "invite, uninvite, unshare, status"
) )
func init() { func init() {
@@ -32,29 +32,20 @@ func (sp *ShareProvider) GetTrigger() string {
func (sp *ShareProvider) GetCommand(a *app.App, T i18n.TranslateFunc) *model.Command { func (sp *ShareProvider) GetCommand(a *app.App, T i18n.TranslateFunc) *model.Command {
share := model.NewAutocompleteData(CommandTriggerShare, "[action]", T("api.command_share.available_actions", map[string]interface{}{"Actions": AvailableShareActions})) share := model.NewAutocompleteData(CommandTriggerShare, "[action]", T("api.command_share.available_actions", map[string]interface{}{"Actions": AvailableShareActions}))
shareChannel := model.NewAutocompleteData("share_channel", "", T("api.command_share.share_current")) inviteRemote := model.NewAutocompleteData("invite", "", T("api.command_share.invite_remote.help"))
shareChannel.AddNamedTextArgument("readonly", T("api.command_share.share_read_only.help"), T("api.command_share.share_read_only.hint"), "Y|N|y|n", false) inviteRemote.AddNamedDynamicListArgument("connectionID", T("api.command_share.remote_id.help"), "builtin:"+CommandTriggerShare, true)
shareChannel.AddNamedTextArgument("name", T("api.command_share.channel_name.help"), T("api.command_share.channel_name.hint"), "", false) inviteRemote.AddNamedTextArgument("readonly", T("api.command_share.share_read_only.help"), T("api.command_share.share_read_only.hint"), "Y|N|y|n", false)
shareChannel.AddNamedTextArgument("displayname", T("api.command_share.channel_display_name.help"), T("api.command_share.channel_display_name.hint"), "", false)
shareChannel.AddNamedTextArgument("purpose", T("api.command_share.channel_purpose.help"), T("api.command_share.channel_purpose.hint"), "", false)
shareChannel.AddNamedTextArgument("header", T("api.command_share.channel_header.help"), T("api.command_share.channel_header.hint"), "", false)
unshareChannel := model.NewAutocompleteData("unshare_channel", "", T("api.command_share.unshare_channel.help")) unInviteRemote := model.NewAutocompleteData("uninvite", "", T("api.command_share.uninvite_remote.help"))
unshareChannel.AddNamedTextArgument("are_you_sure", T("api.command_share.unshare_confirmation.help"), T("api.command_share.unshare_confirmation.hint"), "Y|N|y|n", true) unInviteRemote.AddNamedDynamicListArgument("connectionID", T("api.command_share.uninvite_remote_id.help"), "builtin:"+CommandTriggerShare, true)
inviteRemote := model.NewAutocompleteData("invite_remote", "", T("api.command_share.invite_remote.help")) unshareChannel := model.NewAutocompleteData("unshare", "", T("api.command_share.unshare_channel.help"))
inviteRemote.AddNamedDynamicListArgument("remoteId", T("api.command_share.remote_id.help"), "builtin:share", true)
inviteRemote.AddNamedTextArgument("description", T("api.command_share.description_invite.help"), T("api.command_share.description_invite.hint"), "", false)
unInviteRemote := model.NewAutocompleteData("uninvite_remote", "", T("api.command_share.uninvite_remote.help"))
unInviteRemote.AddNamedDynamicListArgument("remoteId", T("api.command_share.uninvite_remote_id.help"), "builtin:share", true)
status := model.NewAutocompleteData("status", "", T("api.command_share.channel_status.help")) status := model.NewAutocompleteData("status", "", T("api.command_share.channel_status.help"))
share.AddCommand(shareChannel)
share.AddCommand(unshareChannel)
share.AddCommand(inviteRemote) share.AddCommand(inviteRemote)
share.AddCommand(unInviteRemote) share.AddCommand(unInviteRemote)
share.AddCommand(unshareChannel)
share.AddCommand(status) share.AddCommand(status)
return &model.Command{ return &model.Command{
@@ -69,15 +60,15 @@ func (sp *ShareProvider) GetCommand(a *app.App, T i18n.TranslateFunc) *model.Com
func (sp *ShareProvider) GetAutoCompleteListItems(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error) { func (sp *ShareProvider) GetAutoCompleteListItems(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error) {
switch { switch {
case strings.Contains(parsed, " share_channel "): case strings.Contains(parsed, " share "):
return sp.getAutoCompleteShareChannel(a, commandArgs, arg) return sp.getAutoCompleteShareChannel(a, commandArgs, arg)
case strings.Contains(parsed, " invite_remote "): case strings.Contains(parsed, " invite "):
return sp.getAutoCompleteInviteRemote(a, commandArgs, arg) return sp.getAutoCompleteInviteRemote(a, commandArgs, arg)
case strings.Contains(parsed, " uninvite_remote "): case strings.Contains(parsed, " uninvite "):
return sp.getAutoCompleteUnInviteRemote(a, commandArgs, arg) return sp.getAutoCompleteUnInviteRemote(a, commandArgs, arg)
@@ -112,7 +103,7 @@ func (sp *ShareProvider) getAutoCompleteShareChannel(a *app.App, commandArgs *mo
func (sp *ShareProvider) getAutoCompleteInviteRemote(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg) ([]model.AutocompleteListItem, error) { func (sp *ShareProvider) getAutoCompleteInviteRemote(a *app.App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg) ([]model.AutocompleteListItem, error) {
switch arg.Name { switch arg.Name {
case "remoteId": case "connectionID":
return getRemoteClusterAutocompleteListItemsNotInChannel(a, commandArgs.ChannelId, true) return getRemoteClusterAutocompleteListItemsNotInChannel(a, commandArgs.ChannelId, true)
default: default:
return nil, fmt.Errorf("%s not a dynamic argument", arg.Name) return nil, fmt.Errorf("%s not a dynamic argument", arg.Name)
@@ -121,7 +112,7 @@ func (sp *ShareProvider) getAutoCompleteInviteRemote(a *app.App, commandArgs *mo
func (sp *ShareProvider) getAutoCompleteUnInviteRemote(a *app.App, _ *model.CommandArgs, arg *model.AutocompleteArg) ([]model.AutocompleteListItem, error) { func (sp *ShareProvider) getAutoCompleteUnInviteRemote(a *app.App, _ *model.CommandArgs, arg *model.AutocompleteArg) ([]model.AutocompleteListItem, error) {
switch arg.Name { switch arg.Name {
case "remoteId": case "connectionID":
return getRemoteClusterAutocompleteListItems(a, true) return getRemoteClusterAutocompleteListItems(a, true)
default: default:
return nil, fmt.Errorf("%s not a dynamic argument", arg.Name) return nil, fmt.Errorf("%s not a dynamic argument", arg.Name)
@@ -148,13 +139,13 @@ func (sp *ShareProvider) DoCommand(a *app.App, args *model.CommandArgs, message
} }
switch action { switch action {
case "share_channel": case "share":
return sp.doShareChannel(a, args, margs) return sp.doShareChannel(a, args, margs)
case "unshare_channel": case "unshare":
return sp.doUnshareChannel(a, args, margs) return sp.doUnshareChannel(a, args, margs)
case "invite_remote": case "invite":
return sp.doInviteRemote(a, args, margs) return sp.doInviteRemote(a, args, margs)
case "uninvite_remote": case "uninvite":
return sp.doUninviteRemote(a, args, margs) return sp.doUninviteRemote(a, args, margs)
case "status": case "status":
return sp.doStatus(a, args, margs) return sp.doStatus(a, args, margs)
@@ -212,15 +203,6 @@ func (sp *ShareProvider) doShareChannel(a *app.App, args *model.CommandArgs, mar
} }
func (sp *ShareProvider) doUnshareChannel(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse { func (sp *ShareProvider) doUnshareChannel(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
if _, ok := margs["are_you_sure"]; !ok {
margs["are_you_sure"] = "N"
}
sure, err := parseBool(margs["are_you_sure"])
if err != nil || !sure {
return responsef(args.T("api.command_share.shared_channel_not_deleted", map[string]interface{}{"Arg": "are_you_sure", "Expected": "Y"}))
}
sc, appErr := a.GetSharedChannel(args.ChannelId) sc, appErr := a.GetSharedChannel(args.ChannelId)
if appErr != nil { if appErr != nil {
return responsef(args.T("api.command_share.shared_channel_unshare.error", map[string]interface{}{"Error": appErr.Error()})) return responsef(args.T("api.command_share.shared_channel_unshare.error", map[string]interface{}{"Error": appErr.Error()}))
@@ -240,7 +222,7 @@ func (sp *ShareProvider) doUnshareChannel(a *app.App, args *model.CommandArgs, m
} }
func (sp *ShareProvider) doInviteRemote(a *app.App, args *model.CommandArgs, margs map[string]string) (resp *model.CommandResponse) { func (sp *ShareProvider) doInviteRemote(a *app.App, args *model.CommandArgs, margs map[string]string) (resp *model.CommandResponse) {
remoteId, ok := margs["remoteId"] remoteId, ok := margs["connectionID"]
if !ok || remoteId == "" { if !ok || remoteId == "" {
return responsef(args.T("api.command_share.must_specify_valid_remote")) return responsef(args.T("api.command_share.must_specify_valid_remote"))
} }
@@ -284,7 +266,7 @@ func (sp *ShareProvider) doInviteRemote(a *app.App, args *model.CommandArgs, mar
return responsef(args.T("api.command_share.channel_invite.error", map[string]interface{}{"Name": rc.DisplayName, "Error": errApp.Error()})) return responsef(args.T("api.command_share.channel_invite.error", map[string]interface{}{"Name": rc.DisplayName, "Error": errApp.Error()}))
} }
// send channel invite to remote cluster // send channel invite to remote cluster
if err := a.Srv().GetSharedChannelSyncService().SendChannelInvite(channel, args.UserId, margs["description"], rc); err != nil { if err := a.Srv().GetSharedChannelSyncService().SendChannelInvite(channel, args.UserId, rc); err != nil {
return responsef(args.T("api.command_share.channel_invite.error", map[string]interface{}{"Name": rc.DisplayName, "Error": err.Error()})) return responsef(args.T("api.command_share.channel_invite.error", map[string]interface{}{"Name": rc.DisplayName, "Error": err.Error()}))
} }
@@ -292,7 +274,7 @@ func (sp *ShareProvider) doInviteRemote(a *app.App, args *model.CommandArgs, mar
} }
func (sp *ShareProvider) doUninviteRemote(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse { func (sp *ShareProvider) doUninviteRemote(a *app.App, args *model.CommandArgs, margs map[string]string) *model.CommandResponse {
remoteId, ok := margs["remoteId"] remoteId, ok := margs["connectionID"]
if !ok || remoteId == "" { if !ok || remoteId == "" {
return responsef(args.T("api.command_share.remote_not_valid")) return responsef(args.T("api.command_share.remote_not_valid"))
} }
@@ -323,19 +305,18 @@ func (sp *ShareProvider) doStatus(a *app.App, args *model.CommandArgs, _ map[str
fmt.Fprintf(&sb, args.T("api.command_share.channel_status_id", map[string]interface{}{"ChannelId": statuses[0].ChannelId})+"\n\n") fmt.Fprintf(&sb, args.T("api.command_share.channel_status_id", map[string]interface{}{"ChannelId": statuses[0].ChannelId})+"\n\n")
fmt.Fprintf(&sb, args.T("api.command_share.remote_table_header")+" \n") fmt.Fprintf(&sb, args.T("api.command_share.remote_table_header")+" \n")
fmt.Fprintf(&sb, "| ------ | ------- | ----------- | -------- | -------------- | ------ | --------- | \n") // "| Secure Connection | SiteURL | ReadOnly | InviteAccepted | Online | Last Sync |"
fmt.Fprintf(&sb, "| ---- | ---- | ---- | ---- | ---- | ---- | \n")
for _, status := range statuses { for _, status := range statuses {
online := ":white_check_mark:" readonly := formatBool(args.T, status.ReadOnly)
if !isOnline(status.LastPingAt) { accepted := formatBool(args.T, status.IsInviteAccepted)
online = ":skull_and_crossbones:" online := formatBool(args.T, isOnline(status.LastPingAt))
}
lastSync := formatTimestamp(model.GetTimeForMillis(status.NextSyncAt)) lastSync := formatTimestamp(status.NextSyncAt)
fmt.Fprintf(&sb, "| %s | %s | %s | %t | %t | %s | %s |\n", fmt.Fprintf(&sb, "| %s | %s | %s | %s | %s | %s |\n",
status.DisplayName, status.SiteURL, status.Description, status.DisplayName, status.SiteURL, readonly, accepted, online, lastSync)
status.ReadOnly, status.IsInviteAccepted, online, lastSync)
} }
return responsef(sb.String()) return responsef(sb.String())
} }

Просмотреть файл

@@ -37,12 +37,13 @@ func TestShareProviderDoCommand(t *testing.T) {
commandProvider := ShareProvider{} commandProvider := ShareProvider{}
channel := th.CreateChannel(th.BasicTeam, WithShared(false)) channel := th.CreateChannel(th.BasicTeam, WithShared(false))
args := &model.CommandArgs{ args := &model.CommandArgs{
T: func(s string, args ...interface{}) string { return s }, T: func(s string, args ...interface{}) string { return s },
ChannelId: channel.Id, ChannelId: channel.Id,
UserId: th.BasicUser.Id, UserId: th.BasicUser.Id,
TeamId: th.BasicTeam.Id, TeamId: th.BasicTeam.Id,
Command: "/share share_channel", Command: "/share-channel share",
} }
response := commandProvider.DoCommand(th.App, args, "") response := commandProvider.DoCommand(th.App, args, "")
@@ -77,7 +78,7 @@ func TestShareProviderDoCommand(t *testing.T) {
ChannelId: channel.Id, ChannelId: channel.Id,
UserId: th.BasicUser.Id, UserId: th.BasicUser.Id,
TeamId: th.BasicTeam.Id, TeamId: th.BasicTeam.Id,
Command: "/share unshare_channel --are_you_sure Y", Command: "/share-channel unshare",
} }
response := commandProvider.DoCommand(th.App, args, "") response := commandProvider.DoCommand(th.App, args, "")

Просмотреть файл

@@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/shared/i18n"
) )
const ( const (
@@ -72,12 +73,25 @@ func parseBool(s string) (bool, error) {
return false, fmt.Errorf("cannot parse '%s' as a boolean", s) return false, fmt.Errorf("cannot parse '%s' as a boolean", s)
} }
func formatTimestamp(ts time.Time) string { func formatBool(fn i18n.TranslateFunc, b bool) string {
if b {
return fn("True")
}
return fn("False")
}
func formatTimestamp(timestamp int64) string {
if timestamp == 0 {
return "--"
}
ts := model.GetTimeForMillis(timestamp)
if !isToday(ts) { if !isToday(ts) {
return ts.Format("Jan 2 15:04:05 MST 2006") return ts.Format("Jan 2 15:04:05 MST 2006")
} }
date := ts.Format("15:04:05 MST 2006") date := ts.Format("15:04:05 MST 2006")
return fmt.Sprintf("today %s", date) return fmt.Sprintf("Today %s", date)
} }
func isToday(ts time.Time) bool { func isToday(ts time.Time) bool {

Просмотреть файл

@@ -1104,11 +1104,11 @@
}, },
{ {
"id": "api.command_remote.add_remote.error", "id": "api.command_remote.add_remote.error",
"translation": "Could not add remote cluster: {{.Error}}" "translation": "Could not add secure connection: {{.Error}}"
}, },
{ {
"id": "api.command_remote.cluster_removed", "id": "api.command_remote.cluster_removed",
"translation": "Remote cluster {{.RemoteId}} {{.Result}}." "translation": "Secure connection {{.RemoteId}} {{.Result}}."
}, },
{ {
"id": "api.command_remote.decode_invitation.error", "id": "api.command_remote.decode_invitation.error",
@@ -1120,11 +1120,11 @@
}, },
{ {
"id": "api.command_remote.displayname.help", "id": "api.command_remote.displayname.help",
"translation": "Remote cluster display name" "translation": "Secure connection display name"
}, },
{ {
"id": "api.command_remote.displayname.hint", "id": "api.command_remote.displayname.hint",
"translation": "A display name for the remote cluster" "translation": "A display name for the secure connection"
}, },
{ {
"id": "api.command_remote.encrypt_invitation.error", "id": "api.command_remote.encrypt_invitation.error",
@@ -1132,7 +1132,7 @@
}, },
{ {
"id": "api.command_remote.fetch_status.error", "id": "api.command_remote.fetch_status.error",
"translation": "Could not fetch remote clusters: {{.Error}}" "translation": "Could not fetch secure connections: {{.Error}}"
}, },
{ {
"id": "api.command_remote.hint", "id": "api.command_remote.hint",
@@ -1144,11 +1144,11 @@
}, },
{ {
"id": "api.command_remote.invitation.help", "id": "api.command_remote.invitation.help",
"translation": "Invitation from remote cluster" "translation": "Invitation from secure connection"
}, },
{ {
"id": "api.command_remote.invitation.hint", "id": "api.command_remote.invitation.hint",
"translation": "The encrypted invitation from a remote cluster" "translation": "The encrypted invitation from a secure connection"
}, },
{ {
"id": "api.command_remote.invitation_created", "id": "api.command_remote.invitation_created",
@@ -1156,7 +1156,7 @@
}, },
{ {
"id": "api.command_remote.invite.help", "id": "api.command_remote.invite.help",
"translation": "Invite a remote cluster" "translation": "Create a secure connection"
}, },
{ {
"id": "api.command_remote.invite_password.help", "id": "api.command_remote.invite_password.help",
@@ -1180,43 +1180,43 @@
}, },
{ {
"id": "api.command_remote.name", "id": "api.command_remote.name",
"translation": "remote" "translation": "secure-connection"
}, },
{ {
"id": "api.command_remote.name.help", "id": "api.command_remote.name.help",
"translation": "Remote cluster name" "translation": "Secure connection name"
}, },
{ {
"id": "api.command_remote.name.hint", "id": "api.command_remote.name.hint",
"translation": "A unique name for the remote cluster" "translation": "A unique name for the secure connection"
}, },
{ {
"id": "api.command_remote.permission_required", "id": "api.command_remote.permission_required",
"translation": "You require `{{.Permission}}` permission to manage remote clusters." "translation": "You require `{{.Permission}}` permission to manage secure connections."
}, },
{ {
"id": "api.command_remote.remote_add_remove.help", "id": "api.command_remote.remote_add_remove.help",
"translation": "Add/remove remote clusters. Available actions: {{.Actions}}" "translation": "Add/remove secure connections. Available actions: {{.Actions}}"
}, },
{ {
"id": "api.command_remote.remote_table_header", "id": "api.command_remote.remote_table_header",
"translation": "| Name | SiteURL | RemoteId | Invite Accepted | Online | Last Ping |" "translation": "| Secure Connection | Display name | ConnectionID | Site URL | Invite accepted | Online | Last ping |"
}, },
{ {
"id": "api.command_remote.remotes_not_found", "id": "api.command_remote.remotes_not_found",
"translation": "No remote clusters found." "translation": "No secure connections found."
}, },
{ {
"id": "api.command_remote.remove.help", "id": "api.command_remote.remove.help",
"translation": "Removes a remote cluster" "translation": "Removes a secure connection"
}, },
{ {
"id": "api.command_remote.remove_remote.error", "id": "api.command_remote.remove_remote.error",
"translation": "Could not remove remote cluster: {{.Error}}" "translation": "Could not remove secure connection: {{.Error}}"
}, },
{ {
"id": "api.command_remote.remove_remote_id.help", "id": "api.command_remote.remove_remote_id.help",
"translation": "Id of remote cluster remove" "translation": "Id of secure connection remove"
}, },
{ {
"id": "api.command_remote.service_disabled", "id": "api.command_remote.service_disabled",
@@ -1232,7 +1232,7 @@
}, },
{ {
"id": "api.command_remote.status.help", "id": "api.command_remote.status.help",
"translation": "Displays status for all remote clusters" "translation": "Displays status for all secure connections"
}, },
{ {
"id": "api.command_remote.unknown_action", "id": "api.command_remote.unknown_action",
@@ -1306,49 +1306,17 @@
"id": "api.command_share.available_actions", "id": "api.command_share.available_actions",
"translation": "Available actions: {{.Actions}}" "translation": "Available actions: {{.Actions}}"
}, },
{
"id": "api.command_share.channel_display_name.help",
"translation": "Channel display name provided to remote instances"
},
{
"id": "api.command_share.channel_display_name.hint",
"translation": "[displayname] - defaults to channel displayname"
},
{
"id": "api.command_share.channel_header.help",
"translation": "Channel header provided to remote instances"
},
{
"id": "api.command_share.channel_header.hint",
"translation": "[header] - defaults to channels header"
},
{ {
"id": "api.command_share.channel_invite.error", "id": "api.command_share.channel_invite.error",
"translation": "Error inviting `{{.Name}}` to this channel: {{.Error}}" "translation": "Error inviting `{{.Name}}` to this channel: {{.Error}}"
}, },
{ {
"id": "api.command_share.channel_invite_not_home.error", "id": "api.command_share.channel_invite_not_home.error",
"translation": "Cannot invite remote cluster to a shared channel originating somewhere else." "translation": "Cannot invite secure connection to a shared channel originating somewhere else."
},
{
"id": "api.command_share.channel_name.help",
"translation": "Channel name provided to remote instances"
},
{
"id": "api.command_share.channel_name.hint",
"translation": "[name] - defaults to channel name"
},
{
"id": "api.command_share.channel_purpose.help",
"translation": "Channel purpose provided to remote instances"
},
{
"id": "api.command_share.channel_purpose.hint",
"translation": "[purpose] - defaults to channel purpose"
}, },
{ {
"id": "api.command_share.channel_remote_id_not_exists", "id": "api.command_share.channel_remote_id_not_exists",
"translation": "Shared channel remote id `{{.RemoteId}}` does not exist for this channel." "translation": "Shared channel secure connection `{{.RemoteId}}` does not exist for this channel."
}, },
{ {
"id": "api.command_share.channel_shared", "id": "api.command_share.channel_shared",
@@ -1374,21 +1342,13 @@
"id": "api.command_share.desc", "id": "api.command_share.desc",
"translation": "Shares the current channel with a remote Mattermost instance." "translation": "Shares the current channel with a remote Mattermost instance."
}, },
{
"id": "api.command_share.description_invite.help",
"translation": "Description for invite"
},
{
"id": "api.command_share.description_invite.hint",
"translation": "[description] - optional"
},
{ {
"id": "api.command_share.fetch_remote.error", "id": "api.command_share.fetch_remote.error",
"translation": "Error fetching remote clusters: {{.Error}}" "translation": "Error fetching shared connections: {{.Error}}"
}, },
{ {
"id": "api.command_share.fetch_remote_status.error", "id": "api.command_share.fetch_remote_status.error",
"translation": "Could not fetch status for remotes: {{.Error}}." "translation": "Could not fetch status for secure connections: {{.Error}}."
}, },
{ {
"id": "api.command_share.hint", "id": "api.command_share.hint",
@@ -1412,15 +1372,15 @@
}, },
{ {
"id": "api.command_share.must_specify_valid_remote", "id": "api.command_share.must_specify_valid_remote",
"translation": "Must specify a valid remote cluster id to invite." "translation": "Must specify a valid secure connection id to invite."
}, },
{ {
"id": "api.command_share.name", "id": "api.command_share.name",
"translation": "share" "translation": "share-channel"
}, },
{ {
"id": "api.command_share.no_remote_invited", "id": "api.command_share.no_remote_invited",
"translation": "No remotes have been invited to this shared channel." "translation": "No secure connections have been invited to this shared channel."
}, },
{ {
"id": "api.command_share.not_shared_channel_unshare", "id": "api.command_share.not_shared_channel_unshare",
@@ -1432,27 +1392,27 @@
}, },
{ {
"id": "api.command_share.remote_already_invited", "id": "api.command_share.remote_already_invited",
"translation": "The remote cluster has already been invited." "translation": "The secure connection has already been invited."
}, },
{ {
"id": "api.command_share.remote_id.help", "id": "api.command_share.remote_id.help",
"translation": "Id of an existing remote instance. See `remote` command to add a remote instance." "translation": "Id of an existing secure connection. See `secure-connection` command to add a secure connection."
}, },
{ {
"id": "api.command_share.remote_id_invalid.error", "id": "api.command_share.remote_id_invalid.error",
"translation": "Remote cluster id is invalid: {{.Error}}" "translation": "Secure connection id is invalid: {{.Error}}"
}, },
{ {
"id": "api.command_share.remote_not_valid", "id": "api.command_share.remote_not_valid",
"translation": "Must specify a valid remote cluster to uninvite" "translation": "Must specify a valid secure connection id to uninvite"
}, },
{ {
"id": "api.command_share.remote_table_header", "id": "api.command_share.remote_table_header",
"translation": "| Remote | SiteURL | Description | ReadOnly | InviteAccepted | Online | Last Sync |" "translation": "| Secure Connection | SiteURL | ReadOnly | InviteAccepted | Online | Last Sync |"
}, },
{ {
"id": "api.command_share.remote_uninvited", "id": "api.command_share.remote_uninvited",
"translation": "Remote `{{.RemoteId}}` uninvited." "translation": "Secure connection `{{.RemoteId}}` uninvited."
}, },
{ {
"id": "api.command_share.service_disabled", "id": "api.command_share.service_disabled",
@@ -1462,10 +1422,6 @@
"id": "api.command_share.share_channel.error", "id": "api.command_share.share_channel.error",
"translation": "Cannot share this channel: {{.Error}}" "translation": "Cannot share this channel: {{.Error}}"
}, },
{
"id": "api.command_share.share_current",
"translation": "Share the current channel"
},
{ {
"id": "api.command_share.share_read_only.help", "id": "api.command_share.share_read_only.help",
"translation": "Channel will be shared in read-only mode" "translation": "Channel will be shared in read-only mode"
@@ -1474,10 +1430,6 @@
"id": "api.command_share.share_read_only.hint", "id": "api.command_share.share_read_only.hint",
"translation": "[readonly] - 'Y' or 'N'. Defaults to 'N'" "translation": "[readonly] - 'Y' or 'N'. Defaults to 'N'"
}, },
{
"id": "api.command_share.shared_channel_not_deleted",
"translation": "Shared channel was not deleted: `{{.Arg}}` must be `{{.Expected}}`."
},
{ {
"id": "api.command_share.shared_channel_unavailable", "id": "api.command_share.shared_channel_unavailable",
"translation": "This channel is no longer shared." "translation": "This channel is no longer shared."
@@ -1488,11 +1440,11 @@
}, },
{ {
"id": "api.command_share.uninvite_remote.help", "id": "api.command_share.uninvite_remote.help",
"translation": "Uninvites a remote instance from this shared channel" "translation": "Uninvites a secure connection from this shared channel"
}, },
{ {
"id": "api.command_share.uninvite_remote_id.help", "id": "api.command_share.uninvite_remote_id.help",
"translation": "Id of remote instance to uninvite." "translation": "Id of secure connection to uninvite."
}, },
{ {
"id": "api.command_share.unknown_action", "id": "api.command_share.unknown_action",
@@ -1502,14 +1454,6 @@
"id": "api.command_share.unshare_channel.help", "id": "api.command_share.unshare_channel.help",
"translation": "Unshares the current channel" "translation": "Unshares the current channel"
}, },
{
"id": "api.command_share.unshare_confirmation.help",
"translation": "Are you sure? This channel will be unshared and all remote instances will be uninvited"
},
{
"id": "api.command_share.unshare_confirmation.hint",
"translation": "'Y' or 'N'"
},
{ {
"id": "api.command_shortcuts.desc", "id": "api.command_shortcuts.desc",
"translation": "Displays a list of keyboard shortcuts" "translation": "Displays a list of keyboard shortcuts"
@@ -1608,15 +1552,15 @@
}, },
{ {
"id": "api.context.remote_id_invalid.app_error", "id": "api.context.remote_id_invalid.app_error",
"translation": "Unable to find remote cluster id {{.RemoteId}}." "translation": "Unable to find secure connectionID {{.RemoteId}}."
}, },
{ {
"id": "api.context.remote_id_mismatch.app_error", "id": "api.context.remote_id_mismatch.app_error",
"translation": "Remote cluster id mismatch." "translation": "Secure connection ID mismatch."
}, },
{ {
"id": "api.context.remote_id_missing.app_error", "id": "api.context.remote_id_missing.app_error",
"translation": "Remote cluster id missing." "translation": "Secure connection ID missing."
}, },
{ {
"id": "api.context.server_busy.app_error", "id": "api.context.server_busy.app_error",
@@ -2432,11 +2376,11 @@
}, },
{ {
"id": "api.remote_cluster.delete.app_error", "id": "api.remote_cluster.delete.app_error",
"translation": "We encountered an error deleting the remote cluster." "translation": "We encountered an error deleting the secure connection."
}, },
{ {
"id": "api.remote_cluster.get.app_error", "id": "api.remote_cluster.get.app_error",
"translation": "We encountered an error retrieving a remote cluster." "translation": "We encountered an error retrieving a secure connection."
}, },
{ {
"id": "api.remote_cluster.invalid_id.app_error", "id": "api.remote_cluster.invalid_id.app_error",
@@ -2448,11 +2392,11 @@
}, },
{ {
"id": "api.remote_cluster.save.app_error", "id": "api.remote_cluster.save.app_error",
"translation": "We encountered an error saving the remote cluster." "translation": "We encountered an error saving the secure connection."
}, },
{ {
"id": "api.remote_cluster.save_not_unique.app_error", "id": "api.remote_cluster.save_not_unique.app_error",
"translation": "Remote cluster has already been added." "translation": "Secure connection has already been added."
}, },
{ {
"id": "api.remote_cluster.service_not_enabled.app_error", "id": "api.remote_cluster.service_not_enabled.app_error",
@@ -2460,11 +2404,11 @@
}, },
{ {
"id": "api.remote_cluster.update.app_error", "id": "api.remote_cluster.update.app_error",
"translation": "We encountered an error updating the remote cluster." "translation": "We encountered an error updating the secure connection."
}, },
{ {
"id": "api.remote_cluster.update_not_unique.app_error", "id": "api.remote_cluster.update_not_unique.app_error",
"translation": "Remote cluster with the same url already exists." "translation": "Secure connection with the same url already exists."
}, },
{ {
"id": "api.restricted_system_admin", "id": "api.restricted_system_admin",
@@ -7734,10 +7678,6 @@
"id": "model.channel.is_valid.creator_id.app_error", "id": "model.channel.is_valid.creator_id.app_error",
"translation": "Invalid creator id." "translation": "Invalid creator id."
}, },
{
"id": "model.channel.is_valid.description.app_error",
"translation": "Invalid description."
},
{ {
"id": "model.channel.is_valid.display_name.app_error", "id": "model.channel.is_valid.display_name.app_error",
"translation": "Invalid display name." "translation": "Invalid display name."

Просмотреть файл

@@ -24,7 +24,7 @@ const (
MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS = "add_system_roles_permissions" MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS = "add_system_roles_permissions"
MIGRATION_KEY_ADD_BILLING_PERMISSIONS = "add_billing_permissions" MIGRATION_KEY_ADD_BILLING_PERMISSIONS = "add_billing_permissions"
MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS = "manage_shared_channel_permissions" MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS = "manage_shared_channel_permissions"
MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS = "manage_remote_clusters_permissions" MIGRATION_KEY_ADD_MANAGE_SECURE_CONNECTIONS_PERMISSIONS = "manage_secure_connections_permissions"
MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS = "download_compliance_export_results" MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS = "download_compliance_export_results"
MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS = "compliance_subsection_permissions" MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS = "compliance_subsection_permissions"
MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS = "experimental_subsection_permissions" MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS = "experimental_subsection_permissions"

Просмотреть файл

@@ -100,7 +100,7 @@ var PERMISSION_USE_GROUP_MENTIONS *Permission
var PERMISSION_READ_OTHER_USERS_TEAMS *Permission var PERMISSION_READ_OTHER_USERS_TEAMS *Permission
var PERMISSION_EDIT_BRAND *Permission var PERMISSION_EDIT_BRAND *Permission
var PERMISSION_MANAGE_SHARED_CHANNELS *Permission var PERMISSION_MANAGE_SHARED_CHANNELS *Permission
var PERMISSION_MANAGE_REMOTE_CLUSTERS *Permission var PERMISSION_MANAGE_SECURE_CONNECTIONS *Permission
var PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT *Permission var PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT *Permission
var PERMISSION_CREATE_DATA_RETENTION_JOB *Permission var PERMISSION_CREATE_DATA_RETENTION_JOB *Permission
var PERMISSION_READ_DATA_RETENTION_JOB *Permission var PERMISSION_READ_DATA_RETENTION_JOB *Permission
@@ -711,10 +711,10 @@ func initializePermissions() {
"authentication.permissions.manage_shared_channels.description", "authentication.permissions.manage_shared_channels.description",
PermissionScopeSystem, PermissionScopeSystem,
} }
PERMISSION_MANAGE_REMOTE_CLUSTERS = &Permission{ PERMISSION_MANAGE_SECURE_CONNECTIONS = &Permission{
"manage_remote_clusters", "manage_secure_connections",
"authentication.permissions.manage_remote_clusters.name", "authentication.permissions.manage_secure_connections.name",
"authentication.permissions.manage_remote_clusters.description", "authentication.permissions.manage_secure_connections.description",
PermissionScopeSystem, PermissionScopeSystem,
} }
@@ -2041,7 +2041,7 @@ func initializePermissions() {
PERMISSION_DEMOTE_TO_GUEST, PERMISSION_DEMOTE_TO_GUEST,
PERMISSION_EDIT_BRAND, PERMISSION_EDIT_BRAND,
PERMISSION_MANAGE_SHARED_CHANNELS, PERMISSION_MANAGE_SHARED_CHANNELS,
PERMISSION_MANAGE_REMOTE_CLUSTERS, PERMISSION_MANAGE_SECURE_CONNECTIONS,
PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT, PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT,
PERMISSION_CREATE_DATA_RETENTION_JOB, PERMISSION_CREATE_DATA_RETENTION_JOB,
PERMISSION_READ_DATA_RETENTION_JOB, PERMISSION_READ_DATA_RETENTION_JOB,

Просмотреть файл

@@ -106,7 +106,6 @@ func (sc *SharedChannel) PreUpdate() {
type SharedChannelRemote struct { type SharedChannelRemote struct {
Id string `json:"id"` Id string `json:"id"`
ChannelId string `json:"channel_id"` ChannelId string `json:"channel_id"`
Description string `json:"description"`
CreatorId string `json:"creator_id"` CreatorId string `json:"creator_id"`
CreateAt int64 `json:"create_at"` CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"` UpdateAt int64 `json:"update_at"`
@@ -136,10 +135,6 @@ func (sc *SharedChannelRemote) IsValid() *AppError {
return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+sc.ChannelId, http.StatusBadRequest) return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+sc.ChannelId, http.StatusBadRequest)
} }
if len(sc.Description) > 64 {
return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.description.app_error", nil, "description="+sc.Description, http.StatusBadRequest)
}
if sc.CreateAt == 0 { if sc.CreateAt == 0 {
return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest) return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
} }
@@ -172,7 +167,6 @@ type SharedChannelRemoteStatus struct {
SiteURL string `json:"site_url"` SiteURL string `json:"site_url"`
LastPingAt int64 `json:"last_ping_at"` LastPingAt int64 `json:"last_ping_at"`
NextSyncAt int64 `json:"next_sync_at"` NextSyncAt int64 `json:"next_sync_at"`
Description string `json:"description"`
ReadOnly bool `json:"readonly"` ReadOnly bool `json:"readonly"`
IsInviteAccepted bool `json:"is_invite_accepted"` IsInviteAccepted bool `json:"is_invite_accepted"`
Token string `json:"token"` Token string `json:"token"`

Просмотреть файл

@@ -76,12 +76,11 @@ func TestSharedChannelPreUpdate(t *testing.T) {
} }
func TestSharedChannelRemoteJson(t *testing.T) { func TestSharedChannelRemoteJson(t *testing.T) {
o := SharedChannelRemote{Id: NewId(), ChannelId: NewId(), Description: "Test"} o := SharedChannelRemote{Id: NewId(), ChannelId: NewId()}
json := o.ToJson() json := o.ToJson()
ro, err := SharedChannelRemoteFromJson(strings.NewReader(json)) ro, err := SharedChannelRemoteFromJson(strings.NewReader(json))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, o.Id, ro.Id) require.Equal(t, o.Id, ro.Id)
require.Equal(t, o.ChannelId, ro.ChannelId) require.Equal(t, o.ChannelId, ro.ChannelId)
require.Equal(t, o.Description, ro.Description)
} }

Просмотреть файл

@@ -75,7 +75,7 @@ type TopicListener func(msg model.RemoteClusterMsg, rc *model.RemoteCluster, res
// ConnectionStateListener is used to listen to remote cluster connection state changes. // ConnectionStateListener is used to listen to remote cluster connection state changes.
type ConnectionStateListener func(rc *model.RemoteCluster, online bool) type ConnectionStateListener func(rc *model.RemoteCluster, online bool)
// Service provides inter-cluster communication via topic based messages. // Service provides inter-cluster communication via topic based messages. In product these are called "Secured Connections".
type Service struct { type Service struct {
server ServerIface server ServerIface
httpClient *http.Client httpClient *http.Client
@@ -90,7 +90,7 @@ type Service struct {
done chan struct{} done chan struct{}
} }
// NewRemoteClusterService creates a RemoteClusterService instance. // NewRemoteClusterService creates a RemoteClusterService instance. In product this is called a "Secured Connection".
func NewRemoteClusterService(server ServerIface) (*Service, error) { func NewRemoteClusterService(server ServerIface) (*Service, error) {
transport := &http.Transport{ transport := &http.Transport{
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,

Просмотреть файл

@@ -38,7 +38,7 @@ func WithDirectParticipantID(participantID string) InviteOption {
// SendChannelInvite asynchronously sends a channel invite to a remote cluster. The remote cluster is // SendChannelInvite asynchronously sends a channel invite to a remote cluster. The remote cluster is
// expected to create a new channel with the same channel id, and respond with status OK. // expected to create a new channel with the same channel id, and respond with status OK.
// If an error occurs on the remote cluster then an ephemeral message is posted to in the channel for userId. // If an error occurs on the remote cluster then an ephemeral message is posted to in the channel for userId.
func (scs *Service) SendChannelInvite(channel *model.Channel, userId string, description string, rc *model.RemoteCluster, options ...InviteOption) error { func (scs *Service) SendChannelInvite(channel *model.Channel, userId string, rc *model.RemoteCluster, options ...InviteOption) error {
rcs := scs.server.GetRemoteClusterService() rcs := scs.server.GetRemoteClusterService()
if rcs == nil { if rcs == nil {
return fmt.Errorf("cannot invite remote cluster for channel id %s; Remote Cluster Service not enabled", channel.Id) return fmt.Errorf("cannot invite remote cluster for channel id %s; Remote Cluster Service not enabled", channel.Id)
@@ -82,7 +82,6 @@ func (scs *Service) SendChannelInvite(channel *model.Channel, userId string, des
scr := &model.SharedChannelRemote{ scr := &model.SharedChannelRemote{
ChannelId: sc.ChannelId, ChannelId: sc.ChannelId,
Description: description,
CreatorId: userId, CreatorId: userId,
RemoteId: rc.RemoteId, RemoteId: rc.RemoteId,
IsInviteAccepted: true, IsInviteAccepted: true,
@@ -165,7 +164,6 @@ func (scs *Service) onReceiveChannelInvite(msg model.RemoteClusterMsg, rc *model
sharedChannelRemote := &model.SharedChannelRemote{ sharedChannelRemote := &model.SharedChannelRemote{
Id: model.NewId(), Id: model.NewId(),
ChannelId: channel.Id, ChannelId: channel.Id,
Description: invite.DisplayName,
CreatorId: channel.CreatorId, CreatorId: channel.CreatorId,
IsInviteAccepted: true, IsInviteAccepted: true,
IsInviteConfirmed: true, IsInviteConfirmed: true,

Просмотреть файл

@@ -38,7 +38,6 @@ func newSqlSharedChannelStore(sqlStore *SqlStore) store.SharedChannelStore {
tableSharedChannelRemotes := db.AddTableWithName(model.SharedChannelRemote{}, "SharedChannelRemotes").SetKeys(false, "Id", "ChannelId") tableSharedChannelRemotes := db.AddTableWithName(model.SharedChannelRemote{}, "SharedChannelRemotes").SetKeys(false, "Id", "ChannelId")
tableSharedChannelRemotes.ColMap("Id").SetMaxSize(26) tableSharedChannelRemotes.ColMap("Id").SetMaxSize(26)
tableSharedChannelRemotes.ColMap("ChannelId").SetMaxSize(26) tableSharedChannelRemotes.ColMap("ChannelId").SetMaxSize(26)
tableSharedChannelRemotes.ColMap("Description").SetMaxSize(64)
tableSharedChannelRemotes.ColMap("CreatorId").SetMaxSize(26) tableSharedChannelRemotes.ColMap("CreatorId").SetMaxSize(26)
tableSharedChannelRemotes.ColMap("RemoteId").SetMaxSize(26) tableSharedChannelRemotes.ColMap("RemoteId").SetMaxSize(26)
tableSharedChannelRemotes.SetUniqueTogether("ChannelId", "RemoteId") tableSharedChannelRemotes.SetUniqueTogether("ChannelId", "RemoteId")
@@ -524,7 +523,7 @@ func (s SqlSharedChannelStore) GetRemotesStatus(channelId string) ([]*model.Shar
var status []*model.SharedChannelRemoteStatus var status []*model.SharedChannelRemoteStatus
query := s.getQueryBuilder(). query := s.getQueryBuilder().
Select("scr.ChannelId, rc.DisplayName, rc.SiteURL, rc.LastPingAt, scr.NextSyncAt, scr.Description, sc.ReadOnly, scr.IsInviteAccepted"). Select("scr.ChannelId, rc.DisplayName, rc.SiteURL, rc.LastPingAt, scr.NextSyncAt, sc.ReadOnly, scr.IsInviteAccepted").
From("SharedChannelRemotes scr, RemoteClusters rc, SharedChannels sc"). From("SharedChannelRemotes scr, RemoteClusters rc, SharedChannels sc").
Where("scr.RemoteId = rc.RemoteId"). Where("scr.RemoteId = rc.RemoteId").
Where("scr.ChannelId = sc.ChannelId"). Where("scr.ChannelId = sc.ChannelId").

Просмотреть файл

@@ -253,11 +253,11 @@ func testRemoteClusterGetAllInChannel(t *testing.T, ss store.Store) {
// Create some shared channel remotes // Create some shared channel remotes
scrData := []*model.SharedChannelRemote{ scrData := []*model.SharedChannelRemote{
{ChannelId: channel1.Id, Description: "AAA Inc Share", RemoteId: rcData[0].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel1.Id, RemoteId: rcData[0].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel1.Id, Description: "BBB Inc Share", RemoteId: rcData[1].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel1.Id, RemoteId: rcData[1].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel2.Id, Description: "CCC Inc Share", RemoteId: rcData[2].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel2.Id, RemoteId: rcData[2].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel2.Id, Description: "DDD Inc Share", RemoteId: rcData[3].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel2.Id, RemoteId: rcData[3].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel2.Id, Description: "EEE Inc Share", RemoteId: rcData[4].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel2.Id, RemoteId: rcData[4].RemoteId, CreatorId: model.NewId()},
} }
for _, item := range scrData { for _, item := range scrData {
_, err := ss.SharedChannel().SaveRemote(item) _, err := ss.SharedChannel().SaveRemote(item)
@@ -360,11 +360,11 @@ func testRemoteClusterGetAllNotInChannel(t *testing.T, ss store.Store) {
// Create some shared channel remotes // Create some shared channel remotes
scrData := []*model.SharedChannelRemote{ scrData := []*model.SharedChannelRemote{
{ChannelId: channel1.Id, Description: "AAA Inc Share", RemoteId: rcData[0].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel1.Id, RemoteId: rcData[0].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel1.Id, Description: "BBB Inc Share", RemoteId: rcData[1].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel1.Id, RemoteId: rcData[1].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel2.Id, Description: "CCC Inc Share", RemoteId: rcData[2].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel2.Id, RemoteId: rcData[2].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel2.Id, Description: "DDD Inc Share", RemoteId: rcData[3].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel2.Id, RemoteId: rcData[3].RemoteId, CreatorId: model.NewId()},
{ChannelId: channel3.Id, Description: "EEE Inc Share", RemoteId: rcData[4].RemoteId, CreatorId: model.NewId()}, {ChannelId: channel3.Id, RemoteId: rcData[4].RemoteId, CreatorId: model.NewId()},
} }
for _, item := range scrData { for _, item := range scrData {
_, err := ss.SharedChannel().SaveRemote(item) _, err := ss.SharedChannel().SaveRemote(item)

Просмотреть файл

@@ -349,10 +349,9 @@ func testDeleteSharedChannel(t *testing.T, ss store.Store) {
// add some remotes // add some remotes
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "remote_" + strconv.Itoa(i), CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
_, err := ss.SharedChannel().SaveRemote(remote) _, err := ss.SharedChannel().SaveRemote(remote)
require.NoError(t, err, "couldn't add remote", err) require.NoError(t, err, "couldn't add remote", err)
@@ -391,10 +390,9 @@ func testSaveSharedChannelRemote(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
@@ -406,10 +404,9 @@ func testSaveSharedChannelRemote(t *testing.T, ss store.Store) {
t.Run("Save invalid shared channel remote", func(t *testing.T) { t.Run("Save invalid shared channel remote", func(t *testing.T) {
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: "", ChannelId: "",
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
_, err := ss.SharedChannel().SaveRemote(remote) _, err := ss.SharedChannel().SaveRemote(remote)
@@ -418,10 +415,9 @@ func testSaveSharedChannelRemote(t *testing.T, ss store.Store) {
t.Run("Save shared channel remote with invalid channel id", func(t *testing.T) { t.Run("Save shared channel remote with invalid channel id", func(t *testing.T) {
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: model.NewId(), ChannelId: model.NewId(),
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
_, err := ss.SharedChannel().SaveRemote(remote) _, err := ss.SharedChannel().SaveRemote(remote)
@@ -435,10 +431,9 @@ func testUpdateSharedChannelRemote(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote_update", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
@@ -446,22 +441,19 @@ func testUpdateSharedChannelRemote(t *testing.T, ss store.Store) {
remoteSaved.IsInviteAccepted = true remoteSaved.IsInviteAccepted = true
remoteSaved.IsInviteConfirmed = true remoteSaved.IsInviteConfirmed = true
remoteSaved.Description = "new_desc"
remoteUpdated, err := ss.SharedChannel().UpdateRemote(remoteSaved) remoteUpdated, err := ss.SharedChannel().UpdateRemote(remoteSaved)
require.NoError(t, err, "couldn't update shared channel remote", err) require.NoError(t, err, "couldn't update shared channel remote", err)
require.Equal(t, true, remoteUpdated.IsInviteAccepted) require.Equal(t, true, remoteUpdated.IsInviteAccepted)
require.Equal(t, true, remoteUpdated.IsInviteConfirmed) require.Equal(t, true, remoteUpdated.IsInviteConfirmed)
require.Equal(t, "new_desc", remoteUpdated.Description)
}) })
t.Run("Update invalid shared channel remote", func(t *testing.T) { t.Run("Update invalid shared channel remote", func(t *testing.T) {
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: "", ChannelId: "",
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
_, err := ss.SharedChannel().UpdateRemote(remote) _, err := ss.SharedChannel().UpdateRemote(remote)
@@ -470,10 +462,9 @@ func testUpdateSharedChannelRemote(t *testing.T, ss store.Store) {
t.Run("Update shared channel remote with invalid channel id", func(t *testing.T) { t.Run("Update shared channel remote with invalid channel id", func(t *testing.T) {
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: model.NewId(), ChannelId: model.NewId(),
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
_, err := ss.SharedChannel().UpdateRemote(remote) _, err := ss.SharedChannel().UpdateRemote(remote)
@@ -486,10 +477,9 @@ func testGetSharedChannelRemote(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
@@ -501,7 +491,6 @@ func testGetSharedChannelRemote(t *testing.T, ss store.Store) {
require.Equal(t, remoteSaved.Id, r.Id) require.Equal(t, remoteSaved.Id, r.Id)
require.Equal(t, remoteSaved.ChannelId, r.ChannelId) require.Equal(t, remoteSaved.ChannelId, r.ChannelId)
require.Equal(t, remoteSaved.Description, r.Description)
require.Equal(t, remoteSaved.CreatorId, r.CreatorId) require.Equal(t, remoteSaved.CreatorId, r.CreatorId)
require.Equal(t, remoteSaved.RemoteId, r.RemoteId) require.Equal(t, remoteSaved.RemoteId, r.RemoteId)
}) })
@@ -518,10 +507,9 @@ func testGetSharedChannelRemoteByIds(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote_by_ids", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
@@ -533,7 +521,6 @@ func testGetSharedChannelRemoteByIds(t *testing.T, ss store.Store) {
require.Equal(t, remoteSaved.Id, r.Id) require.Equal(t, remoteSaved.Id, r.Id)
require.Equal(t, remoteSaved.ChannelId, r.ChannelId) require.Equal(t, remoteSaved.ChannelId, r.ChannelId)
require.Equal(t, remoteSaved.Description, r.Description)
require.Equal(t, remoteSaved.CreatorId, r.CreatorId) require.Equal(t, remoteSaved.CreatorId, r.CreatorId)
require.Equal(t, remoteSaved.RemoteId, r.RemoteId) require.Equal(t, remoteSaved.RemoteId, r.RemoteId)
}) })
@@ -553,12 +540,12 @@ func testGetSharedChannelRemotes(t *testing.T, ss store.Store) {
remoteId := model.NewId() remoteId := model.NewId()
data := []model.SharedChannelRemote{ data := []model.SharedChannelRemote{
{ChannelId: channel.Id, CreatorId: creator, Description: "r1", RemoteId: model.NewId(), IsInviteConfirmed: true}, {ChannelId: channel.Id, CreatorId: creator, RemoteId: model.NewId(), IsInviteConfirmed: true},
{ChannelId: channel.Id, CreatorId: creator, Description: "r2", RemoteId: model.NewId(), IsInviteConfirmed: true}, {ChannelId: channel.Id, CreatorId: creator, RemoteId: model.NewId(), IsInviteConfirmed: true},
{ChannelId: channel.Id, CreatorId: creator, Description: "r3", RemoteId: model.NewId(), IsInviteConfirmed: true}, {ChannelId: channel.Id, CreatorId: creator, RemoteId: model.NewId(), IsInviteConfirmed: true},
{CreatorId: creator, Description: "r4", RemoteId: remoteId, IsInviteConfirmed: true}, {CreatorId: creator, RemoteId: remoteId, IsInviteConfirmed: true},
{CreatorId: creator, Description: "r5", RemoteId: remoteId, IsInviteConfirmed: true}, {CreatorId: creator, RemoteId: remoteId, IsInviteConfirmed: true},
{CreatorId: creator, Description: "r6", RemoteId: remoteId}, {CreatorId: creator, RemoteId: remoteId},
} }
for i, r := range data { for i, r := range data {
@@ -579,7 +566,7 @@ func testGetSharedChannelRemotes(t *testing.T, ss store.Store) {
require.NoError(t, err, "should not error", err) require.NoError(t, err, "should not error", err)
require.Len(t, remotes, 3) require.Len(t, remotes, 3)
for _, r := range remotes { for _, r := range remotes {
require.Contains(t, []string{"r1", "r2", "r3"}, r.Description) require.Equal(t, channel.Id, r.ChannelId)
} }
}) })
@@ -600,7 +587,8 @@ func testGetSharedChannelRemotes(t *testing.T, ss store.Store) {
require.NoError(t, err, "should not error", err) require.NoError(t, err, "should not error", err)
require.Len(t, remotes, 2) // only confirmed invitations require.Len(t, remotes, 2) // only confirmed invitations
for _, r := range remotes { for _, r := range remotes {
require.Contains(t, []string{"r4", "r5"}, r.Description) require.Equal(t, remoteId, r.RemoteId)
require.True(t, r.IsInviteConfirmed)
} }
}) })
@@ -620,9 +608,9 @@ func testGetSharedChannelRemotes(t *testing.T, ss store.Store) {
} }
remotes, err := ss.SharedChannel().GetRemotes(opts) remotes, err := ss.SharedChannel().GetRemotes(opts)
require.NoError(t, err, "should not error", err) require.NoError(t, err, "should not error", err)
require.Len(t, remotes, 3) // only confirmed invitations require.Len(t, remotes, 3)
for _, r := range remotes { for _, r := range remotes {
require.Contains(t, []string{"r4", "r5", "r6"}, r.Description) require.Equal(t, remoteId, r.RemoteId)
} }
}) })
} }
@@ -636,8 +624,8 @@ func testHasRemote(t *testing.T, ss store.Store) {
creator := model.NewId() creator := model.NewId()
data := []model.SharedChannelRemote{ data := []model.SharedChannelRemote{
{ChannelId: channel.Id, CreatorId: creator, Description: "r1", RemoteId: remote1}, {ChannelId: channel.Id, CreatorId: creator, RemoteId: remote1},
{ChannelId: channel.Id, CreatorId: creator, Description: "r2", RemoteId: remote2}, {ChannelId: channel.Id, CreatorId: creator, RemoteId: remote2},
} }
for _, r := range data { for _, r := range data {
@@ -731,10 +719,9 @@ func testUpdateSharedChannelRemoteNextSyncAt(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
@@ -762,10 +749,9 @@ func testDeleteSharedChannelRemote(t *testing.T, ss store.Store) {
require.NoError(t, err) require.NoError(t, err)
remote := &model.SharedChannelRemote{ remote := &model.SharedChannelRemote{
ChannelId: channel.Id, ChannelId: channel.Id,
Description: "test_remote", CreatorId: model.NewId(),
CreatorId: model.NewId(), RemoteId: model.NewId(),
RemoteId: model.NewId(),
} }
remoteSaved, err := ss.SharedChannel().SaveRemote(remote) remoteSaved, err := ss.SharedChannel().SaveRemote(remote)

Просмотреть файл

@@ -59,7 +59,7 @@ func GetMockStoreForSetupFunctions() *mocks.Store {
systemStore.On("GetByName", model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS, Value: "true"}, nil)
systemStore.On("GetByName", model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS, Value: "true"}, nil)
systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS, Value: "true"}, nil)
systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_SECURE_CONNECTIONS_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_SECURE_CONNECTIONS_PERMISSIONS, Value: "true"}, nil)
systemStore.On("Get").Return(make(model.StringMap), nil) systemStore.On("Get").Return(make(model.StringMap), nil)
systemStore.On("Save", mock.AnythingOfType("*model.System")).Return(nil) systemStore.On("Save", mock.AnythingOfType("*model.System")).Return(nil)