From 46f448899bf715fa2b557562a6a01d80ca4fc6b4 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Thu, 22 Oct 2015 14:16:51 -0400 Subject: In webhooks UI handle error if channel can't be found, also use display name over url name, plus warning fixes --- .../user_settings/manage_incoming_hooks.jsx | 52 +++++++++++++--------- .../user_settings/manage_outgoing_hooks.jsx | 32 +++++++++++-- .../user_settings/user_settings_integrations.jsx | 4 +- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/web/react/components/user_settings/manage_incoming_hooks.jsx b/web/react/components/user_settings/manage_incoming_hooks.jsx index f5a2774a0..812169be4 100644 --- a/web/react/components/user_settings/manage_incoming_hooks.jsx +++ b/web/react/components/user_settings/manage_incoming_hooks.jsx @@ -96,7 +96,14 @@ export default class ManageIncomingHooks extends React.Component { const options = []; channels.forEach((channel) => { if (channel.type !== Constants.DM_CHANNEL) { - options.push(); + options.push( + + ); } }); @@ -108,26 +115,31 @@ export default class ManageIncomingHooks extends React.Component { const hooks = []; this.state.hooks.forEach((hook) => { const c = ChannelStore.get(hook.channel_id); - hooks.push( -
-
-
- {'URL: '}{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id} -
-
- {'Channel: '}{c.name} -
-
- - {'Remove'} - + if (c) { + hooks.push( +
+
+
+ {'URL: '}{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id} +
+
+ {'Channel: '}{c.display_name} +
+
+ + {'Remove'} + +
-
- ); + ); + } }); let displayHooks; diff --git a/web/react/components/user_settings/manage_outgoing_hooks.jsx b/web/react/components/user_settings/manage_outgoing_hooks.jsx index e83ae3bd6..f6d6b515b 100644 --- a/web/react/components/user_settings/manage_outgoing_hooks.jsx +++ b/web/react/components/user_settings/manage_outgoing_hooks.jsx @@ -128,21 +128,42 @@ export default class ManageOutgoingHooks extends React.Component { } const channels = ChannelStore.getAll(); - const options = []; + const options = []; + options.push( + + ); + channels.forEach((channel) => { if (channel.type === Constants.OPEN_CHANNEL) { - options.push(); + options.push( + + ); } }); const hooks = []; this.state.hooks.forEach((hook) => { const c = ChannelStore.get(hook.channel_id); + + if (!c && hook.channel_id && hook.channel_id.length !== 0) { + return; + } + let channelDiv; if (c) { channelDiv = (
- {'Channel: '}{c.name} + {'Channel: '}{c.display_name}
); } @@ -157,7 +178,10 @@ export default class ManageOutgoingHooks extends React.Component { } hooks.push( -
+
{'URLs: '}{hook.callback_urls.join(', ')} diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx index 231580cc3..1845ca28c 100644 --- a/web/react/components/user_settings/user_settings_integrations.jsx +++ b/web/react/components/user_settings/user_settings_integrations.jsx @@ -37,7 +37,7 @@ export default class UserSettingsIntegrationsTab extends React.Component { if (global.window.config.EnableIncomingWebhooks === 'true') { if (this.props.activeSection === 'incoming-hooks') { inputs.push( - + ); incomingHooksSection = ( @@ -68,7 +68,7 @@ export default class UserSettingsIntegrationsTab extends React.Component { if (global.window.config.EnableOutgoingWebhooks === 'true') { if (this.props.activeSection === 'outgoing-hooks') { inputs.push( - + ); outgoingHooksSection = ( -- cgit v1.2.3-1-g7c22 From a431ba2c22918412d90d00c37fb89f6841f47eb8 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Thu, 22 Oct 2015 14:27:47 -0400 Subject: Delete webhooks when the associated channel gets deleted --- api/channel.go | 27 +++++++++++++++++++++++++++ store/sql_webhook_store.go | 21 +++++++++++++++++++++ store/store.go | 1 + 3 files changed, 49 insertions(+) diff --git a/api/channel.go b/api/channel.go index 70f7eba4b..0a8489606 100644 --- a/api/channel.go +++ b/api/channel.go @@ -503,6 +503,8 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { sc := Srv.Store.Channel().Get(id) scm := Srv.Store.Channel().GetMember(id, c.Session.UserId) uc := Srv.Store.User().Get(c.Session.UserId) + ihc := Srv.Store.Webhook().GetIncomingByChannel(id) + ohc := Srv.Store.Webhook().GetOutgoingByChannel(id) if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err @@ -513,10 +515,18 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { } else if scmresult := <-scm; scmresult.Err != nil { c.Err = scmresult.Err return + } else if ihcresult := <-ihc; ihcresult.Err != nil { + c.Err = ihcresult.Err + return + } else if ohcresult := <-ohc; ohcresult.Err != nil { + c.Err = ohcresult.Err + return } else { channel := cresult.Data.(*model.Channel) user := uresult.Data.(*model.User) channelMember := scmresult.Data.(model.ChannelMember) + incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) + outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) if !c.HasPermissionsToTeam(channel.TeamId, "deleteChannel") { return @@ -540,6 +550,23 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + now := model.GetMillis() + for _, hook := range incomingHooks { + go func() { + if result := <-Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil { + l4g.Error("Encountered error deleting incoming webhook, id=" + hook.Id) + } + }() + } + + for _, hook := range outgoingHooks { + go func() { + if result := <-Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil { + l4g.Error("Encountered error deleting outgoing webhook, id=" + hook.Id) + } + }() + } + if dresult := <-Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil { c.Err = dresult.Err return diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go index 1910984f0..c758e2339 100644 --- a/store/sql_webhook_store.go +++ b/store/sql_webhook_store.go @@ -137,6 +137,27 @@ func (s SqlWebhookStore) GetIncomingByUser(userId string) StoreChannel { return storeChannel } +func (s SqlWebhookStore) GetIncomingByChannel(channelId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + var webhooks []*model.IncomingWebhook + + if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE ChannelId = :ChannelId AND DeleteAt = 0", map[string]interface{}{"ChannelId": channelId}); err != nil { + result.Err = model.NewAppError("SqlWebhookStore.GetIncomingByChannel", "We couldn't get the webhooks", "channelId="+channelId+", err="+err.Error()) + } + + result.Data = webhooks + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + func (s SqlWebhookStore) SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel { storeChannel := make(StoreChannel) diff --git a/store/store.go b/store/store.go index 27731cee1..7259556e7 100644 --- a/store/store.go +++ b/store/store.go @@ -149,6 +149,7 @@ type WebhookStore interface { SaveIncoming(webhook *model.IncomingWebhook) StoreChannel GetIncoming(id string) StoreChannel GetIncomingByUser(userId string) StoreChannel + GetIncomingByChannel(channelId string) StoreChannel DeleteIncoming(webhookId string, time int64) StoreChannel SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel GetOutgoing(id string) StoreChannel -- cgit v1.2.3-1-g7c22