You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/02/16 12:44:46 UTC

[15/37] allura git commit: [#4542] ticket:714 Sign webhook payload

[#4542] ticket:714 Sign webhook payload


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0f529d6c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0f529d6c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0f529d6c

Branch: refs/heads/ib/4542
Commit: 0f529d6c95393561b2c801a5e6d8bc555e5a4ab5
Parents: 0eb35a9
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jan 28 11:30:33 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Feb 16 10:16:47 2015 +0000

----------------------------------------------------------------------
 .../allura/ext/admin/templates/webhooks_list.html  |  1 +
 Allura/allura/model/webhook.py                     |  1 +
 Allura/allura/templates/webhooks/create_form.html  |  5 +++++
 Allura/allura/webhooks.py                          | 17 +++++++++++++++--
 4 files changed, 22 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0f529d6c/Allura/allura/ext/admin/templates/webhooks_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/webhooks_list.html b/Allura/allura/ext/admin/templates/webhooks_list.html
index 9bb2476..39df656 100644
--- a/Allura/allura/ext/admin/templates/webhooks_list.html
+++ b/Allura/allura/ext/admin/templates/webhooks_list.html
@@ -35,6 +35,7 @@
           <td>
             <a href="{{ h.app_config.url() }}">{{ h.app_config.options.mount_label }}</a>
           </td>
+          <td>{{ h.secret or '' }}</td>
           <td>
             <a href="#" title="Delete">
               <b data-icon="{{g.icons['delete'].char}}" class="ico {{g.icons['delete'].css}}" title="Delete"></b>

http://git-wip-us.apache.org/repos/asf/allura/blob/0f529d6c/Allura/allura/model/webhook.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/webhook.py b/Allura/allura/model/webhook.py
index 73b9540..05eb436 100644
--- a/Allura/allura/model/webhook.py
+++ b/Allura/allura/model/webhook.py
@@ -27,6 +27,7 @@ class Webhook(Artifact):
 
     type = FieldProperty(str)
     hook_url = FieldProperty(str)
+    secret = FieldProperty(str)
 
     def url(self):
         return '{}{}/{}/{}'.format(

http://git-wip-us.apache.org/repos/asf/allura/blob/0f529d6c/Allura/allura/templates/webhooks/create_form.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/webhooks/create_form.html b/Allura/allura/templates/webhooks/create_form.html
index a44bb5b..f3eb713 100644
--- a/Allura/allura/templates/webhooks/create_form.html
+++ b/Allura/allura/templates/webhooks/create_form.html
@@ -81,6 +81,11 @@
     </select>
     {{ error('app') }}
   </div>
+  <div>
+    <label for="secret">secret (leave empty to autogenerate)</label>
+    <input name="secret" value="{{ c.form_values['secret'] }}">
+    {{ error('secret') }}
+  </div>
 
   {% block additional_fields %}{% endblock %}
 

http://git-wip-us.apache.org/repos/asf/allura/blob/0f529d6c/Allura/allura/webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index c5dc37e..5c792be 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -17,6 +17,8 @@
 
 import logging
 import json
+import hmac
+import hashlib
 
 import requests
 from bson import ObjectId
@@ -45,6 +47,7 @@ class WebhookCreateForm(schema.Schema):
             [unicode(ac._id) for ac in self.triggered_by]))
 
     url = fev.URL(not_empty=True)
+    secret = fev.UnicodeString()
 
 
 class WebhookControllerMeta(type):
@@ -76,10 +79,13 @@ class WebhookController(BaseController):
 
     @expose()
     @require_post()
-    def create(self, url, app):
+    def create(self, url, app, secret=None):
+        if not secret:
+            secret = h.cryptographic_nonce(20)
         # TODO: catch DuplicateKeyError
         wh = M.Webhook(
             hook_url=url,
+            secret=secret,
             app_config_id=ObjectId(app),
             type=self.webhook.type)
         session(wh).flush(wh)
@@ -90,8 +96,15 @@ class WebhookController(BaseController):
 def send_webhook(webhook_id, payload):
     webhook = M.Webhook.query.get(_id=webhook_id)
     url = webhook.hook_url
-    headers = {'content-type': 'application/json'}
     json_payload = json.dumps(payload, cls=DateJSONEncoder)
+    signature = hmac.new(
+        webhook.secret.encode('utf-8'),
+        json_payload.encode('utf-8'),
+        hashlib.sha1)
+    signature = 'sha1=' + signature.hexdigest()
+    headers = {'content-type': 'application/json',
+               'User-Agent': 'Allura Webhook (https://allura.apache.org/)',
+               'X-Allura-Signature': signature}
     # TODO: catch
     # TODO: configurable timeout
     r = requests.post(url, data=json_payload, headers=headers, timeout=30)