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:16 UTC
[09/26] allura git commit: [#7832] ticket:731 Endpoint for editing
webhooks
[#7832] ticket:731 Endpoint for editing webhooks
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/09791466
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/09791466
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/09791466
Branch: refs/heads/ib/7830
Commit: 0979146633b40f75329695b1e2b27e4721ea20cd
Parents: 9e16b0b
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Feb 20 16:27:06 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Feb 27 22:40:52 2015 +0000
----------------------------------------------------------------------
Allura/allura/tests/test_webhooks.py | 125 +++++++++++++++++++++++++-----
Allura/allura/webhooks.py | 38 ++++++++-
2 files changed, 140 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/09791466/Allura/allura/tests/test_webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 237de87..ee9cd0b 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -721,20 +721,23 @@ class TestWebhookRestController(TestRestApiBase):
webhook = self.webhooks[0]
r = self.api_get('{}/repo-push/{}'.format(self.url, webhook._id))
expected = {
- '_id': unicode(webhook._id),
- 'url': 'http://localhost/rest/adobe/adobe-1/admin'
- '/src/webhooks/repo-push/{}'.format(webhook._id),
- 'type': 'repo-push',
- 'hook_url': 'http://httpbin.org/post/0',
- 'mod_date': unicode(webhook.mod_date),
+ u'result': u'ok',
+ u'webhook': {
+ '_id': unicode(webhook._id),
+ 'url': 'http://localhost/rest/adobe/adobe-1/admin'
+ '/src/webhooks/repo-push/{}'.format(webhook._id),
+ 'type': 'repo-push',
+ 'hook_url': 'http://httpbin.org/post/0',
+ '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_get(self.url + '/repo-push', status=405)
- r = self.api_post(self.url + '/repo-push', {}, status=400)
+ r = self.api_post(self.url + '/repo-push', status=400)
expected = {
u'result': u'error',
u'error': {u'url': u'Please enter a value'},
@@ -742,7 +745,7 @@ class TestWebhookRestController(TestRestApiBase):
assert_equal(r.json, expected)
data = {'url': 'qwer', 'secret': 'qwe'}
- r = self.app.post(self.url + '/repo-push', data, status=400)
+ r = self.api_post(self.url + '/repo-push', status=400, **data)
expected = {
u'result': u'error',
u'error': {
@@ -757,17 +760,24 @@ class TestWebhookRestController(TestRestApiBase):
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)
+ msg = 'add webhook repo-push {} {}'.format(
+ data['url'], self.git.config.url())
+ with td.audits(msg):
+ r = self.api_post(self.url + '/repo-push', status=201, **data)
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))
+ expected = {
+ u'result': u'ok',
+ u'webhook': {
+ '_id': unicode(webhook._id),
+ 'url': 'http://localhost/rest/adobe/adobe-1/admin'
+ '/src/webhooks/repo-push/{}'.format(webhook._id),
+ 'type': 'repo-push',
+ 'hook_url': data['url'],
+ 'mod_date': unicode(webhook.mod_date),
+ },
+ }
+ dd.assert_equal(r.json, expected)
assert_equal(M.Webhook.query.find().count(), len(self.webhooks) + 1)
def test_create_duplicates(self):
@@ -775,7 +785,7 @@ class TestWebhookRestController(TestRestApiBase):
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)
+ r = self.api_post(self.url + '/repo-push', status=400, **data)
expected = {u'result': u'error',
u'error': u'_the_form: "repo-push" webhook already '
u'exists for Git http://httpbin.org/post/0'}
@@ -785,7 +795,7 @@ class TestWebhookRestController(TestRestApiBase):
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)
+ r = self.api_post(self.url + '/repo-push', status=400, **data)
expected = {
u'result': u'error',
u'limits': {u'max': 3, u'used': 3},
@@ -793,3 +803,78 @@ class TestWebhookRestController(TestRestApiBase):
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))
+
+ def test_edit_validation(self):
+ webhook = self.webhooks[0]
+ url = u'{}/repo-push/{}'.format(self.url, webhook._id)
+ data = {'url': 'qwe', 'secret': 'qwe'}
+ r = self.api_post(url, status=400, **data)
+ expected = {
+ u'result': u'error',
+ u'error': {
+ u'url': u'You must provide a full domain name (like qwe.com)'
+ },
+ }
+ assert_equal(r.json, expected)
+
+ def test_edit(self):
+ webhook = self.webhooks[0]
+ url = '{}/repo-push/{}'.format(self.url, webhook._id)
+ # change only url
+ data = {'url': 'http://hook.slack.com/abcd'}
+ msg = ('edit webhook repo-push\n'
+ 'http://httpbin.org/post/0 => http://hook.slack.com/abcd\n')
+ with td.audits(msg):
+ r = self.api_post(url, status=200, **data)
+ webhook = M.Webhook.query.get(_id=webhook._id)
+ assert_equal(webhook.hook_url, data['url'])
+ assert_equal(webhook.secret, 'secret-0')
+ expected = {
+ u'result': u'ok',
+ u'webhook': {
+ '_id': unicode(webhook._id),
+ 'url': 'http://localhost/rest/adobe/adobe-1/admin'
+ '/src/webhooks/repo-push/{}'.format(webhook._id),
+ 'type': 'repo-push',
+ 'hook_url': data['url'],
+ 'mod_date': unicode(webhook.mod_date),
+ },
+ }
+ dd.assert_equal(r.json, expected)
+
+ # change only secret
+ data = {'secret': 'new-secret'}
+ msg = ('edit webhook repo-push\n'
+ 'http://hook.slack.com/abcd => http://hook.slack.com/abcd\n'
+ 'secret changed')
+ with td.audits(msg):
+ r = self.api_post(url, status=200, **data)
+ webhook = M.Webhook.query.get(_id=webhook._id)
+ assert_equal(webhook.hook_url, 'http://hook.slack.com/abcd')
+ assert_equal(webhook.secret, 'new-secret')
+ expected = {
+ u'result': u'ok',
+ u'webhook': {
+ '_id': unicode(webhook._id),
+ 'url': 'http://localhost/rest/adobe/adobe-1/admin'
+ '/src/webhooks/repo-push/{}'.format(webhook._id),
+ 'type': 'repo-push',
+ 'hook_url': 'http://hook.slack.com/abcd',
+ 'mod_date': unicode(webhook.mod_date),
+ },
+ }
+ dd.assert_equal(r.json, expected)
+
+ def test_edit_duplicates(self):
+ webhook = self.webhooks[0]
+ url = '{}/repo-push/{}'.format(self.url, webhook._id)
+ # change only url
+ data = {'url': 'http://httpbin.org/post/1'}
+ r = self.api_post(url, status=400, **data)
+ expected = {u'result': u'error',
+ u'error': u'_the_form: "repo-push" webhook already '
+ u'exists for Git http://httpbin.org/post/1'}
+ assert_equal(r.json, expected)
+ webhook = M.Webhook.query.get(_id=webhook._id)
+ assert_equal(webhook.hook_url, 'http://httpbin.org/post/0')
+ assert_equal(webhook.secret, 'secret-0')
http://git-wip-us.apache.org/repos/asf/allura/blob/09791466/Allura/allura/webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index fe41342..f30994f 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -28,7 +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 pylons import response, request
from formencode import validators as fev, schema, Invalid
from ming.odm import session
from webob import exc
@@ -240,7 +240,10 @@ class WebhookRestController(BaseController):
webhook.type, webhook.hook_url,
webhook.app_config.url())
response.status_int = 201
- return {'result': 'ok', 'webhook': webhook.__json__()}
+ # refetch updated values (e.g. mod_date)
+ session(webhook).expunge(webhook)
+ webhook = M.Webhook.query.get(_id=webhook._id)
+ return {'result': 'ok', 'webhook': webhook}
else:
limits = {
'max': M.Webhook.max_hooks(
@@ -267,7 +270,36 @@ class WebhookRestController(BaseController):
wh = form.fields['webhook'].to_python(webhook)
except Invalid:
raise exc.HTTPNotFound()
- return wh.__json__()
+ if request.method == 'POST':
+ return self._edit(wh, form, **kw)
+ else:
+ return {'result': 'ok', 'webhook': wh}
+
+ def _edit(self, webhook, form, **kw):
+ old_secret = webhook.secret
+ old_url = webhook.hook_url
+ try:
+ params = {'secret': kw.pop('secret', old_secret),
+ 'url': kw.pop('url', old_url),
+ 'webhook': unicode(webhook._id)}
+ valid = form.to_python(params)
+ except Exception as e:
+ response.status_int = 400
+ return {'result': 'error', 'error': self._error(e)}
+ 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(
+ 'edit webhook %s\n%s => %s\n%s',
+ webhook.type, old_url, valid['url'],
+ 'secret changed' if old_secret != valid['secret'] else '')
+ # refetch updated values (e.g. mod_date)
+ session(webhook).expunge(webhook)
+ webhook = M.Webhook.query.get(_id=webhook._id)
+ return {'result': 'ok',
+ 'webhook': webhook}
class SendWebhookHelper(object):