summaryrefslogtreecommitdiffstats
path: root/app/plugin/jira/plugin.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/plugin/jira/plugin.go')
-rw-r--r--app/plugin/jira/plugin.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/app/plugin/jira/plugin.go b/app/plugin/jira/plugin.go
new file mode 100644
index 000000000..ad51e723c
--- /dev/null
+++ b/app/plugin/jira/plugin.go
@@ -0,0 +1,78 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package jira
+
+import (
+ "crypto/subtle"
+ "encoding/json"
+ "net/http"
+ "sync/atomic"
+
+ l4g "github.com/alecthomas/log4go"
+ "github.com/mattermost/platform/app/plugin"
+ "github.com/mattermost/platform/model"
+)
+
+type Plugin struct {
+ plugin.Base
+ api plugin.API
+ configuration atomic.Value
+}
+
+func (p *Plugin) Initialize(api plugin.API) {
+ p.api = api
+ p.OnConfigurationChange()
+ api.PluginRouter().HandleFunc("/webhook", p.handleWebhook).Methods("POST")
+}
+
+func (p *Plugin) config() *Configuration {
+ return p.configuration.Load().(*Configuration)
+}
+
+func (p *Plugin) OnConfigurationChange() {
+ var configuration Configuration
+ if err := p.api.LoadPluginConfiguration(&configuration); err != nil {
+ l4g.Error(err.Error())
+ }
+ p.configuration.Store(&configuration)
+}
+
+func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) {
+ config := p.config()
+ if !config.Enabled || config.Secret == "" || config.UserName == "" {
+ http.Error(w, "This plugin is not configured.", http.StatusForbidden)
+ return
+ } else if subtle.ConstantTimeCompare([]byte(r.URL.Query().Get("secret")), []byte(config.Secret)) != 1 {
+ http.Error(w, "You must provide the configured secret.", http.StatusForbidden)
+ return
+ }
+
+ var webhook Webhook
+
+ if err := json.NewDecoder(r.Body).Decode(&webhook); err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ } else if attachment, err := webhook.SlackAttachment(); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ } else if attachment == nil {
+ return
+ } else if r.URL.Query().Get("channel") == "" {
+ http.Error(w, "You must provide a channel.", http.StatusBadRequest)
+ } else if user, err := p.api.GetUserByName(config.UserName); err != nil {
+ http.Error(w, p.api.I18n(err.Message, r), err.StatusCode)
+ } else if team, err := p.api.GetTeamByName(r.URL.Query().Get("team")); err != nil {
+ http.Error(w, p.api.I18n(err.Message, r), err.StatusCode)
+ } else if channel, err := p.api.GetChannelByName(team.Id, r.URL.Query().Get("channel")); err != nil {
+ http.Error(w, p.api.I18n(err.Message, r), err.StatusCode)
+ } else if _, err := p.api.CreatePost(&model.Post{
+ ChannelId: channel.Id,
+ Type: model.POST_SLACK_ATTACHMENT,
+ UserId: user.Id,
+ Props: map[string]interface{}{
+ "from_webhook": "true",
+ "attachments": []*model.SlackAttachment{attachment},
+ },
+ }, channel.TeamId); err != nil {
+ http.Error(w, p.api.I18n(err.Message, r), err.StatusCode)
+ }
+}