Return-Path: X-Original-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 01B3FD3EB for ; Wed, 28 Nov 2012 21:43:17 +0000 (UTC) Received: (qmail 46872 invoked by uid 500); 28 Nov 2012 21:43:16 -0000 Delivered-To: apmail-incubator-allura-commits-archive@incubator.apache.org Received: (qmail 46857 invoked by uid 500); 28 Nov 2012 21:43:16 -0000 Mailing-List: contact allura-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: allura-dev@incubator.apache.org Delivered-To: mailing list allura-commits@incubator.apache.org Received: (qmail 46849 invoked by uid 99); 28 Nov 2012 21:43:16 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Nov 2012 21:43:16 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id A95E6813081; Wed, 28 Nov 2012 21:43:16 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: brondsem@apache.org To: allura-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: git commit: [#5360] within project registration, separate validation from creation for easier ProjectRegistrationProvider plugin implementation Message-Id: <20121128214316.A95E6813081@tyr.zones.apache.org> Date: Wed, 28 Nov 2012 21:43:16 +0000 (UTC) Updated Branches: refs/heads/db/5360 [created] 7bed3029a [#5360] within project registration, separate validation from creation for easier ProjectRegistrationProvider plugin implementation Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7bed3029 Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7bed3029 Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7bed3029 Branch: refs/heads/db/5360 Commit: 7bed3029adb36af666f34250f98bd6cc0c278fcb Parents: cde6443 Author: Dave Brondsema Authored: Wed Nov 28 21:43:03 2012 +0000 Committer: Dave Brondsema Committed: Wed Nov 28 21:43:03 2012 +0000 ---------------------------------------------------------------------- Allura/allura/lib/plugin.py | 196 ++++++++++++++++++++------------------ 1 files changed, 102 insertions(+), 94 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7bed3029/Allura/allura/lib/plugin.py ---------------------------------------------------------------------- diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py index ed32e01..495fdfe 100644 --- a/Allura/allura/lib/plugin.py +++ b/Allura/allura/lib/plugin.py @@ -11,7 +11,7 @@ from cStringIO import StringIO from random import randint from hashlib import sha256 from base64 import b64encode -from datetime import datetime, timedelta +from datetime import datetime import json try: @@ -20,7 +20,7 @@ try: except ImportError: ldap = modlist = None import pkg_resources -from tg import config, flash +from tg import config from pylons import g, c from webob import exc from bson.tz_util import FixedOffset @@ -30,7 +30,6 @@ from ming.orm import state from ming.orm import ThreadLocalORMSession from allura.lib import helpers as h -from allura.lib import utils from allura.lib import security from allura.lib import exceptions as forge_exc @@ -396,6 +395,13 @@ class ProjectRegistrationProvider(object): '''Register a new project in the neighborhood. The given user will become the project's superuser. ''' + self.validate_project(neighborhood, shortname, project_name, user, user_project, private_project) + return self._create_project(neighborhood, shortname, project_name, user, user_project, private_project, apps) + + def validate_project(self, neighborhood, shortname, project_name, user, user_project, private_project): + ''' + Validate that a project can be registered, before it is + ''' from allura import model as M # Check for private project rights @@ -418,97 +424,99 @@ class ProjectRegistrationProvider(object): if not h.re_path_portion.match(shortname.replace('/', '')): raise ValueError('Invalid project shortname: %s' % shortname) - try: - p = M.Project.query.get(shortname=shortname, neighborhood_id=neighborhood._id) - if p: - raise forge_exc.ProjectConflict() - project_template = neighborhood.get_project_template() - p = M.Project(neighborhood_id=neighborhood._id, - shortname=shortname, - name=project_name, - short_description='', - description=('You can edit this description in the admin page'), - homepage_title=shortname, - database_uri=M.Project.default_database_uri(shortname), - last_updated = datetime.utcnow(), - is_nbhd_project=False, - is_root=True) - p.configure_project( - users=[user], - is_user_project=user_project, - is_private_project=private_project or project_template.get('private', False), - apps=apps or [] if 'tools' in project_template else None) - - # Setup defaults from neighborhood project template if applicable - offset = p.next_mount_point(include_hidden=True) - if 'groups' in project_template: - for obj in project_template['groups']: - name = obj.get('name') - permissions = set(obj.get('permissions', [])) & \ - set(p.permissions) - usernames = obj.get('usernames', []) - # Must provide a group name - if not name: continue - # If the group already exists, we'll add users to it, - # but we won't change permissions on the group - group = M.ProjectRole.by_name(name, project=p) - if not group: - # If creating a new group, *must* specify permissions - if not permissions: continue - group = M.ProjectRole(project_id=p._id, name=name) - p.acl += [M.ACE.allow(group._id, perm) - for perm in permissions] - for username in usernames: - guser = M.User.by_username(username) - if not (guser and guser._id): continue - pr = guser.project_role(project=p) - if group._id not in pr.roles: - pr.roles.append(group._id) - if 'tools' in project_template: - for i, tool in enumerate(project_template['tools'].keys()): - tool_config = project_template['tools'][tool] - tool_options = tool_config.get('options', {}) - for k, v in tool_options.iteritems(): - if isinstance(v, basestring): - tool_options[k] = \ - string.Template(v).safe_substitute( - p.__dict__.get('root_project', {})) - app = p.install_app(tool, - mount_label=tool_config['label'], - mount_point=tool_config['mount_point'], - ordinal=i + offset, - **tool_options) - if tool == 'wiki': - from forgewiki import model as WM - text = tool_config.get('home_text', - '[[project_admins]]\n[[download_button]]') - WM.Page.query.get(app_config_id=app.config._id).text = text - - if 'tool_order' in project_template: - for i, tool in enumerate(project_template['tool_order']): - p.app_config(tool).options.ordinal = i - if 'labels' in project_template: - p.labels = project_template['labels'] - if 'trove_cats' in project_template: - for trove_type in project_template['trove_cats'].keys(): - troves = getattr(p, 'trove_%s' % trove_type) - for trove_id in project_template['trove_cats'][trove_type]: - troves.append(M.TroveCategory.query.get(trove_cat_id=trove_id)._id) - if 'icon' in project_template: - icon_file = StringIO(urlopen(project_template['icon']['url']).read()) - M.ProjectFile.save_image( - project_template['icon']['filename'], icon_file, - square=True, thumbnail_size=(48, 48), - thumbnail_meta=dict(project_id=p._id, category='icon')) - # clear the RoleCache for the user so this project will - # be picked up by user.my_projects() - g.credentials.clear_user(user._id) - except forge_exc.ProjectConflict: - raise - except: - ThreadLocalORMSession.close_all() - log.exception('Error registering project %s' % p) - raise + + p = M.Project.query.get(shortname=shortname, neighborhood_id=neighborhood._id) + if p: + raise forge_exc.ProjectConflict() + + def _create_project(self, neighborhood, shortname, project_name, user, user_project, private_project, apps): + ''' + Actually create the project, no validation. This should not be called directly + under normal circumstances. + ''' + from allura import model as M + + project_template = neighborhood.get_project_template() + p = M.Project(neighborhood_id=neighborhood._id, + shortname=shortname, + name=project_name, + short_description='', + description=('You can edit this description in the admin page'), + homepage_title=shortname, + database_uri=M.Project.default_database_uri(shortname), + last_updated = datetime.utcnow(), + is_nbhd_project=False, + is_root=True) + p.configure_project( + users=[user], + is_user_project=user_project, + is_private_project=private_project or project_template.get('private', False), + apps=apps or [] if 'tools' in project_template else None) + + # Setup defaults from neighborhood project template if applicable + offset = p.next_mount_point(include_hidden=True) + if 'groups' in project_template: + for obj in project_template['groups']: + name = obj.get('name') + permissions = set(obj.get('permissions', [])) & \ + set(p.permissions) + usernames = obj.get('usernames', []) + # Must provide a group name + if not name: continue + # If the group already exists, we'll add users to it, + # but we won't change permissions on the group + group = M.ProjectRole.by_name(name, project=p) + if not group: + # If creating a new group, *must* specify permissions + if not permissions: continue + group = M.ProjectRole(project_id=p._id, name=name) + p.acl += [M.ACE.allow(group._id, perm) + for perm in permissions] + for username in usernames: + guser = M.User.by_username(username) + if not (guser and guser._id): continue + pr = guser.project_role(project=p) + if group._id not in pr.roles: + pr.roles.append(group._id) + if 'tools' in project_template: + for i, tool in enumerate(project_template['tools'].keys()): + tool_config = project_template['tools'][tool] + tool_options = tool_config.get('options', {}) + for k, v in tool_options.iteritems(): + if isinstance(v, basestring): + tool_options[k] = \ + string.Template(v).safe_substitute( + p.__dict__.get('root_project', {})) + app = p.install_app(tool, + mount_label=tool_config['label'], + mount_point=tool_config['mount_point'], + ordinal=i + offset, + **tool_options) + if tool == 'wiki': + from forgewiki import model as WM + text = tool_config.get('home_text', + '[[project_admins]]\n[[download_button]]') + WM.Page.query.get(app_config_id=app.config._id).text = text + + if 'tool_order' in project_template: + for i, tool in enumerate(project_template['tool_order']): + p.app_config(tool).options.ordinal = i + if 'labels' in project_template: + p.labels = project_template['labels'] + if 'trove_cats' in project_template: + for trove_type in project_template['trove_cats'].keys(): + troves = getattr(p, 'trove_%s' % trove_type) + for trove_id in project_template['trove_cats'][trove_type]: + troves.append(M.TroveCategory.query.get(trove_cat_id=trove_id)._id) + if 'icon' in project_template: + icon_file = StringIO(urlopen(project_template['icon']['url']).read()) + M.ProjectFile.save_image( + project_template['icon']['filename'], icon_file, + square=True, thumbnail_size=(48, 48), + thumbnail_meta=dict(project_id=p._id, category='icon')) + # clear the RoleCache for the user so this project will + # be picked up by user.my_projects() + g.credentials.clear_user(user._id) with h.push_config(c, project=p, user=user): ThreadLocalORMSession.flush_all() # have to add user to context, since this may occur inside auth code