You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/04/03 21:57:46 UTC

[allura] 10/11: [#8273] tg 2.3.2: fix Invalid being raised inside controller

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8273
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2e6eaf6d936092d3892fef2cc29e572205b521e5
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue Apr 2 10:23:50 2019 -0400

    [#8273] tg 2.3.2: fix Invalid being raised inside controller
---
 Allura/allura/controllers/auth.py                   |  6 ++----
 Allura/allura/controllers/discuss.py                |  8 ++++----
 Allura/allura/controllers/repository.py             | 18 ++++++++++++++----
 Allura/allura/webhooks.py                           | 21 +++++++++++++++++----
 .../forgegit/tests/functional/test_controllers.py   | 10 ++++++++++
 5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index e10fdd0..008de84 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -482,11 +482,10 @@ class AuthController(BaseController):
     @expose()
     @require_post()
     @without_trailing_slash
-    @validate(V.NullValidator(), error_handler=pwd_expired)
+    @validate(F.password_change_form, error_handler=pwd_expired)
     def pwd_expired_change(self, **kw):
         require_authenticated()
         return_to = kw.get('return_to')
-        kw = F.password_change_form.to_python(kw, None)
         ap = plugin.AuthenticationProvider.get(request)
         try:
             expired_username = session.get('expired-username')
@@ -643,9 +642,8 @@ class PreferencesController(BaseController):
 
     @expose()
     @require_post()
-    @validate(V.NullValidator(), error_handler=index)
+    @validate(F.password_change_form, error_handler=index)
     def change_password(self, **kw):
-        kw = F.password_change_form.to_python(kw, None)
         ap = plugin.AuthenticationProvider.get(request)
         try:
             ap.set_password(c.user, kw['oldpw'], kw['pw'])
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 3984c73..7209242 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -260,7 +260,7 @@ def handle_post_or_reply(thread, edit_widget, rate_limit, kw, parent_post_id=Non
     rate_limit(M.Post, "Comment", redir=request.referrer)
     if thread.ref:
         require_access(thread.ref.artifact, 'post')
-    kw = edit_widget.to_python(kw, None)
+    kw = edit_widget.to_python(kw, None)  # could raise Invalid, but doesn't seem like it ever does
     if not kw['text']:
         flash('Your post was not saved. You must provide content.',
               'error')
@@ -310,7 +310,7 @@ class PostController(BaseController):
         c.post = self.W.post
         if request.method == 'POST':
             require_access(self.post, 'moderate')
-            post_fields = self.W.edit_post.to_python(kw, None)
+            post_fields = self.W.edit_post.to_python(kw, None)  # could raise Invalid, but doesn't seem like it ever does
             file_info = post_fields.pop('file_info', None)
             self.post.add_multiple_attachments(file_info)
             for k, v in post_fields.iteritems():
@@ -554,7 +554,7 @@ class PostRestController(PostController):
     @validate(pass_validator, error_handler=h.json_validation_error)
     def reply(self, **kw):
         require_access(self.thread, 'post')
-        kw = self.W.edit_post.to_python(kw, None)
+        kw = self.W.edit_post.to_python(kw, None)  # could raise Invalid, but doesn't seem like it ever does
         post = self.thread.post(parent_id=self.post._id, **kw)
         self.thread.num_replies += 1
         redirect(post.slug.split('/')[-1] + '/')
@@ -573,7 +573,7 @@ class ThreadRestController(ThreadController):
     @validate(pass_validator, error_handler=h.json_validation_error)
     def new(self, **kw):
         require_access(self.thread, 'post')
-        kw = self.W.edit_post.to_python(kw, None)
+        kw = self.W.edit_post.to_python(kw, None)  # could raise Invalid, but doesn't seem like it ever does
         p = self.thread.add_post(**kw)
         redirect(p.slug + '/')
 
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 8cae021..db69358 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -22,6 +22,7 @@ from datetime import datetime
 from urllib import quote, unquote
 from collections import defaultdict, OrderedDict
 
+
 from ming.utils import LazyProperty
 from paste.deploy.converters import asbool
 from tg import tmpl_context as c, app_globals as g
@@ -31,6 +32,7 @@ import tg
 from tg import redirect, expose, flash, validate
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from tg import session as web_session
+import formencode
 from formencode import validators
 from bson import ObjectId
 from ming.base import Object
@@ -187,10 +189,14 @@ class RepoRootController(BaseController, FeedController):
         }
 
     @memorable_forget()
-    @expose()
+    @expose('jinja:allura:templates/repo/request_merge.html')  # needed when we "return self.request_merge(...)"
     @require_post()
     def do_request_merge(self, **kw):
-        kw = self.mr_widget.to_python(kw)
+        try:
+            kw = self.mr_widget.to_python(kw)
+        except formencode.Invalid:
+            # trigger error_handler directly
+            return self.request_merge(**kw)
         downstream = dict(
             project_id=c.project._id,
             mount_point=c.app.config.options.mount_point,
@@ -459,11 +465,15 @@ class MergeRequestController(object):
         }
 
     @memorable_forget()
-    @expose()
+    @expose('jinja:allura:templates/repo/merge_request_edit.html')   # needed when we "return self.edit(...)"
     @require_post()
     def do_request_merge_edit(self, **kw):
         require_access(self.req, 'write')
-        kw = self.mr_widget_edit.to_python(kw)
+        try:
+            kw = self.mr_widget_edit.to_python(kw)
+        except formencode.Invalid:
+            # trigger error_handler directly
+            return self.edit(**kw)
         changes = OrderedDict()
         if self.req.summary != kw['summary']:
             changes['Summary'] = [self.req.summary, kw['summary']]
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index 57871e6..be9b75b 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -135,14 +135,21 @@ class WebhookController(BaseController, AdminControllerMixin):
                 'action': 'create',
                 'form': self.create_form()}
 
-    @expose()
+    @expose('jinja:allura:templates/webhooks/create_form.html')  # needed when we "return self.index(...)"
     @require_post()
+    # @validate set dynamically in WebhookControllerMeta
     def create(self, url, secret):
         if self.sender.enforce_limit(self.app):
             webhook = M.Webhook(
                 type=self.sender.type,
                 app_config_id=self.app.config._id)
-            self.update_webhook(webhook, url, secret)
+            try:
+                self.update_webhook(webhook, url, secret)
+            except Invalid as e:
+                # trigger error_handler directly
+                c.form_errors['_the_form'] = e
+                return self.index(url=url, secret=secret)
+
             M.AuditLog.log('add webhook %s %s %s',
                            webhook.type, webhook.hook_url,
                            webhook.app_config.url())
@@ -152,12 +159,18 @@ class WebhookController(BaseController, AdminControllerMixin):
                   'you are allowed to create for this project/app', 'error')
         redirect(self.app.admin_url + 'webhooks')
 
-    @expose()
+    @expose('jinja:allura:templates/webhooks/create_form.html')  # needed when we "return self._default(...)"
     @require_post()
+    # @validate set dynamically in WebhookControllerMeta
     def edit(self, webhook, url, secret):
         old_url = webhook.hook_url
         old_secret = webhook.secret
-        self.update_webhook(webhook, url, secret)
+        try:
+            self.update_webhook(webhook, url, secret)
+        except Invalid as e:
+            # trigger error_handler directly
+            c.form_errors['_the_form'] = e
+            return self._default(webhook=webhook, url=url, secret=secret)
         M.AuditLog.log('edit webhook %s\n%s => %s\n%s',
                        webhook.type, old_url, url,
                        'secret changed' if old_secret != secret else '')
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index a4db828..ed23927 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -841,6 +841,16 @@ class TestFork(_TestCase):
         assert_in('commits-loading', r)
         self.app.get('/p/test/src-git/merge-requests/%s/commits_html' % mr_num, status=202)  # 202 used for "busy"
 
+    def test_merge_request_validation_error(self):
+        r = self.app.get('/p/test2/code/request_merge')
+        r = self._follow(r)
+        form = self._find_request_merge_form(r)
+        form['source_branch'].options.append(('bogus', False))
+        form['source_branch'].value = 'bogus'
+        r = form.submit()
+        r = self._follow(r)
+        r.mustcontain('Value must be one of:')
+
 
 class TestDiff(TestController):
     def setUp(self):