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 2015/11/03 20:30:56 UTC

[4/4] allura git commit: [#7919] unify _lookup for regular nbhd controller and rest controller

[#7919] unify _lookup for regular nbhd controller and rest controller

Enables /rest/p/admin/configure_tool_grouping to work for nbhd-level
project nav settings.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e1ca8deb
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e1ca8deb
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e1ca8deb

Branch: refs/heads/db/7919
Commit: e1ca8deb8423f54ffbeee4f8163a0f652ec6fc2d
Parents: 8324dd6
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Nov 3 14:24:05 2015 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Nov 3 14:30:35 2015 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/project.py        | 51 ++-------------
 Allura/allura/controllers/rest.py           | 83 +++++++++++++++++-------
 Allura/allura/ext/admin/admin_main.py       |  3 +-
 Allura/allura/tests/functional/test_rest.py | 15 +++++
 4 files changed, 81 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e1ca8deb/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 0d689a8..c05a165 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -19,7 +19,6 @@ import re
 import logging
 from datetime import datetime, timedelta
 from urllib import unquote
-from hashlib import sha1
 
 from bson import ObjectId
 from tg import expose, flash, redirect, validate, request, config, session
@@ -29,7 +28,6 @@ from paste.deploy.converters import asbool
 from webob import exc
 import jinja2
 import pymongo
-from formencode.api import Invalid
 
 from ming.utils import LazyProperty
 
@@ -42,7 +40,8 @@ from allura.lib import utils
 from allura.lib.decorators import require_post
 from allura.controllers.error import ErrorController
 from allura.controllers.feed import FeedArgs, FeedController
-from allura.lib.security import require_access, has_access
+from allura.controllers.rest import nbhd_lookup_first_path
+from allura.lib.security import require_access
 from allura.lib.security import RoleCache
 from allura.lib.widgets import forms as ff
 from allura.lib.widgets import form_fields as ffw
@@ -58,8 +57,7 @@ log = logging.getLogger(__name__)
 class W:
     resize_editor = ffw.AutoResizeTextarea()
     project_summary = plw.ProjectSummary()
-    add_project = plugin.ProjectRegistrationProvider.get().add_project_widget(
-        antispam=True)
+    add_project = plugin.ProjectRegistrationProvider.get().add_project_widget(antispam=True)
     page_list = ffw.PageList()
     page_size = ffw.PageSize()
     project_select = ffw.NeighborhoodProjectSelect
@@ -75,7 +73,6 @@ class NeighborhoodController(object):
     def __init__(self, neighborhood):
         self.neighborhood = neighborhood
         self.neighborhood_name = self.neighborhood.name
-        self.prefix = self.neighborhood.shortname_prefix
         self.browse = NeighborhoodProjectBrowseController(neighborhood=self.neighborhood)
         # 'admin' without underscore will pass through to _lookup which will find the regular "admin" tool mounted
         # on the --init-- Project record for this neighborhood.
@@ -92,47 +89,7 @@ class NeighborhoodController(object):
 
     @expose()
     def _lookup(self, pname, *remainder):
-        pname = unquote(pname)
-        provider = plugin.ProjectRegistrationProvider.get()
-        try:
-            provider.shortname_validator.to_python(
-                pname, check_allowed=False, neighborhood=self.neighborhood)
-        except Invalid:
-            project = None
-        else:
-            project = M.Project.query.get(
-                shortname=self.prefix + pname, neighborhood_id=self.neighborhood._id)
-        if project is None and self.prefix == 'u/':
-            # create user-project if it is missing
-            user = M.User.query.get(username=pname, disabled=False, pending=False)
-            if user:
-                project = user.private_project()
-                if project.shortname != self.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())
-        if project is None:
-            # look for neighborhood tools matching the URL
-            project = self.neighborhood.neighborhood_project
-            c.project = project
-            return ProjectController()._lookup(pname, *remainder)
-        if project and self.prefix == 'u/':
-            # make sure user-projects are associated with an enabled user
-            user = project.user_project_of
-            if not user or user.disabled or user.pending:
-                raise exc.HTTPNotFound
-        if project.database_configured == False:
-            if remainder == ('user_icon',):
-                redirect(g.forge_static('images/user.png'))
-            elif c.user.username == pname:
-                log.info('Configuring %s database for access to %r',
-                         pname, remainder)
-                project.configure_project(is_user_project=True)
-            else:
-                raise exc.HTTPNotFound, pname
-        c.project = project
-        if project is None or (project.deleted and not has_access(c.project, 'update')()):
-            raise exc.HTTPNotFound, pname
+        c.project, remainder = nbhd_lookup_first_path(self.neighborhood, pname, c.user, *remainder)
         return ProjectController(), remainder
 
     @expose('jinja:allura:templates/neighborhood_project_list.html')

http://git-wip-us.apache.org/repos/asf/allura/blob/e1ca8deb/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 7723c0d..e59087c 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -19,6 +19,7 @@
 
 """REST Controller"""
 import logging
+from urllib import unquote
 
 import oauth2 as oauth
 from paste.util.converters import asbool
@@ -36,6 +37,7 @@ from allura.lib import security
 from allura.lib import plugin
 from allura.lib.exceptions import Invalid
 from allura.lib.decorators import require_post
+from allura.lib.security import has_access
 
 log = logging.getLogger(__name__)
 action_logger = h.log_action(log, 'API:')
@@ -271,6 +273,61 @@ class AppRestControllerMixin(object):
         return rest_has_access(c.app, user, perm)
 
 
+def nbhd_lookup_first_path(nbhd, name, current_user, *remainder):
+    """
+    Resolve first part of a neighborhood url.  May raise 404, redirect, or do other side effects.
+
+    Shared between NeighborhoodController and NeighborhoodRestController
+
+    :param nbhd: neighborhood
+    :param name: project or tool name (next part of url)
+    :param current_user: a User
+    :param remainder: remainder of url
+
+    :return: project (to be set as c.project)
+    :return: remainder (possibly modified)
+    """
+
+    prefix = nbhd.shortname_prefix
+    pname = unquote(name)
+    provider = plugin.ProjectRegistrationProvider.get()
+    try:
+        provider.shortname_validator.to_python(pname, check_allowed=False, neighborhood=nbhd)
+    except Invalid:
+        project = None
+    else:
+        project = M.Project.query.get(shortname=prefix + pname, neighborhood_id=nbhd._id)
+    if project is None and prefix == 'u/':
+        # create user-project if it is missing
+        user = M.User.query.get(username=pname, disabled=False, pending=False)
+        if user:
+            project = user.private_project()
+            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())
+    if project is None:
+        # look for neighborhood tools matching the URL
+        project = nbhd.neighborhood_project
+        return project, (pname,) + remainder  # include pname in new remainder, it is actually the nbhd tool path
+    if project and prefix == 'u/':
+        # make sure user-projects are associated with an enabled user
+        user = project.user_project_of
+        if not user or user.disabled or user.pending:
+            raise exc.HTTPNotFound
+    if project.database_configured is False:
+        if remainder == ('user_icon',):
+            redirect(g.forge_static('images/user.png'))
+        elif current_user.username == pname:
+            log.info('Configuring %s database for access to %r', pname, remainder)
+            project.configure_project(is_user_project=True)
+        else:
+            raise exc.HTTPNotFound, pname
+    if project is None or (project.deleted and not has_access(project, 'update')()):
+        raise exc.HTTPNotFound, pname
+    return project, remainder
+
+
 class NeighborhoodRestController(object):
 
     def __init__(self, neighborhood):
@@ -282,29 +339,9 @@ class NeighborhoodRestController(object):
 
     @expose()
     def _lookup(self, name=None, *remainder):
-
-        # TODO: make this match NeighborhoodController._lookup so that /rest/p/admin/configure_tool_grouping works
-
-        provider = plugin.ProjectRegistrationProvider.get()
-        try:
-            provider.shortname_validator.to_python(
-                name, check_allowed=False, neighborhood=self._neighborhood)
-        except Invalid:
-            raise exc.HTTPNotFound, name
-        name = self._neighborhood.shortname_prefix + name
-        project = M.Project.query.get(
-            shortname=name, neighborhood_id=self._neighborhood._id, deleted=False)
-        log.info('nbhd rest proj=%s ... %s', project, name)
-        if not project:
-            raise exc.HTTPNotFound, name
-
-        if project and name and name.startswith('u/'):
-            # make sure user-projects are associated with an enabled user
-            user = project.user_project_of
-            if not user or user.disabled:
-                raise exc.HTTPNotFound
-
-        c.project = project
+        if not name:
+            raise exc.HTTPNotFound
+        c.project, remainder = nbhd_lookup_first_path(self._neighborhood, name, c.user, *remainder)
         return ProjectRestController(), remainder
 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e1ca8deb/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 99cf879..4d361bb 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -862,7 +862,7 @@ class ProjectAdminRestController(BaseController):
         }
 
     @expose('json:')
-    @require_post()
+    @require_post() # FIXME
     def mount_point(self, mount_point=None, **kw):
         """
         Returns a tool from a given mount point
@@ -879,6 +879,7 @@ class ProjectAdminRestController(BaseController):
 
         try:
             info = json.dumps(tool)
+            # FIXME
         except TypeError:
             info = "Could not serialize tool."
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e1ca8deb/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 1a2006d..90b71ed 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -248,6 +248,21 @@ class TestRestHome(TestRestApiBase):
         assert_equal(r.status_int, 200)
         assert_equal(r.json['result'], False)
 
+    def test_neighborhood(self):
+        self.api_get('/rest/p/', status=404)
+
+    def test_neighborhood_tools(self):
+        r = self.api_get('/rest/p/wiki/Home/')
+        assert_equal(r.status_int, 200)
+        assert_equal(r.json['title'], 'Home')
+
+        r = self.api_get('/rest/p/admin/installable_tools')
+        assert_equal(r.status_int, 403)
+
+        r = self.api_get('/rest/p/admin/installable_tools', user='root')
+        assert_equal(r.status_int, 200)
+        assert [t for t in r.json['tools'] if t['tool_label'] == 'Wiki'], r.json
+
     def test_project_has_access_no_params(self):
         self.api_get('/rest/p/test/has_access', status=404)
         self.api_get('/rest/p/test/has_access?user=root', status=404)