@@ -2,6 +2,7 @@ package plugin
2
2
3
3
import (
4
4
"fmt"
5
+ "net/http"
5
6
"strings"
6
7
7
8
"github.com/pkg/errors"
@@ -22,11 +23,11 @@ type Handler struct {
22
23
23
24
var azureDevopsCommandHandler = Handler {
24
25
handlers : map [string ]HandlerFunc {
25
- "help" : azureDevopsHelpCommand ,
26
- "connect" : azureDevopsConnectCommand ,
27
- "disconnect" : azureDevopsDisconnectCommand ,
28
- "link" : azureDevopsAccountConnectionCheck ,
29
- "boards" : azureDevopsAccountConnectionCheck ,
26
+ constants . CommandHelp : azureDevopsHelpCommand ,
27
+ constants . CommandConnect : azureDevopsConnectCommand ,
28
+ constants . CommandDisconnect : azureDevopsDisconnectCommand ,
29
+ constants . CommandLink : azureDevopsAccountConnectionCheck ,
30
+ constants . CommandBoards : azureDevopsBoardsCommand ,
30
31
},
31
32
defaultHandler : executeDefault ,
32
33
}
@@ -45,31 +46,44 @@ func (ch *Handler) Handle(p *Plugin, c *plugin.Context, commandArgs *model.Comma
45
46
}
46
47
47
48
func (p * Plugin ) getAutoCompleteData () * model.AutocompleteData {
48
- azureDevops := model .NewAutocompleteData (constants .CommandTriggerName , "[command]" , "Available commands: help, connect, disconnect, create, link, subscribe, subscriptions, unsubscribe" )
49
+ azureDevops := model .NewAutocompleteData (constants .CommandTriggerName , "[command]" , fmt . Sprintf ( "Available commands: %s, %s, %s, %s, %s" , constants . CommandHelp , constants . CommandConnect , constants . CommandDisconnect , constants . CommandLink , constants . CommandBoards ) )
49
50
50
- help := model .NewAutocompleteData ("help" , "" , fmt .Sprintf ("Show %s slash command help" , constants .CommandTriggerName ))
51
+ help := model .NewAutocompleteData (constants . CommandHelp , "" , fmt .Sprintf ("Show %s slash command help" , constants .CommandTriggerName ))
51
52
azureDevops .AddCommand (help )
52
53
53
- connect := model .NewAutocompleteData ("connect" , "" , "Connect to your Azure DevOps account" )
54
+ connect := model .NewAutocompleteData (constants . CommandConnect , "" , "Connect to your Azure DevOps account" )
54
55
azureDevops .AddCommand (connect )
55
56
56
- disconnect := model .NewAutocompleteData ("disconnect" , "" , "Disconnect your Azure DevOps account" )
57
+ disconnect := model .NewAutocompleteData (constants . CommandDisconnect , "" , "Disconnect your Azure DevOps account" )
57
58
azureDevops .AddCommand (disconnect )
58
59
59
- link := model .NewAutocompleteData ("link" , "[projectURL]" , "Link a project" )
60
+ link := model .NewAutocompleteData (constants .CommandLink , "" , "Link a project" )
61
+ link .AddTextArgument ("URL of the project to be linked" , "[projectURL]" , "" )
60
62
azureDevops .AddCommand (link )
61
63
62
- create := model .NewAutocompleteData ("boards create [title] [description]" , "" , "Create a new task" )
63
- azureDevops .AddCommand (create )
64
-
65
- subscribe := model .NewAutocompleteData ("boards subscribe" , "" , "Add a boards subscription" )
66
- azureDevops .AddCommand (subscribe )
67
-
68
- subscriptions := model .NewAutocompleteData ("boards subscriptions" , "" , "View board's subscriptions in the current channel" )
69
- azureDevops .AddCommand (subscriptions )
70
-
71
- unsubscribe := model .NewAutocompleteData ("boards unsubscribe [subscription id]" , "" , "Unsubscribe a board subscription" )
72
- azureDevops .AddCommand (unsubscribe )
64
+ subscription := model .NewAutocompleteData (constants .CommandSubscription , "" , "Add/list/unsubscribe subscriptions" )
65
+ subscriptionAdd := model .NewAutocompleteData (constants .CommandAdd , "" , "Add a new subscription" )
66
+ subscriptionView := model .NewAutocompleteData (constants .CommandList , "" , "List subscriptions" )
67
+ subscriptionUnsubscribe := model .NewAutocompleteData (constants .CommandDelete , "" , "Unsubscribe a subscription" )
68
+ subscriptionUnsubscribe .AddTextArgument ("ID of the subscription to be deleted" , "[subscription id]" , "" )
69
+ subscriptionCreatedByMe := model .NewAutocompleteData (constants .FilterCreatedByMe , "" , "Created By Me" )
70
+ subscriptionShowForAllChannels := model .NewAutocompleteData (constants .FilterAllChannels , "" , "Show for all channels or You can leave this argument to show for the current channel only" )
71
+ subscriptionCreatedByMe .AddCommand (subscriptionShowForAllChannels )
72
+ subscriptionView .AddCommand (subscriptionCreatedByMe )
73
+ subscriptionCreatedByAnyone := model .NewAutocompleteData (constants .FilterCreatedByAnyone , "" , "Created By Anyone" )
74
+ subscriptionCreatedByAnyone .AddCommand (subscriptionShowForAllChannels )
75
+ subscriptionView .AddCommand (subscriptionCreatedByAnyone )
76
+ subscription .AddCommand (subscriptionAdd )
77
+ subscription .AddCommand (subscriptionView )
78
+ subscription .AddCommand (subscriptionUnsubscribe )
79
+
80
+ boards := model .NewAutocompleteData (constants .CommandBoards , "" , "Create a new work-item or add/list/delete subscriptions" )
81
+ create := model .NewAutocompleteData (constants .CommandCreate , "" , "Create a new work-item" )
82
+ create .AddTextArgument ("Title" , "[title]" , "" )
83
+ create .AddTextArgument ("Description" , "[description]" , "" )
84
+ boards .AddCommand (create )
85
+ boards .AddCommand (subscription )
86
+ azureDevops .AddCommand (boards )
73
87
74
88
return azureDevops
75
89
}
@@ -83,7 +97,7 @@ func (p *Plugin) getCommand() (*model.Command, error) {
83
97
return & model.Command {
84
98
Trigger : constants .CommandTriggerName ,
85
99
AutoComplete : true ,
86
- AutoCompleteDesc : "Available commands: help" ,
100
+ AutoCompleteDesc : fmt . Sprintf ( "Available commands: %s, %s, %s, %s, %s" , constants . CommandHelp , constants . CommandConnect , constants . CommandDisconnect , constants . CommandLink , constants . CommandBoards ) ,
87
101
AutoCompleteHint : "[command]" ,
88
102
AutocompleteData : p .getAutoCompleteData (),
89
103
AutocompleteIconData : iconData ,
@@ -94,37 +108,59 @@ func azureDevopsAccountConnectionCheck(p *Plugin, c *plugin.Context, commandArgs
94
108
if isConnected := p .UserAlreadyConnected (commandArgs .UserId ); ! isConnected {
95
109
return p .sendEphemeralPostForCommand (commandArgs , p .getConnectAccountFirstMessage ())
96
110
}
111
+ return & model.CommandResponse {}, nil
112
+ }
113
+
114
+ func azureDevopsBoardsCommand (p * Plugin , c * plugin.Context , commandArgs * model.CommandArgs , args ... string ) (* model.CommandResponse , * model.AppError ) {
115
+ // Check if user's Azure DevOps account is connected
116
+ if isConnected := p .UserAlreadyConnected (commandArgs .UserId ); ! isConnected {
117
+ return p .sendEphemeralPostForCommand (commandArgs , p .getConnectAccountFirstMessage ())
118
+ }
97
119
98
- if len (args ) > 0 {
99
- switch {
100
- case args [0 ] == "subscriptions" :
101
- return azureDevopsListSubscriptionsCommand (p , c , commandArgs , args ... )
102
- case args [0 ] == "unsubscribe" :
120
+ // Validate commands and their arguments
121
+ switch {
122
+ case len (args ) >= 1 && args [0 ] == constants .CommandCreate :
123
+ return & model.CommandResponse {}, nil
124
+ // For "subscription" command there must be at least 2 arguments
125
+ case len (args ) >= 2 && args [0 ] == constants .CommandSubscription :
126
+ switch args [1 ] {
127
+ case constants .CommandList :
128
+ // For "list" command there must be at least 3 arguments
129
+ if len (args ) >= 3 && (args [2 ] == constants .FilterCreatedByMe || args [2 ] == constants .FilterCreatedByAnyone ) {
130
+ return azureDevopsListSubscriptionsCommand (p , c , commandArgs , args ... )
131
+ }
132
+ case constants .CommandDelete :
103
133
return azureDevopsUnsubscribeCommand (p , c , commandArgs , args ... )
134
+ case constants .CommandAdd :
135
+ return & model.CommandResponse {}, nil
104
136
}
105
137
}
106
138
107
- return & model. CommandResponse {}, nil
139
+ return executeDefault ( p , c , commandArgs , args ... )
108
140
}
109
141
110
142
func azureDevopsUnsubscribeCommand (p * Plugin , c * plugin.Context , commandArgs * model.CommandArgs , args ... string ) (* model.CommandResponse , * model.AppError ) {
111
- if len (args ) < 2 {
143
+ if len (args ) < 3 {
112
144
return p .sendEphemeralPostForCommand (commandArgs , "Subscription ID is not provided" )
113
145
}
114
146
115
- subscriptionList , err := p .Store .GetAllSubscriptions (commandArgs . UserId )
147
+ subscriptionList , err := p .Store .GetAllSubscriptions ("" )
116
148
if err != nil {
117
149
p .API .LogError (constants .FetchSubscriptionListError , "Error" , err .Error ())
118
150
return p .sendEphemeralPostForCommand (commandArgs , constants .GenericErrorMessage )
119
151
}
120
152
153
+ subscriptionIDToBeDeleted := args [2 ]
121
154
for _ , subscription := range subscriptionList {
122
- if subscription .SubscriptionID == args [ 1 ] {
123
- if _ , err := p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q is being deleted" , args [ 1 ] )); err != nil {
155
+ if subscription .SubscriptionID == subscriptionIDToBeDeleted {
156
+ if _ , err := p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q is being deleted" , subscriptionIDToBeDeleted )); err != nil {
124
157
p .API .LogError ("Error in sending ephemeral post" , "Error" , err .Error ())
125
158
}
126
159
127
- if _ , err := p .Client .DeleteSubscription (subscription .OrganizationName , subscription .SubscriptionID , commandArgs .UserId ); err != nil {
160
+ if statusCode , err := p .Client .DeleteSubscription (subscription .OrganizationName , subscription .SubscriptionID , commandArgs .UserId ); err != nil {
161
+ if statusCode == http .StatusForbidden {
162
+ return p .sendEphemeralPostForCommand (commandArgs , constants .ErrorAdminAccess )
163
+ }
128
164
p .API .LogError ("Error in deleting subscription" , "Error" , err .Error ())
129
165
return p .sendEphemeralPostForCommand (commandArgs , constants .GenericErrorMessage )
130
166
}
@@ -140,21 +176,30 @@ func azureDevopsUnsubscribeCommand(p *Plugin, c *plugin.Context, commandArgs *mo
140
176
& model.WebsocketBroadcast {UserId : commandArgs .UserId },
141
177
)
142
178
143
- return p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q is successfully deleted" , args [ 1 ] ))
179
+ return p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q is successfully deleted" , subscriptionIDToBeDeleted ))
144
180
}
145
181
}
146
182
147
- return p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q does not exist" , args [ 1 ] ))
183
+ return p .sendEphemeralPostForCommand (commandArgs , fmt .Sprintf ("Boards subscription with ID: %q does not exist" , subscriptionIDToBeDeleted ))
148
184
}
149
185
150
186
func azureDevopsListSubscriptionsCommand (p * Plugin , c * plugin.Context , commandArgs * model.CommandArgs , args ... string ) (* model.CommandResponse , * model.AppError ) {
151
- subscriptionList , err := p .Store .GetAllSubscriptions (commandArgs .UserId )
187
+ // If 4th argument is present then it must be "all_channels"
188
+ if len (args ) >= 4 && args [3 ] != constants .FilterAllChannels {
189
+ return executeDefault (p , c , commandArgs , args ... )
190
+ }
191
+
192
+ subscriptionList , err := p .Store .GetAllSubscriptions ("" )
152
193
if err != nil {
153
194
p .API .LogError (constants .FetchSubscriptionListError , "Error" , err .Error ())
154
195
return p .sendEphemeralPostForCommand (commandArgs , constants .GenericErrorMessage )
155
196
}
156
197
157
- return p .sendEphemeralPostForCommand (commandArgs , p .ParseSubscriptionsToCommandResponse (subscriptionList , commandArgs .ChannelId ))
198
+ showForChannelID := commandArgs .ChannelId
199
+ if len (args ) >= 4 && args [3 ] == constants .FilterAllChannels {
200
+ showForChannelID = ""
201
+ }
202
+ return p .sendEphemeralPostForCommand (commandArgs , p .ParseSubscriptionsToCommandResponse (subscriptionList , showForChannelID , args [2 ], commandArgs .UserId ))
158
203
}
159
204
160
205
func azureDevopsHelpCommand (p * Plugin , c * plugin.Context , commandArgs * model.CommandArgs , args ... string ) (* model.CommandResponse , * model.AppError ) {
0 commit comments