When /u/someuser/ needs to redirect, make sure it preserves /rest/ and any trailing URL parts
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 96bfd0d..1742372 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -89,7 +89,7 @@
@expose()
def _lookup(self, pname, *remainder):
- c.project, remainder = nbhd_lookup_first_path(self.neighborhood, pname, c.user, *remainder)
+ c.project, remainder = nbhd_lookup_first_path(self.neighborhood, pname, c.user, remainder)
return ProjectController(), remainder
@expose('jinja:allura:templates/neighborhood_project_list.html')
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index e59087c..a8a98fd 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -273,7 +273,7 @@
return rest_has_access(c.app, user, perm)
-def nbhd_lookup_first_path(nbhd, name, current_user, *remainder):
+def nbhd_lookup_first_path(nbhd, name, current_user, remainder, api=False):
"""
Resolve first part of a neighborhood url. May raise 404, redirect, or do other side effects.
@@ -283,6 +283,7 @@
:param name: project or tool name (next part of url)
:param current_user: a User
:param remainder: remainder of url
+ :param bool api: whether this is handling a /rest/ request or not
:return: project (to be set as c.project)
:return: remainder (possibly modified)
@@ -305,7 +306,13 @@
if project.shortname != prefix + pname:
# might be different URL than the URL requested
# e.g. if username isn't valid project name and user_project_shortname() converts the name
- redirect(project.url())
+ new_url = project.url()
+ if api:
+ new_url = '/rest' + new_url
+ new_url += '/'.join(remainder)
+ if request.query_string:
+ new_url += '?' + request.query_string
+ redirect(new_url)
if project is None:
# look for neighborhood tools matching the URL
project = nbhd.neighborhood_project
@@ -341,7 +348,7 @@
def _lookup(self, name=None, *remainder):
if not name:
raise exc.HTTPNotFound
- c.project, remainder = nbhd_lookup_first_path(self._neighborhood, name, c.user, *remainder)
+ c.project, remainder = nbhd_lookup_first_path(self._neighborhood, name, c.user, remainder, api=True)
return ProjectRestController(), remainder
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 14c28bf..d3c502d 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -57,8 +57,10 @@
User.upsert('foo_bar')
# default auth provider's user_project_shortname() converts _ to - for the project name
- response = self.app.get('/u/foo_bar/profile/', status=302)
+ response = self.app.get('/u/foo_bar/', status=302)
assert_equal(response.location, 'http://localhost/u/foo-bar/')
+ response = self.app.get('/u/foo_bar/profile/xyz?a=b', status=302)
+ assert_equal(response.location, 'http://localhost/u/foo-bar/profile/xyz?a=b')
# unfortunately this doesn't work because the default auth provider's user_by_project_shortname()
# doesn't try converting back (and it probably shouldn't since you could get multiple users with conflicting proj names)
@@ -66,6 +68,13 @@
# user_project_shortname() and user_by_project_shortname()
#self.app.get('/u/foo-bar/profile/')
+ def test_differing_profile_proj_shortname_rest_api(self):
+ User.upsert('foo_bar')
+
+ # default auth provider's user_project_shortname() converts _ to - for the project name
+ response = self.app.get('/rest/u/foo_bar/', status=302)
+ assert_equal(response.location, 'http://localhost/rest/u/foo-bar/')
+
@td.with_user_project('test-admin')
@td.with_wiki
def test_feed(self):