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:54 UTC
[23/37] allura git commit: [#4542] ticket:715 Add thresholds
[#4542] ticket:715 Add thresholds
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e7c60a34
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e7c60a34
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e7c60a34
Branch: refs/heads/ib/4542
Commit: e7c60a345d82844f9d529d9171991b74b60f3515
Parents: 5c82af91
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 2 12:53:03 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Feb 16 10:17:38 2015 +0000
----------------------------------------------------------------------
Allura/allura/tests/test_webhooks.py | 42 +++++++++++++++++++++++++++++++
Allura/allura/webhooks.py | 31 +++++++++++++++++------
Allura/development.ini | 6 +++++
3 files changed, 72 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/e7c60a34/Allura/allura/tests/test_webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 99e5f91..791128e 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -202,6 +202,25 @@ class TestWebhookController(TestController):
'"repo-push" webhook already exists for Git http://httpbin.org/post')
assert_equal(M.Webhook.query.find().count(), 1)
+ def test_create_limit_reached(self):
+ assert_equal(M.Webhook.query.find().count(), 0)
+ limit = json.dumps({'git': 1})
+ with h.push_config(config, **{'webhook.repo_push.max_hooks': limit}):
+ data = {'url': u'http://httpbin.org/post',
+ 'app': unicode(self.git.config._id),
+ 'secret': ''}
+ r = self.create_webhook(data).follow().follow(status=200)
+ assert_equal(M.Webhook.query.find().count(), 1)
+
+ r = self.app.post(self.url + '/repo-push/create', data)
+ wf = json.loads(self.webflash(r))
+ assert_equal(wf['status'], 'error')
+ assert_equal(
+ wf['message'],
+ 'You have exceeded the maximum number of projects '
+ 'you are allowed to create for this project/app')
+ assert_equal(M.Webhook.query.find().count(), 1)
+
def test_create_validation(self):
assert_equal(M.Webhook.query.find().count(), 0)
r = self.app.post(
@@ -468,6 +487,29 @@ class TestRepoPushWebhookSender(TestWebhookBase):
}
assert_equal(result, expected_result)
+ def test_enforce_limit(self):
+ def add_webhooks(suffix, n):
+ for i in range(n):
+ webhook = M.Webhook(
+ type='repo-push',
+ app_config_id=self.git.config._id,
+ hook_url='http://httpbin.org/{}/{}'.format(suffix, i),
+ secret='secret')
+ session(webhook).flush(webhook)
+
+ sender = RepoPushWebhookSender()
+ # default
+ assert_equal(sender.enforce_limit(self.git.config), True)
+ add_webhooks('one', 3)
+ assert_equal(sender.enforce_limit(self.git.config), False)
+
+ # config
+ limit = json.dumps({'git': 5})
+ with h.push_config(config, **{'webhook.repo_push.max_hooks': limit}):
+ assert_equal(sender.enforce_limit(self.git.config), True)
+ add_webhooks('two', 3)
+ assert_equal(sender.enforce_limit(self.git.config), False)
+
class TestModels(TestWebhookBase):
http://git-wip-us.apache.org/repos/asf/allura/blob/e7c60a34/Allura/allura/webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index e13086d..7df8a42 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -22,7 +22,7 @@ import hashlib
import requests
from bson import ObjectId
-from tg import expose, validate, redirect, flash
+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 formencode import validators as fev, schema, Invalid
@@ -125,7 +125,7 @@ class WebhookController(BaseController):
def __init__(self, sender):
super(WebhookController, self).__init__()
- self.sender = sender
+ self.sender = sender()
def gen_secret(self):
return h.cryptographic_nonce(20)
@@ -169,11 +169,15 @@ class WebhookController(BaseController):
@expose()
@require_post()
def create(self, url, app, secret):
- wh = M.Webhook(type=self.sender.type)
- self.update_webhook(wh, url, app, secret)
- M.AuditLog.log('add webhook %s %s %s',
- wh.type, wh.hook_url, wh.app_config.url())
- flash('Created successfully', 'ok')
+ if self.sender.enforce_limit(app):
+ wh = M.Webhook(type=self.sender.type)
+ self.update_webhook(wh, url, app, secret)
+ M.AuditLog.log('add webhook %s %s %s',
+ wh.type, wh.hook_url, wh.app_config.url())
+ flash('Created successfully', 'ok')
+ else:
+ flash('You have exceeded the maximum number of projects '
+ 'you are allowed to create for this project/app', 'error')
redirect(c.project.url() + 'admin/webhooks/')
@expose()
@@ -278,6 +282,19 @@ class WebhookSender(object):
else:
log.warn('Webhook fires too often: %s. Skipping', webhook)
+ def enforce_limit(self, app_config):
+ '''
+ Checks if limit of webhooks created for given project/app is reached.
+ Returns False if limit is reached, True otherwise.
+ '''
+ _type = self.type.replace('-', '_')
+ limits = json.loads(config.get('webhook.%s.max_hooks' % _type, '{}'))
+ count = M.Webhook.query.find(dict(
+ app_config_id=app_config._id,
+ type=self.type,
+ )).count()
+ return count < limits.get(app_config.tool_name.lower(), 3)
+
class RepoPushWebhookSender(WebhookSender):
type = 'repo-push'
http://git-wip-us.apache.org/repos/asf/allura/blob/e7c60a34/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 39a9efa..f08ffb7 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -135,6 +135,12 @@ user_prefs.maximum_claimed_emails = 20
# e.g. for repo-push webhook:
# webhook.repo_push.limit = 10
+# Limit max number of hooks that can be created for given project/app
+# Option name format: same as above.
+# Value format: json dict, where keys are app names (as appears in
+# `WebhookSender.triggered_by`) and values are actual limits (default=3), e.g.:
+# webhook.repo_push.max_hooks = {"git": 3, "hg": 3, "svn": 3}
+
# Additional fields for admin project/user search
# Note: whitespace after comma is important!
# search.project.additional_search_fields = private, url, title