Skip to content

Commit e20c404

Browse files
vegerismwbrooks
andauthored
feat: update 'collaborator' command to support read-only permission type (#272)
* unhide read-only collaborator setting for deployed apps * update * update prompt wording * Update cmd/collaborators/add.go Co-authored-by: Michael Brooks <[email protected]> * Update cmd/collaborators/update.go Co-authored-by: Michael Brooks <[email protected]> * error out when flag not provided * update error message --------- Co-authored-by: Michael Brooks <[email protected]>
1 parent f768cc2 commit e20c404

File tree

8 files changed

+20
-93
lines changed

8 files changed

+20
-93
lines changed

cmd/collaborators/add.go

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/opentracing/opentracing-go"
2424
"github.com/slackapi/slack-cli/internal/cmdutil"
25-
"github.com/slackapi/slack-cli/internal/experiment"
2625
"github.com/slackapi/slack-cli/internal/iostreams"
2726
"github.com/slackapi/slack-cli/internal/prompts"
2827
"github.com/slackapi/slack-cli/internal/shared"
@@ -62,8 +61,11 @@ func NewAddCommand(clients *shared.ClientFactory) *cobra.Command {
6261
return runAddCommandFunc(ctx, clients, cmd, args)
6362
},
6463
}
65-
cmd.Flags().StringVarP(&addFlags.permissionType, "permission-type", "P", "", "collaborator permission type: reader, owner")
66-
cmd.Flag("permission-type").Hidden = true
64+
cmd.Flags().StringVarP(&addFlags.permissionType, "permission-type", "P", string(types.OWNER), fmt.Sprintf(
65+
"collaborator permission type\n(\"%s\" or \"%s\")",
66+
string(types.OWNER),
67+
string(types.READER),
68+
))
6769
return cmd
6870
}
6971

@@ -87,7 +89,7 @@ func runAddCommandFunc(ctx context.Context, clients *shared.ClientFactory, cmd *
8789
}
8890
err = clients.API().AddCollaborator(ctx, selection.Auth.Token, selection.App.AppID, slackUser)
8991
if err != nil {
90-
if clients.Config.WithExperimentOn(experiment.ReadOnlyAppCollaborators) && strings.Contains(err.Error(), "user_already_owner") {
92+
if strings.Contains(err.Error(), "user_already_owner") {
9193
cmd.Println()
9294
cmd.Println(style.Sectionf(style.TextSection{
9395
Emoji: "bulb",
@@ -123,14 +125,15 @@ func promptCollaboratorsAdd(
123125
if err != nil {
124126
return types.SlackUser{}, err
125127
}
128+
126129
switch clients.Config.Flags.Lookup("permission-type").Changed {
127130
case true:
128131
slackUser.PermissionType, err = promptCollaboratorsAddPermissionFlags(ctx, clients, addFlags.permissionType)
132+
if err != nil {
133+
return types.SlackUser{}, err
134+
}
129135
default:
130-
slackUser.PermissionType, err = promptCollaboratorsAddPermissionPrompts(ctx, clients)
131-
}
132-
if err != nil {
133-
return types.SlackUser{}, err
136+
slackUser.PermissionType = types.OWNER
134137
}
135138
return slackUser, nil
136139
}
@@ -181,40 +184,7 @@ func promptCollaboratorsAddSlackUserPrompts(
181184
return slackUser, nil
182185
}
183186

184-
// promptCollaboratorsAddPermissionPrompts gathers the collaborator permission
185-
// from selection if the experiment allows
186-
func promptCollaboratorsAddPermissionPrompts(
187-
ctx context.Context,
188-
clients *shared.ClientFactory,
189-
) (
190-
permission types.AppCollaboratorPermission,
191-
err error,
192-
) {
193-
switch clients.Config.WithExperimentOn(experiment.ReadOnlyAppCollaborators) {
194-
case false:
195-
return types.OWNER, nil
196-
default:
197-
permissionLabels := []string{
198-
"owner",
199-
"reader",
200-
}
201-
response, err := clients.IO.SelectPrompt(
202-
ctx,
203-
"Decide the collaborator permission",
204-
permissionLabels,
205-
iostreams.SelectPromptConfig{
206-
Required: true,
207-
},
208-
)
209-
if err != nil {
210-
return "", err
211-
}
212-
return types.StringToAppCollaboratorPermission(response.Option)
213-
}
214-
}
215-
216-
// promptCollaboratorsAddPermissionFlags gathers the collaborator permission
217-
// from flags if the experiment allows
187+
// promptCollaboratorsAddPermissionFlags fetches collaborator permission from the flag
218188
func promptCollaboratorsAddPermissionFlags(
219189
ctx context.Context,
220190
clients *shared.ClientFactory,
@@ -223,19 +193,7 @@ func promptCollaboratorsAddPermissionFlags(
223193
permission types.AppCollaboratorPermission,
224194
err error,
225195
) {
226-
switch clients.Config.WithExperimentOn(experiment.ReadOnlyAppCollaborators) {
227-
case true:
228-
return types.StringToAppCollaboratorPermission(addFlags.permissionType)
229-
default:
230-
clients.IO.PrintInfo(ctx, false, "\n%s", style.Sectionf(style.TextSection{
231-
Emoji: "construction",
232-
Text: fmt.Sprintf("This command is under construction. Use at your own risk %s", style.Emoji("skull")),
233-
Secondary: []string{
234-
fmt.Sprintf("Bypass this message with the %s flag", style.Highlight("--experiment read-only-collaborators")),
235-
},
236-
}))
237-
return "", slackerror.New(slackerror.ErrMissingExperiment)
238-
}
196+
return types.StringToAppCollaboratorPermission(addFlags.permissionType)
239197
}
240198

241199
// printCollaboratorsAddSuccess outputs a message when addition is done

cmd/collaborators/add_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ func TestAddCommand(t *testing.T) {
3737
appSelectMock := prompts.NewAppSelectMock()
3838
appSelectPromptFunc = appSelectMock.AppSelectPrompt
3939
appSelectMock.On("AppSelectPrompt", mock.Anything, mock.Anything, prompts.ShowHostedOnly, prompts.ShowInstalledAndUninstalledApps).Return(prompts.SelectedApp{App: types.App{AppID: "A123"}, Auth: types.SlackAuth{}}, nil)
40-
// Set experiment flag
41-
cm.Config.ExperimentsFlag = append(cm.Config.ExperimentsFlag, "read-only-collaborators")
42-
cm.Config.LoadExperiments(ctx, cm.IO.PrintDebug)
4340
// Mock API call
4441
cm.API.On("AddCollaborator", mock.Anything, mock.Anything,
4542
"A123",
@@ -61,9 +58,6 @@ func TestAddCommand(t *testing.T) {
6158
appSelectMock := prompts.NewAppSelectMock()
6259
appSelectPromptFunc = appSelectMock.AppSelectPrompt
6360
appSelectMock.On("AppSelectPrompt", mock.Anything, mock.Anything, prompts.ShowHostedOnly, prompts.ShowInstalledAndUninstalledApps).Return(prompts.SelectedApp{App: types.App{AppID: "A123"}, Auth: types.SlackAuth{}}, nil)
64-
// Set experiment flag
65-
cm.Config.ExperimentsFlag = append(cm.Config.ExperimentsFlag, "read-only-collaborators")
66-
cm.Config.LoadExperiments(ctx, cm.IO.PrintDebug)
6761
// Mock API call
6862
cm.API.On("AddCollaborator", mock.Anything, mock.Anything,
6963
"A123",

cmd/collaborators/update.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020

2121
"github.com/opentracing/opentracing-go"
2222
"github.com/slackapi/slack-cli/internal/cmdutil"
23-
"github.com/slackapi/slack-cli/internal/experiment"
2423
"github.com/slackapi/slack-cli/internal/prompts"
2524
"github.com/slackapi/slack-cli/internal/shared"
2625
"github.com/slackapi/slack-cli/internal/shared/types"
@@ -51,23 +50,15 @@ func NewUpdateCommand(clients *shared.ClientFactory) *cobra.Command {
5150
return cmdutil.IsValidProjectDirectory(clients)
5251
},
5352
RunE: func(cmd *cobra.Command, args []string) error {
54-
if !clients.Config.WithExperimentOn(experiment.ReadOnlyAppCollaborators) {
55-
cmd.Println()
56-
cmd.Println(style.Sectionf(style.TextSection{
57-
Emoji: "construction",
58-
Text: fmt.Sprintf("This command is under construction. Use at your own risk %s", style.Emoji("skull")),
59-
Secondary: []string{
60-
fmt.Sprintf("Bypass this message with the %s flag", style.Highlight("--experiment read-only-collaborators")),
61-
},
62-
}))
63-
return nil
64-
}
65-
6653
return runUpdateCommand(cmd, clients, args)
6754
},
6855
}
6956

70-
cmd.Flags().StringVarP(&updateFlags.permissionType, "permission-type", "P", "", "collaborator permission type: reader, owner")
57+
cmd.Flags().StringVarP(&updateFlags.permissionType, "permission-type", "P", "", fmt.Sprintf(
58+
"collaborator permission type\n(\"%s\" or \"%s\")",
59+
string(types.OWNER),
60+
string(types.READER),
61+
))
7162

7263
return cmd
7364
}

cmd/collaborators/update_test.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ func TestUpdateCommand(t *testing.T) {
3737
appSelectMock := prompts.NewAppSelectMock()
3838
appSelectPromptFunc = appSelectMock.AppSelectPrompt
3939
appSelectMock.On("AppSelectPrompt", mock.Anything, mock.Anything, prompts.ShowHostedOnly, prompts.ShowInstalledAndUninstalledApps).Return(prompts.SelectedApp{App: types.App{AppID: "A123"}, Auth: types.SlackAuth{}}, nil)
40-
// Set experiment flag
41-
clientsMock.Config.ExperimentsFlag = append(clientsMock.Config.ExperimentsFlag, "read-only-collaborators")
42-
clientsMock.Config.LoadExperiments(ctx, clientsMock.IO.PrintDebug)
4340
// Mock APi call
4441
clientsMock.API.On("UpdateCollaborator", mock.Anything, mock.Anything,
4542
"A123",
@@ -55,10 +52,7 @@ func TestUpdateCommand(t *testing.T) {
5552
appSelectMock := prompts.NewAppSelectMock()
5653
appSelectPromptFunc = appSelectMock.AppSelectPrompt
5754
appSelectMock.On("AppSelectPrompt", mock.Anything, mock.Anything, prompts.ShowHostedOnly, prompts.ShowInstalledAndUninstalledApps).Return(prompts.SelectedApp{App: types.App{AppID: "A123"}, Auth: types.SlackAuth{}}, nil)
58-
// Set experiment flag
59-
clientsMock.Config.ExperimentsFlag = append(clientsMock.Config.ExperimentsFlag, "read-only-collaborators")
60-
clientsMock.Config.LoadExperiments(ctx, clientsMock.IO.PrintDebug)
61-
// Mock APi call
55+
// Mock API call
6256
clientsMock.API.On("UpdateCollaborator", mock.Anything, mock.Anything,
6357
"A123",
6458
types.SlackUser{Email: "[email protected]", PermissionType: types.OWNER}).Return(nil)
@@ -79,9 +73,6 @@ func TestUpdateCommand(t *testing.T) {
7973
ExpectedErrorStrings: []string{"accepts 1 arg(s), received 0"},
8074
Setup: func(t *testing.T, ctx context.Context, clientsMock *shared.ClientsMock, clients *shared.ClientFactory) {
8175
clientsMock.AddDefaultMocks()
82-
// Set experiment flag
83-
clientsMock.Config.ExperimentsFlag = append(clientsMock.Config.ExperimentsFlag, "read-only-collaborators")
84-
clientsMock.Config.LoadExperiments(ctx, clientsMock.IO.PrintDebug)
8576
},
8677
},
8778
}, func(clients *shared.ClientFactory) *cobra.Command {

docs/reference/experiments.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ The following is a list of currently available experiments. We'll remove experim
99
* `bolt-install`: enables creating, installing, and running Bolt projects that manage their app manifest on app settings (remote manifest).
1010
* `slack create` and `slack init` now set manifest source to "app settings" (remote) for Bolt JS & Bolt Python projects ([PR#96](https://github.com/slackapi/slack-cli/pull/96)).
1111
* `slack run` and `slack install` support creating and installing Bolt Framework apps that have the manifest source set to "app settings (remote)" ([PR#111](https://github.com/slackapi/slack-cli/pull/111), [PR#154](https://github.com/slackapi/slack-cli/pull/154)).
12-
* `read-only-collaborators`: enables creating and modifying collaborator permissions via the `slack collaborator` commands.
1312

1413
## Experiments changelog
1514

internal/experiment/experiment.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ const (
3838
// manage their app manifest on app settings (remote manifest).
3939
BoltInstall Experiment = "bolt-install"
4040

41-
// The ReadOnlyAppCollaborators experiment enables creating and modifying collaborator
42-
// permissions via the `collaborator` commands.
43-
ReadOnlyAppCollaborators Experiment = "read-only-collaborators"
44-
4541
// Placeholder experiment is a placeholder for testing and does nothing... or does it?
4642
Placeholder Experiment = "placeholder"
4743
)
@@ -51,7 +47,6 @@ const (
5147
var AllExperiments = []Experiment{
5248
BoltFrameworks,
5349
BoltInstall,
54-
ReadOnlyAppCollaborators,
5550
Placeholder,
5651
}
5752

internal/experiment/experiment_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ func Test_Includes(t *testing.T) {
2626

2727
// Test expected experiments
2828
require.Equal(t, true, Includes(Experiment("bolt")))
29-
require.Equal(t, true, Includes(Experiment("read-only-collaborators")))
3029

3130
// Test invalid experiment
3231
require.Equal(t, false, Includes(Experiment("should-fail")))

internal/shared/types/permissions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func StringToAppCollaboratorPermission(input string) (AppCollaboratorPermission,
3737
case "reader":
3838
return READER, nil
3939
default:
40-
return "", fmt.Errorf("invalid")
40+
return "", fmt.Errorf("invalid permission; accepted values are \"owner\" or \"reader\"")
4141
}
4242
}
4343

0 commit comments

Comments
 (0)