[#8041] more accurate project & mount point regex matching DNS host rules
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 4bf92ae..c66b3f5 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -68,9 +68,14 @@
 
 log = logging.getLogger(__name__)
 
+# http://stackoverflow.com/questions/2063213/regular-expression-for-validating-dns-label-host-name
+# modified to remove capital A-Z and make length parameterized
+dns_var_length = r'^(?![0-9]+$)(?!-)[a-z0-9-]{%s}(?<!-)$'
+
+# project & tool names must comply to DNS since used in subdomains for emailing
 re_mount_points = {
-    're_project_name': r'^[a-z][-a-z0-9]{2,14}$',  # validates project, subproject, and user names
-    're_tool_mount_point': r'^[a-z][-a-z0-9]{0,62}$',  # validates tool mount point names
+    're_project_name': dns_var_length % '3,15',  # validates project, subproject, and user names
+    're_tool_mount_point': dns_var_length % '1,63',  # validates tool mount point names
     're_tool_mount_point_fragment': r'[a-z][-a-z0-9]*',
     're_relaxed_tool_mount_point': r'^[a-zA-Z0-9][-a-zA-Z0-9_\.\+]{0,62}$',
     're_relaxed_tool_mount_point_fragment':  r'[a-zA-Z0-9][-a-zA-Z0-9_\.\+]*'
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index d379d97..0441f18 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -86,6 +86,8 @@
                       'this-is-valid-but-too-long', neighborhood=nbhd)
         assert_raises(ProjectShortnameInvalid, v,
                       'this is invalid and too long', neighborhood=nbhd)
+        assert_raises(ProjectShortnameInvalid, v,
+                      'end-dash-', neighborhood=nbhd)
         Project.query.get.return_value = Mock()
         assert_raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd)
 
diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py
index eca1ae7..667dc09 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -30,8 +30,14 @@
 
     def test_validate_mount_point(self):
         app = Application
+
+        self.assertIsNotNone(app.validate_mount_point('dash-in-middle'))
+
+        self.assertIsNone(app.validate_mount_point('end-dash-'))
+
         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))