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/03/06 13:35:14 UTC
[07/26] allura git commit: [#7832] ticket:731 Endpoint for creating
webhook
[#7832] ticket:731 Endpoint for creating webhook
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9e16b0b2
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9e16b0b2
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9e16b0b2
Branch: refs/heads/ib/7830
Commit: 9e16b0b2f7ff1c2ff112c264e4126b1696bf2b58
Parents: 41c054c
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Feb 20 13:52:38 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Feb 27 22:40:52 2015 +0000
----------------------------------------------------------------------
Allura/allura/tests/test_webhooks.py | 65 ++++++++++++++++++++++++++++++-
Allura/allura/webhooks.py | 61 +++++++++++++++++++++++++++++
2 files changed, 125 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/9e16b0b2/Allura/allura/tests/test_webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 5bbee21..237de87 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -657,7 +657,6 @@ class TestModels(TestWebhookBase):
dd.assert_equal(self.wh.__json__(), expected)
-
class TestWebhookRestController(TestRestApiBase):
def setUp(self):
super(TestWebhookRestController, self).setUp()
@@ -730,3 +729,67 @@ class TestWebhookRestController(TestRestApiBase):
'mod_date': unicode(webhook.mod_date),
}
dd.assert_equal(r.json, expected)
+
+ def test_create_validation(self):
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+ r = self.api_get(self.url + '/repo-push', {}, status=405)
+
+ r = self.api_post(self.url + '/repo-push', {}, status=400)
+ expected = {
+ u'result': u'error',
+ u'error': {u'url': u'Please enter a value'},
+ }
+ assert_equal(r.json, expected)
+
+ data = {'url': 'qwer', 'secret': 'qwe'}
+ r = self.app.post(self.url + '/repo-push', data, status=400)
+ expected = {
+ u'result': u'error',
+ u'error': {
+ u'url': u'You must provide a full domain name (like qwer.com)'
+ },
+ }
+ assert_equal(r.json, expected)
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+
+ def test_create(self):
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+ data = {u'url': u'http://hook.slack.com/abcd'}
+ limit = json.dumps({'git': 10})
+ with h.push_config(config, **{'webhook.repo_push.max_hooks': limit}):
+ r = self.app.post(self.url + '/repo-push', data, status=201)
+ webhook = M.Webhook.query.get(hook_url=data['url'])
+ assert_equal(webhook.secret, 'super-secret') # secret generated
+ assert_equal(r.json['result'], 'ok')
+ assert_equal(r.json['webhook']['_id'], unicode(webhook._id))
+ assert_equal(r.json['webhook']['type'], 'repo-push')
+ assert_equal(r.json['webhook']['hook_url'], data['url'])
+ assert_equal(
+ r.json['webhook']['url'],
+ u'http://localhost/rest/adobe/adobe-1/admin'
+ u'/src/webhooks/repo-push/{}'.format(webhook._id))
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks) + 1)
+
+ def test_create_duplicates(self):
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+ data = {u'url': self.webhooks[0].hook_url}
+ limit = json.dumps({'git': 10})
+ with h.push_config(config, **{'webhook.repo_push.max_hooks': limit}):
+ r = self.app.post(self.url + '/repo-push', data, status=400)
+ expected = {u'result': u'error',
+ u'error': u'_the_form: "repo-push" webhook already '
+ u'exists for Git http://httpbin.org/post/0'}
+ assert_equal(r.json, expected)
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+
+ def test_create_limit_reached(self):
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
+ data = {u'url': u'http://hook.slack.com/abcd'}
+ r = self.app.post(self.url + '/repo-push', data, status=400)
+ expected = {
+ u'result': u'error',
+ u'limits': {u'max': 3, u'used': 3},
+ u'error': u'You have exceeded the maximum number of webhooks '
+ u'you are allowed to create for this project/app'}
+ assert_equal(r.json, expected)
+ assert_equal(M.Webhook.query.find().count(), len(self.webhooks))
http://git-wip-us.apache.org/repos/asf/allura/blob/9e16b0b2/Allura/allura/webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index dffaa21..fe41342 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -28,6 +28,7 @@ from bson import ObjectId
from tg import expose, validate, redirect, flash, config
from tg.decorators import with_trailing_slash, without_trailing_slash
from pylons import tmpl_context as c
+from pylons import response
from formencode import validators as fev, schema, Invalid
from ming.odm import session
from webob import exc
@@ -199,6 +200,66 @@ class WebhookRestController(BaseController):
self.create_form = WebhookController.create_form
self.edit_form = WebhookController.edit_form
+ def _error(self, e):
+ error = getattr(e, 'error_dict', None)
+ if error:
+ _error = {}
+ for k, v in error.iteritems():
+ _error[k] = unicode(v)
+ return _error
+ error = getattr(e, 'msg', None)
+ if not error:
+ error = getattr(e, 'message', '')
+ return error
+
+ def update_webhook(self, wh, url, secret=None):
+ controller = WebhookController(self.sender.__class__, self.app)
+ controller.update_webhook(wh, url, secret)
+
+ @expose('json:')
+ @require_post()
+ def index(self, **kw):
+ response.content_type = 'application/json'
+ try:
+ params = {'secret': kw.pop('secret', ''),
+ 'url': kw.pop('url', None)}
+ valid = self.create_form().to_python(params)
+ except Exception as e:
+ response.status_int = 400
+ return {'result': 'error', 'error': self._error(e)}
+ if self.sender.enforce_limit(self.app):
+ webhook = M.Webhook(
+ type=self.sender.type,
+ app_config_id=self.app.config._id)
+ try:
+ self.update_webhook(webhook, valid['url'], valid['secret'])
+ except Invalid as e:
+ response.status_int = 400
+ return {'result': 'error', 'error': self._error(e)}
+ M.AuditLog.log('add webhook %s %s %s',
+ webhook.type, webhook.hook_url,
+ webhook.app_config.url())
+ response.status_int = 201
+ return {'result': 'ok', 'webhook': webhook.__json__()}
+ else:
+ limits = {
+ 'max': M.Webhook.max_hooks(
+ self.sender.type,
+ self.app.config.tool_name),
+ 'used': M.Webhook.query.find({
+ 'type': self.sender.type,
+ 'app_config_id': self.app.config._id,
+ }).count(),
+ }
+ resp = {
+ 'result': 'error',
+ 'error': 'You have exceeded the maximum number of webhooks '
+ 'you are allowed to create for this project/app',
+ 'limits': limits,
+ }
+ response.status_int = 400
+ return resp
+
@expose('json:')
def _default(self, webhook, **kw):
form = self.edit_form(self.sender, self.app)