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 2013/05/03 23:57:40 UTC
[10/50] git commit: [#5332] Relax mount point name rules for repos
[#5332] Relax mount point name rules for repos
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ba32ac79
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ba32ac79
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ba32ac79
Branch: refs/heads/db/6007
Commit: ba32ac79881cb1ba74cea0ea279a426c5e416801
Parents: f2c3475
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Thu Apr 25 18:34:31 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 14:44:04 2013 +0000
----------------------------------------------------------------------
Allura/allura/app.py | 30 +++++++++++++--
Allura/allura/controllers/project.py | 4 +-
Allura/allura/controllers/rest.py | 2 -
.../allura/ext/admin/templates/project_tools.html | 23 +++++++++--
Allura/allura/lib/helpers.py | 3 +-
Allura/allura/lib/repository.py | 1 +
Allura/allura/model/project.py | 2 +-
Allura/allura/public/nf/js/project_tools.js | 12 +++++-
Allura/allura/tests/unit/test_app.py | 13 ++++++
9 files changed, 74 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index bf874bf..124f084 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -28,7 +28,7 @@ from bson import ObjectId
from ming.orm import session, state
from ming.utils import LazyProperty
-from allura.lib.helpers import push_config, vardec
+from allura.lib import helpers as h
from allura.lib.security import require, has_access, require_access
from allura import model
from allura.controllers import BaseController
@@ -144,6 +144,10 @@ class Application(object):
:cvar bool hidden: Default is False, Application is not hidden from the
list of a project's installed tools.
:cvar str tool_description: Text description of this Application.
+ :cvar bool relaxed_mount_points: Set to True to relax the default mount point
+ naming restrictions for this Application. Default is False. See
+ :attr:`default mount point naming rules <allura.lib.helpers.re_tool_mount_point>` and
+ :attr:`relaxed mount point naming rules <allura.lib.helpers.re_relaxed_tool_mount_point>`.
:cvar Controller root: Serves content at
/<neighborhood>/<project>/<app>/. Default is None - subclasses should
override.
@@ -154,7 +158,6 @@ class Application(object):
/<neighborhood>/<project>/<admin>/<app>/. Default is a
:class:`DefaultAdminController` instance.
:cvar dict icons: Mapping of icon sizes to application-specific icon paths.
-
"""
__version__ = None
@@ -178,6 +181,7 @@ class Application(object):
tool_description="This is a tool for Allura forge."
default_mount_label='Tool Name'
default_mount_point='tool'
+ relaxed_mount_points=False
ordinal=0
hidden = False
icons={
@@ -203,6 +207,24 @@ class Application(object):
return self.config.parent_security_context()
@classmethod
+ def validate_mount_point(cls, mount_point):
+ """Check if ``mount_point`` is valid for this Application.
+
+ In general, subclasses should not override this, but rather toggle
+ the strictness of allowed mount point names by toggling
+ :attr:`Application.relaxed_mount_points`.
+
+ :param mount_point: the mount point to validate
+ :type mount_point: str
+ :rtype: A :class:`regex Match object <_sre.SRE_Match>` if the mount
+ point is valid, else None
+
+ """
+ re = (h.re_relaxed_tool_mount_point if cls.relaxed_mount_points
+ else h.re_tool_mount_point)
+ return re.match(mount_point)
+
+ @classmethod
def status_int(self):
return self.status_map.index(self.status)
@@ -450,7 +472,7 @@ class DefaultAdminController(BaseController):
@expose()
@require_post()
def configure(self, **kw):
- with push_config(c, app=self.app):
+ with h.push_config(c, app=self.app):
require_access(self.app, 'configure')
is_admin = self.app.config.tool_name == 'admin'
if kw.pop('delete', False):
@@ -481,7 +503,7 @@ class DefaultAdminController(BaseController):
@without_trailing_slash
@expose()
- @vardec
+ @h.vardec
@require_post()
def update(self, card=None, **kw):
self.app.config.acl = []
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 2f59a38..75e7792 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -317,8 +317,6 @@ class ProjectController(object):
@expose()
def _lookup(self, name, *remainder):
name = unquote(name)
- if not h.re_path_portion.match(name):
- raise exc.HTTPNotFound, name
subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
neighborhood_id=c.project.neighborhood_id)
if subproject:
@@ -592,7 +590,7 @@ class NeighborhoodAdminController(object):
for tool in validate_tools.keys():
- if not h.re_tool_mount_point.match(tool):
+ if tool not in g.entry_points['tool']:
flash('Anchored tools "%s" is invalid' % anchored_tools,'error')
result = False
if result:
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index cf03733..8ae0c70 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -257,8 +257,6 @@ class ProjectRestController(object):
def _lookup(self, name, *remainder):
if not name:
return self, ()
- if not h.re_path_portion.match(name):
- raise exc.HTTPNotFound, name
subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
neighborhood_id=c.project.neighborhood_id,
deleted=False)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/ext/admin/templates/project_tools.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_tools.html b/Allura/allura/ext/admin/templates/project_tools.html
index 6516039..dc7646c 100644
--- a/Allura/allura/ext/admin/templates/project_tools.html
+++ b/Allura/allura/ext/admin/templates/project_tools.html
@@ -30,7 +30,7 @@
<div class="nested-grid-container">
{% for tool in installable_tools %}
<span class="tcenter grid-4 installable_tool">
- <a class="install_trig" data-tool="{{ tool['name'] }}">
+ <a class="install_trig" data-tool="{{ tool['name'] }}" data-relaxed-mount-points="{{ tool.app.relaxed_mount_points and 'true' or 'false' }}">
<span class="tool_title">{{ tool['app'].tool_label }}{{' (%s)' % tool.app.status if tool.app.status != 'production' else ''}}</span><br />
<img src="{{ g.theme.app_icon_url(tool['app'], 32) or 'unk.png' }}" alt="">
</a>
@@ -50,9 +50,24 @@
<div class="grid-13"><input type="text" name="new.mount_label" class="new_mount_label"></div>
<label class="grid-13">Mount Point</label>
<div class="grid-13"><input type="text" name="new.mount_point" class="new_mount_point"></div>
- <div class="grid-13"><small>* The mount point is the name of the tool as it will appear in a URL.
- A valid mount point must begin with a letter, contain only letters, numbers, and dashes,
- and be from 1-63 characters in length.</small></div>
+ <div class="grid-13">
+ <small>
+ * The mount point is the name of the tool as it will appear in a URL.
+ <span class="mount-point-name-rules tool">
+ A valid mount point for this tool must begin with a letter, contain only letters,
+ numbers, and dashes, and be from 1-63 characters in length.
+ </span>
+ <span class="mount-point-name-rules tool-relaxed">
+ A valid mount point for this tool must begin with a letter or number, contain only
+ letters, numbers, dashes, underscores, periods, and plus signs, and be
+ from 1-63 characters in length.
+ </span>
+ <span class="mount-point-name-rules subproject">
+ A valid subproject mount point must begin with a letter, contain only letters,
+ numbers, and dashes, and be from 3-63 characters in length.
+ </span>
+ </small>
+ </div>
<hr>
<div class="grid-13"> </div>
<div class="grid-13">
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index ea2b4d2..b118efe 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -53,8 +53,9 @@ from allura.lib import AsciiDammit
from .security import has_access
re_path_portion_fragment = re.compile(r'[a-z][-a-z0-9]*')
-re_path_portion = re.compile(r'^[a-z][-a-z0-9]{2,}$')
+re_path_portion = re.compile(r'^[a-z][-a-z0-9]{2,62}$')
re_tool_mount_point = re.compile(r'^[a-z][-a-z0-9]{0,62}$')
+re_relaxed_tool_mount_point = re.compile(r'^[a-z0-9][-a-z0-9_\.\+]{0,62}$')
re_clean_vardec_key = re.compile(r'''\A
( # first part
\w+# name...
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 69736b6..3a432ec 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -53,6 +53,7 @@ class RepositoryApp(Application):
tool_label='Repository'
default_mount_label='Code'
default_mount_point='code'
+ relaxed_mount_points=True
ordinal=2
forkable=False
default_branch_name=None # master or default or some such
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index d207aab..b3f1131 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -547,7 +547,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
for x in range(10):
if self.app_instance(mount_point) is None: break
mount_point = base_mount_point + '-%d' % x
- if not h.re_tool_mount_point.match(mount_point):
+ if not App.validate_mount_point(mount_point):
raise exceptions.ToolError, 'Mount point "%s" is invalid' % mount_point
# HACK: reserved url components
if mount_point in ('feed', 'index', 'icon', '_nav.json'):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/public/nf/js/project_tools.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/project_tools.js b/Allura/allura/public/nf/js/project_tools.js
index 3a5b5d7..b148ba4 100644
--- a/Allura/allura/public/nf/js/project_tools.js
+++ b/Allura/allura/public/nf/js/project_tools.js
@@ -28,20 +28,30 @@
var new_mount_point = install_form.find('input.new_mount_point');
var new_mount_label = install_form.find('input.new_mount_label');
var install_tool_label = $('#install_tool_label');
+ var mount_point_rule_names = $('#install_form .mount-point-rule-names');
install_popup.append(install_form.show());
$('a.install_trig').click(function () {
- var datatool = $(this).attr('data-tool');
+ var datatool = $(this).data('tool');
+ var relaxed_mount_points = $(this).data('relaxed-mount-points');
+ install_form.find('.mount-point-name-rules').hide();
if (datatool) {
var tool = defaults[datatool];
install_tool_label.html(tool.default_label);
new_ep_name.val(datatool);
new_mount_point.val(tool.default_mount);
new_mount_label.val(tool.default_label);
+ if (relaxed_mount_points) {
+ install_form.find('.mount-point-name-rules.tool-relaxed').show();
+ }
+ else {
+ install_form.find('.mount-point-name-rules.tool').show();
+ }
} else {
install_tool_label.html("Subproject");
new_ep_name.val('');
new_mount_point.val('');
new_mount_label.val('');
+ install_form.find('.mount-point-name-rules.subproject').show();
}
});
// Edit popup
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/tests/unit/test_app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py
index 668ac65..8f0c0db 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -15,6 +15,9 @@
# specific language governing permissions and limitations
# under the License.
+import re
+from unittest import TestCase
+
from allura.app import Application
from allura import model
from allura.tests.unit import WithDatabase
@@ -22,6 +25,16 @@ from allura.tests.unit.patches import fake_app_patch
from allura.tests.unit.factories import create_project, create_app_config
+class TestApplication(TestCase):
+
+ def test_validate_mount_point(self):
+ app = Application
+ mount_point = '1.2+foo_bar'
+ self.assertIsNone(app.validate_mount_point(mount_point))
+ app.relaxed_mount_points = True
+ self.assertIsNotNone(app.validate_mount_point(mount_point))
+
+
class TestInstall(WithDatabase):
patches = [fake_app_patch]