def approve(self, file_info=None): from allura.model.notification import Notification if self.status == 'ok': return self.status = 'ok' if self.parent_id is None: thd = self.thread_class().query.get(_id=self.thread_id) g.post_event('discussion.new_thread', thd._id) author = self.author() security.simple_grant(self.acl, author.project_role()._id, 'moderate') self.commit() if (c.app.config.options.get('PostingPolicy') == 'ApproveOnceModerated' and author._id != None): security.simple_grant(self.acl, author.project_role()._id, 'unmoderated_post') g.post_event('discussion.new_post', self.thread_id, self._id) artifact = self.thread.artifact or self.thread n = Notification.post(artifact, 'message', post=self, file_info=file_info) if hasattr(self.discussion, "monitoring_email") and self.discussion.monitoring_email: n.send_simple(self.discussion.monitoring_email) session(self).flush() self.thread.last_post_date = max(self.thread.last_post_date, self.mod_date) self.thread.update_stats() self.discussion.update_stats()
def update(self, card=None, **kw): permissions = self._index_permissions() old_permissions = dict(permissions) for args in card: perm = args['id'] new_group_ids = args.get('new', []) group_ids = args.get('value', []) if isinstance(new_group_ids, basestring): new_group_ids = [ new_group_ids ] if isinstance(group_ids, basestring): group_ids = [ group_ids ] # make sure the admin group has the admin permission if perm == 'admin': if c.project.is_root: pid = c.project._id else: pid = c.project.parent_id admin_group_id = str(M.ProjectRole.query.get(project_id=pid, name='Admin')._id) if admin_group_id not in group_ids + new_group_ids: flash('You cannot remove the admin group from the admin permission.','warning') group_ids.append(admin_group_id) permissions[perm] = [] role_ids = map(ObjectId, group_ids + new_group_ids) permissions[perm] = role_ids c.project.acl = [] for perm, role_ids in permissions.iteritems(): role_names = lambda ids: ','.join(sorted( pr.name for pr in M.ProjectRole.query.find(dict(_id={'$in':ids})))) old_role_ids = old_permissions.get(perm, []) if old_role_ids != role_ids: M.AuditLog.log('updated "%s" permissions: "%s" => "%s"', perm,role_names(old_role_ids), role_names(role_ids)) c.project.acl += [M.ACE.allow(rid, perm) for rid in role_ids] g.post_event('project_updated') redirect('.')
def delete_screenshot(self, id=None, **kw): require_access(c.project, 'update') if id is not None and id != '': M.AuditLog.log('remove screenshot') M.ProjectFile.query.remove(dict(project_id=c.project._id, _id=ObjectId(id))) g.post_event('project_updated') redirect('screenshots')
def update(self, card=None, **kw): for pr in card: group = M.ProjectRole.query.get(_id=ObjectId(pr["id"])) assert group.project == c.project, "Security violation" user_ids = pr.get("value", []) new_users = pr.get("new", []) if isinstance(user_ids, basestring): user_ids = [user_ids] if isinstance(new_users, basestring): new_users = [new_users] # Handle new users in groups user_added = False for username in new_users: user = M.User.by_username(username.strip()) if not user: flash("User %s not found" % username, "error") redirect(".") if not user._id: continue # never add anon users to groups M.AuditLog.log("add user %s to %s", username, group.name) user.project_role().roles.append(group._id) user_added = True # Make sure we aren't removing all users from the Admin group if group.name == u"Admin" and not (user_ids or user_added): flash("You must have at least one user with the Admin role.", "warning") redirect(".") # Handle users removed from groups user_ids = set(uid and ObjectId(uid) for uid in user_ids) for role in M.ProjectRole.query.find(dict(user_id={"$ne": None}, roles=group._id)): if role.user_id and role.user_id not in user_ids: role.roles = [rid for rid in role.roles if rid != group._id] M.AuditLog.log("remove user %s from %s", role.user.username, group.name) g.post_event("project_updated") redirect(".")
def delete_screenshot(self, id=None, **kw): require_access(c.project, "update") if id is not None and id != "": M.AuditLog.log("remove screenshot") M.ProjectFile.query.remove(dict(project_id=c.project._id, _id=ObjectId(id))) g.post_event("project_updated") redirect("screenshots")
def edit_screenshot(self, id=None, caption=None, **kw): require_access(c.project, 'update') if id is not None and id != '': M.ProjectFile.query.get(project_id=c.project._id, _id=ObjectId(id)).caption = caption g.post_event('project_updated') redirect('screenshots')
def create(self, name=None, **kw): if M.ProjectRole.by_name(name): flash('%s already exists' % name, 'error') else: M.ProjectRole(project_id=c.project._id, name=name) M.AuditLog.log('create group %s', name) g.post_event('project_updated') redirect('.')
def create(self, name=None, **kw): if M.ProjectRole.by_name(name): flash("%s already exists" % name, "error") else: M.ProjectRole(project_id=c.project._id, name=name) M.AuditLog.log("create group %s", name) g.post_event("project_updated") redirect(".")
def delete_trove(self, type, trove, **kw): require_access(c.project, 'update') trove_obj = M.TroveCategory.query.get(trove_cat_id=int(trove)) current_troves = getattr(c.project, 'trove_%s' % type) if trove_obj is not None and trove_obj._id in current_troves: M.AuditLog.log('remove trove %s: %s', type, trove_obj.fullpath) current_troves.remove(trove_obj._id) g.post_event('project_updated') redirect('trove')
def delete_trove(self, type, trove, **kw): require_access(c.project, 'update') trove_obj = M.TroveCategory.query.get(trove_cat_id=int(trove)) current_troves = getattr(c.project,'trove_%s'%type) if trove_obj is not None and trove_obj._id in current_troves: M.AuditLog.log('remove trove %s: %s', type, trove_obj.fullpath) current_troves.remove(trove_obj._id) g.post_event('project_updated') redirect('trove')
def delete_group(self, group_name, **kw): role = M.ProjectRole.by_name(group_name) if not role: flash('Group "%s" does not exist.' % group_name, 'error') else: role.delete() M.AuditLog.log('delete group %s', group_name) flash('Group "%s" deleted successfully.' % group_name) g.post_event('project_updated') redirect('.')
def delete(self): require_access(self.neighborhood, 'admin') if self.award: grants = M.AwardGrant.query.find(dict(award_id=self.award._id)) for grant in grants: grant.delete() with h.push_context(grant.granted_to_project_id): g.post_event('project_updated') M.AwardFile.query.remove(dict(award_id=self.award._id)) self.award.delete() redirect(request.referer)
def change_perm(self, role_id, permission, allow="true", **kw): if allow=="true": M.AuditLog.log('granted permission %s to group with id %s', permission, role_id) c.project.acl.append(M.ACE.allow(ObjectId(role_id), permission)) else: admin_group_id = str(M.ProjectRole.by_name('Admin')._id) if admin_group_id == role_id and permission == 'admin': return dict(error='You cannot remove the admin permission from the admin group.') M.AuditLog.log('revoked permission %s from group with id %s', permission, role_id) c.project.acl.remove(M.ACE.allow(ObjectId(role_id), permission)) g.post_event('project_updated') return self._map_group_permissions()
def add_screenshot(self, screenshot=None, caption=None, **kw): require_access(c.project, 'update') if len(c.project.get_screenshots()) >= 6: flash('You may not have more than 6 screenshots per project.','error') elif screenshot is not None and screenshot != '': M.AuditLog.log('add screenshot') M.ProjectFile.save_image( screenshot.filename, screenshot.file, content_type=screenshot.type, save_original=True, original_meta=dict(project_id=c.project._id,category='screenshot',caption=caption), square=True, thumbnail_size=(150,150), thumbnail_meta=dict(project_id=c.project._id,category='screenshot_thumb')) g.post_event('project_updated') redirect('screenshots')
def remove_user(self, role_id, username, **kw): group = M.ProjectRole.query.get(_id=ObjectId(role_id)) user = M.User.by_username(username.strip()) if group.name == 'Admin' and len(group.users_with_role()) == 1: return dict(error='You must have at least one user with the Admin role.') if not group: return dict(error='Could not find group with id %s' % role_id) if not user: return dict(error='User %s not found' % username) if group._id not in user.project_role().roles: return dict(error='%s (%s) is not in the group %s.' % (user.display_name, username, group.name)) M.AuditLog.log('remove user %s from %s', username, group.name) user.project_role().roles.remove(group._id) g.post_event('project_updated') return dict()
def _add_trove(self, type, new_trove): current_troves = getattr(c.project,'trove_%s'%type) trove_obj = M.TroveCategory.query.get(trove_cat_id=int(new_trove)) error_msg = None if type in ['license','audience','developmentstatus','language'] and len(current_troves) >= 6: error_msg = 'You may not have more than 6 of this category.' elif type in ['topic'] and len(current_troves) >= 3: error_msg = 'You may not have more than 3 of this category.' elif trove_obj is not None: if trove_obj._id not in current_troves: current_troves.append(trove_obj._id) g.post_event('project_updated') else: error_msg = 'This category has already been assigned to the project.' return (trove_obj, error_msg)
def add_user(self, role_id, username, **kw): if not username or username=='*anonymous': return dict(error='You must choose a user to add.') group = M.ProjectRole.query.get(_id=ObjectId(role_id)) user = M.User.by_username(username.strip()) if not group: return dict(error='Could not find group with id %s' % role_id) if not user: return dict(error='User %s not found' % username) if group._id in user.project_role().roles: return dict(error='%s (%s) is already in the group %s.' % (user.display_name, username, group.name)) M.AuditLog.log('add user %s to %s', username, group.name) user.project_role().roles.append(group._id) g.post_event('project_updated') return dict(username=username, displayname=user.display_name)
def _add_trove(self, type, new_trove): current_troves = getattr(c.project, "trove_%s" % type) trove_obj = M.TroveCategory.query.get(trove_cat_id=int(new_trove)) error_msg = None if type in ["license", "audience", "developmentstatus", "language"] and len(current_troves) >= 6: error_msg = "You may not have more than 6 of this category." elif type in ["topic"] and len(current_troves) >= 3: error_msg = "You may not have more than 3 of this category." elif trove_obj is not None: if trove_obj._id not in current_troves: current_troves.append(trove_obj._id) g.post_event("project_updated") else: error_msg = "This category has already been assigned to the project." return (trove_obj, error_msg)
def update(self, icon=None, short=None, full=None): require_access(self.neighborhood, 'admin') self.award.short = short self.award.full = full if hasattr(icon, 'filename'): if self.award.icon: self.award.icon.delete() M.AwardFile.save_image( icon.filename, icon.file, content_type=icon.type, square=True, thumbnail_size=(48, 48), thumbnail_meta=dict(award_id=self.award._id)) for grant in M.AwardGrant.query.find(dict(award_id=self.award._id)): with h.push_context(grant.granted_to_project_id): g.post_event('project_updated') flash('Award updated.') redirect(self.award.longurl())
def add_screenshot(self, screenshot=None, caption=None, **kw): require_access(c.project, "update") if len(c.project.get_screenshots()) >= 6: flash("You may not have more than 6 screenshots per project.", "error") elif screenshot is not None and screenshot != "": M.AuditLog.log("add screenshot") M.ProjectFile.save_image( screenshot.filename, screenshot.file, content_type=screenshot.type, save_original=True, original_meta=dict(project_id=c.project._id, category="screenshot", caption=caption), square=True, thumbnail_size=(150, 150), thumbnail_meta=dict(project_id=c.project._id, category="screenshot_thumb"), ) g.post_event("project_updated") redirect("screenshots")
def register_subproject(self, project, name, user, install_apps): from allura import model as M assert h.re_path_portion.match(name), 'Invalid subproject shortname' shortname = project.shortname + '/' + name sp = M.Project(parent_id=project._id, neighborhood_id=project.neighborhood_id, shortname=shortname, name=name, database_uri=project.database_uri, last_updated=datetime.utcnow(), is_root=False) with h.push_config(c, project=sp): M.AppConfig.query.remove(dict(project_id=c.project._id)) if install_apps: sp.install_app('admin', 'admin', ordinal=1) sp.install_app('search', 'search', ordinal=2) g.post_event('project_created') return sp
def grant(self, grant=None, recipient=None): require_access(self.neighborhood, 'admin') grant_q = M.Award.query.find(dict(short=grant, created_by_neighborhood_id=self.neighborhood._id)).first() recipient_q = M.Project.query.find(dict( neighborhood_id=self.neighborhood._id, shortname=recipient, deleted=False)).first() if grant_q and recipient_q: app_config_id = ObjectId() tool_version = {'neighborhood': '0'} award = M.AwardGrant(app_config_id=app_config_id, tool_version=tool_version) award.award_id = grant_q._id award.granted_to_project_id = recipient_q._id award.granted_by_neighborhood_id = self.neighborhood._id with h.push_context(recipient_q._id): g.post_event('project_updated') redirect(request.referer)
def main(options): log.addHandler(logging.StreamHandler(sys.stdout)) log.setLevel(getattr(logging, options.log_level.upper())) nbhd = M.Neighborhood.query.get(name=options.neighborhood) if not nbhd: return 'Invalid neighborhood "%s".' % options.neighborhood admin_role = M.ProjectRole.by_name('Admin', project=nbhd.neighborhood_project) nbhd_admin = admin_role.users_with_role( project=nbhd.neighborhood_project)[0].user log.info('Making updates as neighborhood admin "%s"' % nbhd_admin.username) q = { 'neighborhood_id': nbhd._id, 'is_nbhd_project': False, 'deleted': False } private_count = public_count = 0 for projects in utils.chunked_find(M.Project, q): for p in projects: role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=p.root_project._id) if M.ACE.allow(role_anon._id, 'read') not in p.acl: if options.test: log.info('Would be made public: "%s"' % p.shortname) else: log.info('Making public: "%s"' % p.shortname) p.acl.append(M.ACE.allow(role_anon._id, 'read')) with h.push_config(c, project=p, user=nbhd_admin): ThreadLocalORMSession.flush_all() g.post_event('project_updated') private_count += 1 else: log.info('Already public: "%s"' % p.shortname) public_count += 1 log.info('Already public: %s' % public_count) if options.test: log.info('Would be made public: %s' % private_count) else: log.info('Made public: %s' % private_count) return 0
def register_subproject(self, project, name, user, install_apps): from allura import model as M assert h.re_path_portion.match(name), 'Invalid subproject shortname' shortname = project.shortname + '/' + name sp = M.Project( parent_id=project._id, neighborhood_id=project.neighborhood_id, shortname=shortname, name=name, database_uri=project.database_uri, last_updated = datetime.utcnow(), is_root=False) with h.push_config(c, project=sp): M.AppConfig.query.remove(dict(project_id=c.project._id)) if install_apps: sp.install_app('admin', 'admin', ordinal=1) sp.install_app('search', 'search', ordinal=2) g.post_event('project_created') return sp
def grant(self, grant=None, recipient=None): require_access(self.neighborhood, 'admin') grant_q = M.Award.query.find( dict(short=grant, created_by_neighborhood_id=self.neighborhood._id)).first() recipient_q = M.Project.query.find( dict(neighborhood_id=self.neighborhood._id, shortname=recipient, deleted=False)).first() if grant_q and recipient_q: app_config_id = ObjectId() tool_version = {'neighborhood': '0'} award = M.AwardGrant(app_config_id=app_config_id, tool_version=tool_version) award.award_id = grant_q._id award.granted_to_project_id = recipient_q._id award.granted_by_neighborhood_id = self.neighborhood._id with h.push_context(recipient_q._id): g.post_event('project_updated') redirect(request.referer)
def update(self, card=None, **kw): for pr in card: group = M.ProjectRole.query.get(_id=ObjectId(pr['id'])) assert group.project == c.project, 'Security violation' user_ids = pr.get('value', []) new_users = pr.get('new', []) if isinstance(user_ids, basestring): user_ids = [user_ids] if isinstance(new_users, basestring): new_users = [new_users] # Handle new users in groups user_added = False for username in new_users: user = M.User.by_username(username.strip()) if not user: flash('User %s not found' % username, 'error') redirect('.') if not user._id: continue # never add anon users to groups M.AuditLog.log('add user %s to %s', username, group.name) user.project_role().roles.append(group._id) user_added = True # Make sure we aren't removing all users from the Admin group if group.name == u'Admin' and not (user_ids or user_added): flash('You must have at least one user with the Admin role.', 'warning') redirect('.') # Handle users removed from groups user_ids = set(uid and ObjectId(uid) for uid in user_ids) for role in M.ProjectRole.query.find( dict(user_id={'$ne': None}, roles=group._id)): if role.user_id and role.user_id not in user_ids: role.roles = [ rid for rid in role.roles if rid != group._id ] M.AuditLog.log('remove user %s from %s', role.user.username, group.name) g.post_event('project_updated') redirect('.')
def main(options): log.addHandler(logging.StreamHandler(sys.stdout)) log.setLevel(getattr(logging, options.log_level.upper())) nbhd = M.Neighborhood.query.get(name=options.neighborhood) if not nbhd: return 'Invalid neighborhood "%s".' % options.neighborhood admin_role = M.ProjectRole.by_name('Admin', project=nbhd.neighborhood_project) nbhd_admin = admin_role.users_with_role(project=nbhd.neighborhood_project)[0].user log.info('Making updates as neighborhood admin "%s"' % nbhd_admin.username) q = {'neighborhood_id': nbhd._id, 'is_nbhd_project': False, 'deleted':False} private_count = public_count = 0 for projects in utils.chunked_find(M.Project, q): for p in projects: role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=p.root_project._id) if M.ACE.allow(role_anon._id, 'read') not in p.acl: if options.test: log.info('Would be made public: "%s"' % p.shortname) else: log.info('Making public: "%s"' % p.shortname) p.acl.append(M.ACE.allow(role_anon._id, 'read')) with h.push_config(c, project=p, user=nbhd_admin): ThreadLocalORMSession.flush_all() g.post_event('project_updated') private_count += 1 else: log.info('Already public: "%s"' % p.shortname) public_count += 1 log.info('Already public: %s' % public_count) if options.test: log.info('Would be made public: %s' % private_count) else: log.info('Made public: %s' % private_count) return 0
def update(self, card=None, **kw): for pr in card: group = M.ProjectRole.query.get(_id=ObjectId(pr['id'])) assert group.project == c.project, 'Security violation' user_ids = pr.get('value', []) new_users = pr.get('new', []) if isinstance(user_ids, basestring): user_ids = [ user_ids ] if isinstance(new_users, basestring): new_users = [ new_users ] # Handle new users in groups user_added = False for username in new_users: user = M.User.by_username(username.strip()) if not user: flash('User %s not found' % username, 'error') redirect('.') if not user._id: continue # never add anon users to groups M.AuditLog.log('add user %s to %s', username, group.name) user.project_role().roles.append(group._id) user_added = True # Make sure we aren't removing all users from the Admin group if group.name == u'Admin' and not (user_ids or user_added): flash('You must have at least one user with the Admin role.', 'warning') redirect('.') # Handle users removed from groups user_ids = set( uid and ObjectId(uid) for uid in user_ids) for role in M.ProjectRole.query.find(dict(user_id={'$ne':None}, roles=group._id)): if role.user_id and role.user_id not in user_ids: role.roles = [ rid for rid in role.roles if rid != group._id ] M.AuditLog.log('remove user %s from %s', role.user.username, group.name) g.post_event('project_updated') redirect('.')
project.trove_license = trove_ids(project.trove_license, p.trove_licenses) project.trove_os = trove_ids(project.trove_os, p.trove_oses) project.trove_language = trove_ids(project.trove_language, p.trove_languages) project.trove_topic = trove_ids(project.trove_topic, p.trove_topics) project.trove_natlanguage = trove_ids(project.trove_natlanguage, p.trove_natlanguages) project.trove_environment = trove_ids(project.trove_environment, p.trove_environments) for a in p.awards: M.AwardGrant(app_config_id=bson.ObjectId(), tool_version=dict(neighborhood='0'), award_id=a._id, granted_to_project_id=project._id, granted_by_neighborhood_id=nbhd._id) project.notifications_disabled = False with h.push_config(c, project=project, user=user): ThreadLocalORMSession.flush_all() g.post_event('project_updated') session(project).clear() return 0 def create_projects(projects, nbhd, user, options): for p in projects: r = create_project(Object(p), nbhd, user, options) if r != 0: sys.exit(r) def main(options): log.addHandler(logging.StreamHandler(sys.stdout)) log.setLevel(getattr(logging, options.log_level.upper())) log.debug(options) nbhd = M.Neighborhood.query.get(name=options.neighborhood)
def register_project(self, neighborhood, shortname, project_name, user, user_project, private_project, apps=None): '''Register a new project in the neighborhood. The given user will become the project's superuser. ''' from allura import model as M # Check for private project rights if neighborhood.features['private_projects'] == False and private_project: raise ValueError("You can't create private projects for %s neighborhood" % neighborhood.name) # Check for project limit creation pq = M.Project.query.find(dict( neighborhood_id=neighborhood._id, deleted=False, is_nbhd_project=False, )) count = pq.count() nb_max_projects = neighborhood.get_max_projects() if nb_max_projects is not None and count >= nb_max_projects: log.exception('Error registering project %s' % project_name) raise forge_exc.ProjectOverlimitError() 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: user = M.User.by_username(username) if not (user and user._id): continue pr = user.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')) except forge_exc.ProjectConflict: raise except: ThreadLocalORMSession.close_all() log.exception('Error registering project %s' % p) raise 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 # for user-project reg, and c.user isn't set yet g.post_event('project_created') return p
def register_project(self, neighborhood, shortname, project_name, user, user_project, private_project, apps=None): '''Register a new project in the neighborhood. The given user will become the project's superuser. ''' from allura import model as M # Check for private project rights if neighborhood.features['private_projects'] == False and private_project: raise ValueError("You can't create private projects for %s neighborhood" % neighborhood.name) # Check for project limit creation pq = M.Project.query.find(dict( neighborhood_id=neighborhood._id, deleted=False, is_nbhd_project=False, )) count = pq.count() nb_max_projects = neighborhood.get_max_projects() if nb_max_projects is not None and count >= nb_max_projects: log.exception('Error registering project %s' % project_name) raise forge_exc.ProjectOverlimitError() self.rate_limit(user, neighborhood) 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 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 # for user-project reg, and c.user isn't set yet g.post_event('project_created') return p
def update(self, name=None, short_description=None, summary='', icon=None, category=None, external_homepage='', support_page='', support_page_url='', removal='', moved_to_url='', export_controlled=False, export_control_type=None, tracking_id='', **kw): require_access(c.project, 'update') if removal != c.project.removal: M.AuditLog.log('change project removal status to %s', removal) h.log_action(log, 'change project removal status').info('') c.project.removal = removal c.project.removal_changed_date = datetime.utcnow() if 'delete_icon' in kw: M.ProjectFile.query.remove(dict(project_id=c.project._id, category='icon')) M.AuditLog.log('remove project icon') h.log_action(log, 'remove project icon').info('') g.post_event('project_updated') redirect('overview') elif 'delete' in kw: allow_project_delete = asbool(config.get('allow_project_delete', True)) if allow_project_delete or not c.project.is_root: M.AuditLog.log('delete project') h.log_action(log, 'delete project').info('') plugin.ProjectRegistrationProvider.get().delete_project(c.project, c.user) redirect('overview') elif 'undelete' in kw: h.log_action(log, 'undelete project').info('') M.AuditLog.log('undelete project') plugin.ProjectRegistrationProvider.get().undelete_project(c.project, c.user) redirect('overview') if name != c.project.name: h.log_action(log, 'change project name').info('') M.AuditLog.log('change project name to %s', name) c.project.name = name if short_description != c.project.short_description: h.log_action(log, 'change project short description').info('') M.AuditLog.log('change short description to %s', short_description) c.project.short_description = short_description if summary != c.project.summary: h.log_action(log, 'change project summary').info('') M.AuditLog.log('change summary to %s', summary) c.project.summary = summary category = category and ObjectId(category) or None if category != c.project.category_id: h.log_action(log, 'change project category').info('') M.AuditLog.log('change category to %s', category) c.project.category_id = category if external_homepage != c.project.external_homepage: h.log_action(log, 'change external home page').info('') M.AuditLog.log('change external home page to %s', external_homepage) c.project.external_homepage = external_homepage if support_page != c.project.support_page: h.log_action(log, 'change project support page').info('') M.AuditLog.log('change project support page to %s', support_page) c.project.support_page = support_page if support_page_url != c.project.support_page_url: h.log_action(log, 'change project support page url').info('') M.AuditLog.log('change project support page url to %s', support_page_url) c.project.support_page_url = support_page_url if moved_to_url != c.project.moved_to_url: h.log_action(log, 'change project moved to url').info('') M.AuditLog.log('change project moved to url to %s', moved_to_url) c.project.moved_to_url = moved_to_url if export_controlled != c.project.export_controlled: h.log_action(log, 'change project export controlled status').info('') M.AuditLog.log('change project export controlled status to %s', export_controlled) c.project.export_controlled = not not export_controlled if not export_controlled: export_control_type = None if export_control_type != c.project.export_control_type: h.log_action(log, 'change project export control type').info('') M.AuditLog.log('change project export control type to %s', export_control_type) c.project.export_control_type = export_control_type if tracking_id != c.project.tracking_id: h.log_action(log, 'change project tracking ID').info('') M.AuditLog.log('change project tracking ID to %s', tracking_id) c.project.tracking_id = tracking_id if icon is not None and icon != '': if c.project.icon: M.ProjectFile.remove(dict(project_id=c.project._id, category='icon')) M.AuditLog.log('update project icon') M.ProjectFile.save_image( icon.filename, icon.file, content_type=icon.type, square=True, thumbnail_size=(48,48), thumbnail_meta=dict(project_id=c.project._id,category='icon')) g.post_event('project_updated') redirect('overview')
def edit_screenshot(self, id=None, caption=None, **kw): require_access(c.project, 'update') if id is not None and id != '': M.ProjectFile.query.get(project_id=c.project._id, _id=ObjectId(id)).caption=caption g.post_event('project_updated') redirect('screenshots')
def update(self, name=None, short_description=None, summary='', icon=None, category=None, external_homepage='', support_page='', support_page_url='', removal='', moved_to_url='', export_controlled=False, export_control_type=None, tracking_id='', **kw): require_access(c.project, 'update') if removal != c.project.removal: M.AuditLog.log('change project removal status to %s', removal) h.log_action(log, 'change project removal status').info('') c.project.removal = removal c.project.removal_changed_date = datetime.utcnow() if 'delete_icon' in kw: M.ProjectFile.query.remove( dict(project_id=c.project._id, category='icon')) M.AuditLog.log('remove project icon') h.log_action(log, 'remove project icon').info('') g.post_event('project_updated') redirect('overview') elif 'delete' in kw: allow_project_delete = asbool( config.get('allow_project_delete', True)) if allow_project_delete or not c.project.is_root: M.AuditLog.log('delete project') h.log_action(log, 'delete project').info('') plugin.ProjectRegistrationProvider.get().delete_project( c.project, c.user) redirect('overview') elif 'undelete' in kw: h.log_action(log, 'undelete project').info('') M.AuditLog.log('undelete project') plugin.ProjectRegistrationProvider.get().undelete_project( c.project, c.user) redirect('overview') if name != c.project.name: h.log_action(log, 'change project name').info('') M.AuditLog.log('change project name to %s', name) c.project.name = name if short_description != c.project.short_description: h.log_action(log, 'change project short description').info('') M.AuditLog.log('change short description to %s', short_description) c.project.short_description = short_description if summary != c.project.summary: h.log_action(log, 'change project summary').info('') M.AuditLog.log('change summary to %s', summary) c.project.summary = summary category = category and ObjectId(category) or None if category != c.project.category_id: h.log_action(log, 'change project category').info('') M.AuditLog.log('change category to %s', category) c.project.category_id = category if external_homepage != c.project.external_homepage: h.log_action(log, 'change external home page').info('') M.AuditLog.log('change external home page to %s', external_homepage) c.project.external_homepage = external_homepage if support_page != c.project.support_page: h.log_action(log, 'change project support page').info('') M.AuditLog.log('change project support page to %s', support_page) c.project.support_page = support_page if support_page_url != c.project.support_page_url: h.log_action(log, 'change project support page url').info('') M.AuditLog.log('change project support page url to %s', support_page_url) c.project.support_page_url = support_page_url if moved_to_url != c.project.moved_to_url: h.log_action(log, 'change project moved to url').info('') M.AuditLog.log('change project moved to url to %s', moved_to_url) c.project.moved_to_url = moved_to_url if export_controlled != c.project.export_controlled: h.log_action(log, 'change project export controlled status').info('') M.AuditLog.log('change project export controlled status to %s', export_controlled) c.project.export_controlled = not not export_controlled if not export_controlled: export_control_type = None if export_control_type != c.project.export_control_type: h.log_action(log, 'change project export control type').info('') M.AuditLog.log('change project export control type to %s', export_control_type) c.project.export_control_type = export_control_type if tracking_id != c.project.tracking_id: h.log_action(log, 'change project tracking ID').info('') M.AuditLog.log('change project tracking ID to %s', tracking_id) c.project.tracking_id = tracking_id if icon is not None and icon != '': if c.project.icon: M.ProjectFile.remove( dict(project_id=c.project._id, category='icon')) M.AuditLog.log('update project icon') M.ProjectFile.save_image(icon.filename, icon.file, content_type=icon.type, square=True, thumbnail_size=(48, 48), thumbnail_meta=dict( project_id=c.project._id, category='icon')) g.post_event('project_updated') redirect('overview')
class ProjectAdminController(BaseController): def _check_security(self): require_access(c.project, 'admin') def __init__(self): self.permissions = PermissionsController() self.groups = GroupsController() self.audit = AuditController() @with_trailing_slash @expose('jinja:allura.ext.admin:templates/project_admin.html') def index(self, **kw): return dict() @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_invitations.html') def invitations(self): return dict() @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_overview.html') def overview(self, **kw): c.markdown_editor = W.markdown_editor c.metadata_admin = W.metadata_admin c.explain_export_modal = W.explain_export_modal show_export_control = asbool(config.get('show_export_control', False)) allow_project_delete = asbool(config.get('allow_project_delete', True)) explain_export_text = '''The purpose of this section is to determine whether your project is subject to the provisions of the US Export Administration Regulations. You should consult section 734.4 and Supplement 2 to Part 734 for information on such items and the calculation of U.S. controlled content. <a href="http://www.bis.doc.gov/encryption/default.htm" target="_blank">http://www.bis.doc.gov/encryption/default.htm</a>''' if 'us_export_contact' in config: explain_export_text += 'If you have additional questions, please contact <a href="mailto:{contact}">{contact}</a>.'.format( contact=config['us_export_contact']) return dict(show_export_control=show_export_control, allow_project_delete=allow_project_delete, explain_export_text=explain_export_text) @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_screenshots.html') def screenshots(self, **kw): c.screenshot_admin = W.screenshot_admin c.screenshot_list = W.screenshot_list return dict() @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_trove.html') def trove(self): c.label_edit = W.label_edit base_troves = M.TroveCategory.query.find( dict(trove_parent_id=0)).sort('fullname').all() topic_trove = M.TroveCategory.query.get(trove_parent_id=0, shortname='topic') license_trove = M.TroveCategory.query.get(trove_parent_id=0, shortname='license') return dict(base_troves=base_troves, license_trove=license_trove, topic_trove=topic_trove) @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_tools.html') def tools(self, **kw): c.markdown_editor = W.markdown_editor c.label_edit = W.label_edit c.mount_delete = W.mount_delete c.admin_modal = W.admin_modal c.install_modal = W.install_modal mounts = c.project.ordered_mounts() return dict( mounts=mounts, installable_tools=AdminApp.installable_tools_for(c.project), roles=M.ProjectRole.query.find( dict(project_id=c.project.root_project._id)).sort('_id').all(), categories=M.ProjectCategory.query.find( dict(parent_id=None)).sort('label').all()) @expose() @require_post() def update_labels(self, labels=None, labels_old=None, **kw): require_access(c.project, 'admin') c.project.labels = labels.split(',') M.AuditLog.log('updated labels') redirect('trove') @without_trailing_slash @expose() def clone(self, repo_type=None, source_url=None, mount_point=None, mount_label=None, **kw): require_access(c.project, 'admin') if repo_type is None: return ('<form method="get">' '<input name="repo_type" value="Git">' '<input name="source_url">' '<input type="submit">' '</form>') for ep in pkg_resources.iter_entry_points('allura', repo_type): break if ep is None or source_url is None: raise exc.HTTPNotFound h.log_action(log, 'install tool').info('clone repo from %s', source_url, meta=dict(tool_type=repo_type, mount_point=mount_point, mount_label=mount_label)) c.project.install_app(repo_type, mount_point=mount_point, mount_label=mount_label, init_from_url=source_url) M.AuditLog.log('Create repo as clone') redirect('tools') @without_trailing_slash @expose('jinja:allura.ext.admin:templates/project_permissions.html') def groups(self, **kw): return dict() @expose() def _lookup(self, name, *remainder): app = c.project.app_instance(name) if app is None: raise exc.HTTPNotFound, name return app.admin, remainder @expose() @require_post() @validate(W.metadata_admin, error_handler=overview) def update(self, name=None, short_description=None, summary='', icon=None, category=None, external_homepage='', support_page='', support_page_url='', removal='', moved_to_url='', export_controlled=False, export_control_type=None, tracking_id='', **kw): require_access(c.project, 'update') if removal != c.project.removal: M.AuditLog.log('change project removal status to %s', removal) h.log_action(log, 'change project removal status').info('') c.project.removal = removal c.project.removal_changed_date = datetime.utcnow() if 'delete_icon' in kw: M.ProjectFile.query.remove( dict(project_id=c.project._id, category='icon')) M.AuditLog.log('remove project icon') h.log_action(log, 'remove project icon').info('') g.post_event('project_updated') redirect('overview') elif 'delete' in kw: allow_project_delete = asbool( config.get('allow_project_delete', True)) if allow_project_delete or not c.project.is_root: M.AuditLog.log('delete project') h.log_action(log, 'delete project').info('') plugin.ProjectRegistrationProvider.get().delete_project( c.project, c.user) redirect('overview') elif 'undelete' in kw: h.log_action(log, 'undelete project').info('') M.AuditLog.log('undelete project') plugin.ProjectRegistrationProvider.get().undelete_project( c.project, c.user) redirect('overview') if name != c.project.name: h.log_action(log, 'change project name').info('') M.AuditLog.log('change project name to %s', name) c.project.name = name if short_description != c.project.short_description: h.log_action(log, 'change project short description').info('') M.AuditLog.log('change short description to %s', short_description) c.project.short_description = short_description if summary != c.project.summary: h.log_action(log, 'change project summary').info('') M.AuditLog.log('change summary to %s', summary) c.project.summary = summary category = category and ObjectId(category) or None if category != c.project.category_id: h.log_action(log, 'change project category').info('') M.AuditLog.log('change category to %s', category) c.project.category_id = category if external_homepage != c.project.external_homepage: h.log_action(log, 'change external home page').info('') M.AuditLog.log('change external home page to %s', external_homepage) c.project.external_homepage = external_homepage if support_page != c.project.support_page: h.log_action(log, 'change project support page').info('') M.AuditLog.log('change project support page to %s', support_page) c.project.support_page = support_page if support_page_url != c.project.support_page_url: h.log_action(log, 'change project support page url').info('') M.AuditLog.log('change project support page url to %s', support_page_url) c.project.support_page_url = support_page_url if moved_to_url != c.project.moved_to_url: h.log_action(log, 'change project moved to url').info('') M.AuditLog.log('change project moved to url to %s', moved_to_url) c.project.moved_to_url = moved_to_url if export_controlled != c.project.export_controlled: h.log_action(log, 'change project export controlled status').info('') M.AuditLog.log('change project export controlled status to %s', export_controlled) c.project.export_controlled = not not export_controlled if not export_controlled: export_control_type = None if export_control_type != c.project.export_control_type: h.log_action(log, 'change project export control type').info('') M.AuditLog.log('change project export control type to %s', export_control_type) c.project.export_control_type = export_control_type if tracking_id != c.project.tracking_id: h.log_action(log, 'change project tracking ID').info('') M.AuditLog.log('change project tracking ID to %s', tracking_id) c.project.tracking_id = tracking_id if icon is not None and icon != '': if c.project.icon: M.ProjectFile.remove( dict(project_id=c.project._id, category='icon')) M.AuditLog.log('update project icon') M.ProjectFile.save_image(icon.filename, icon.file, content_type=icon.type, square=True, thumbnail_size=(48, 48), thumbnail_meta=dict( project_id=c.project._id, category='icon')) g.post_event('project_updated') redirect('overview') def _add_trove(self, type, new_trove): current_troves = getattr(c.project, 'trove_%s' % type) trove_obj = M.TroveCategory.query.get(trove_cat_id=int(new_trove)) error_msg = None if type in ['license', 'audience', 'developmentstatus', 'language' ] and len(current_troves) >= 6: error_msg = 'You may not have more than 6 of this category.' elif type in ['topic'] and len(current_troves) >= 3: error_msg = 'You may not have more than 3 of this category.' elif trove_obj is not None: if trove_obj._id not in current_troves: current_troves.append(trove_obj._id) g.post_event('project_updated') else: error_msg = 'This category has already been assigned to the project.' return (trove_obj, error_msg) @expose('json:') @require_post() def add_trove_js(self, type, new_trove, **kw): require_access(c.project, 'update') trove_obj, error_msg = self._add_trove(type, new_trove) return dict(trove_full_path=trove_obj.fullpath, trove_cat_id=trove_obj.trove_cat_id, error_msg=error_msg) redirect('trove') @expose() @require_post() def add_trove(self, type, new_trove, **kw): require_access(c.project, 'update') trove_obj, error_msg = self._add_trove(type, new_trove) M.AuditLog.log('add trove %s: %s', type, trove_obj.fullpath) if error_msg: flash(error_msg, 'error') redirect('trove') @expose() @require_post() def delete_trove(self, type, trove, **kw): require_access(c.project, 'update') trove_obj = M.TroveCategory.query.get(trove_cat_id=int(trove)) current_troves = getattr(c.project, 'trove_%s' % type) if trove_obj is not None and trove_obj._id in current_troves: M.AuditLog.log('remove trove %s: %s', type, trove_obj.fullpath) current_troves.remove(trove_obj._id) g.post_event('project_updated') redirect('trove') @expose() @require_post() @validate(W.screenshot_admin) def add_screenshot(self, screenshot=None, caption=None, **kw): require_access(c.project, 'update') if len(c.project.get_screenshots()) >= 6: flash('You may not have more than 6 screenshots per project.', 'error') elif screenshot is not None and screenshot != '': M.AuditLog.log('add screenshot') M.ProjectFile.save_image( screenshot.filename, screenshot.file, content_type=screenshot.type, save_original=True, original_meta=dict(project_id=c.project._id, category='screenshot', caption=caption), square=True, thumbnail_size=(150, 150), thumbnail_meta=dict(project_id=c.project._id, category='screenshot_thumb')) g.post_event('project_updated') redirect('screenshots') @expose() @require_post() def delete_screenshot(self, id=None, **kw): require_access(c.project, 'update') if id is not None and id != '': M.AuditLog.log('remove screenshot') M.ProjectFile.query.remove( dict(project_id=c.project._id, _id=ObjectId(id))) g.post_event('project_updated') redirect('screenshots') @expose() @require_post() def edit_screenshot(self, id=None, caption=None, **kw): require_access(c.project, 'update') if id is not None and id != '': M.ProjectFile.query.get(project_id=c.project._id, _id=ObjectId(id)).caption = caption g.post_event('project_updated') redirect('screenshots') @expose() @require_post() def join_neighborhood(self, nid): require_access(c.project, 'admin') if not nid: n = M.Neighborhood.query.get(name='Projects') c.project.neighborhood_id = n._id flash('Joined %s' % n.name) redirect(c.project.url() + 'admin/') nid = ObjectId(str(nid)) if nid not in c.project.neighborhood_invitations: flash('No invitation to that neighborhood', 'error') redirect('.') c.project.neighborhood_id = nid n = M.Neighborhood.query.get(_id=nid) flash('Joined %s' % n.name) redirect('invitations') @h.vardec @expose() @require_post() def update_mount_order(self, subs=None, tools=None, **kw): if subs: for sp in subs: p = M.Project.query.get( shortname=sp['shortname'], neighborhood_id=c.project.neighborhood_id) p.ordinal = int(sp['ordinal']) if tools: for p in tools: c.project.app_config(p['mount_point']).options.ordinal = int( p['ordinal']) redirect('tools') @h.vardec @expose() @require_post() def update_mounts(self, subproject=None, tool=None, new=None, **kw): if subproject is None: subproject = [] if tool is None: tool = [] for sp in subproject: p = M.Project.query.get(shortname=sp['shortname'], neighborhood_id=c.project.neighborhood_id) if sp.get('delete'): require_access(c.project, 'admin') M.AuditLog.log('delete subproject %s', sp['shortname']) h.log_action(log, 'delete subproject').info( 'delete subproject %s', sp['shortname'], meta=dict(name=sp['shortname'])) p.removal = 'deleted' plugin.ProjectRegistrationProvider.get().delete_project( p, c.user) elif not new: M.AuditLog.log('update subproject %s', sp['shortname']) p.name = sp['name'] p.ordinal = int(sp['ordinal']) for p in tool: if p.get('delete'): require_access(c.project, 'admin') M.AuditLog.log('uninstall tool %s', p['mount_point']) h.log_action(log, 'uninstall tool').info( 'uninstall tool %s', p['mount_point'], meta=dict(mount_point=p['mount_point'])) c.project.uninstall_app(p['mount_point']) elif not new: M.AuditLog.log('update tool %s', p['mount_point']) options = c.project.app_config(p['mount_point']).options options.mount_label = p['mount_label'] options.ordinal = int(p['ordinal']) try: if new and new.get('install'): ep_name = new.get('ep_name', None) if not ep_name: require_access(c.project, 'create') mount_point = new['mount_point'].lower() or h.nonce() M.AuditLog.log('create subproject %s', mount_point) h.log_action(log, 'create subproject').info( 'create subproject %s', mount_point, meta=dict(mount_point=mount_point, name=new['mount_label'])) sp = c.project.new_subproject(mount_point) sp.name = new['mount_label'] sp.ordinal = int(new['ordinal']) else: require_access(c.project, 'admin') mount_point = new['mount_point'].lower() or ep_name.lower() M.AuditLog.log('install tool %s', mount_point) h.log_action(log, 'install tool').info( 'install tool %s', mount_point, meta=dict(tool_type=ep_name, mount_point=mount_point, mount_label=new['mount_label'])) c.project.install_app(ep_name, mount_point, mount_label=new['mount_label'], ordinal=new['ordinal']) except forge_exc.ForgeError, exc: flash('%s: %s' % (exc.__class__.__name__, exc.args[0]), 'error') g.post_event('project_updated') redirect('tools')
def spam(self): self.status = 'spam' self.thread.num_replies = max(0, self.thread.num_replies - 1) g.post_event('spam', self.index_id())
def revoke(self): require_access(self.neighborhood, 'admin') self.grant.delete() with h.push_context(self.project._id): g.post_event('project_updated') redirect(request.referer)
project.trove_topic = trove_ids(project.trove_topic, p.trove_topics) project.trove_natlanguage = trove_ids(project.trove_natlanguage, p.trove_natlanguages) project.trove_environment = trove_ids(project.trove_environment, p.trove_environments) for a in p.awards: M.AwardGrant(app_config_id=bson.ObjectId(), tool_version=dict(neighborhood='0'), award_id=a._id, granted_to_project_id=project._id, granted_by_neighborhood_id=nbhd._id) project.notifications_disabled = False with h.push_config(c, project=project, user=user): ThreadLocalORMSession.flush_all() g.post_event('project_updated') session(project).clear() return 0 def create_projects(projects, nbhd, user, options): for p in projects: r = create_project(Object(p), nbhd, user, options) if r != 0: sys.exit(r) def main(options): log.addHandler(logging.StreamHandler(sys.stdout)) log.setLevel(getattr(logging, options.log_level.upper())) log.debug(options)
def update( self, name=None, short_description=None, summary="", icon=None, category=None, external_homepage="", support_page="", support_page_url="", removal="", moved_to_url="", export_controlled=False, export_control_type=None, tracking_id="", **kw ): require_access(c.project, "update") if removal != c.project.removal: M.AuditLog.log("change project removal status to %s", removal) h.log_action(log, "change project removal status").info("") c.project.removal = removal c.project.removal_changed_date = datetime.utcnow() if "delete_icon" in kw: M.ProjectFile.query.remove(dict(project_id=c.project._id, category="icon")) M.AuditLog.log("remove project icon") h.log_action(log, "remove project icon").info("") g.post_event("project_updated") redirect("overview") elif "delete" in kw: allow_project_delete = asbool(config.get("allow_project_delete", True)) if allow_project_delete or not c.project.is_root: M.AuditLog.log("delete project") h.log_action(log, "delete project").info("") plugin.ProjectRegistrationProvider.get().delete_project(c.project, c.user) redirect("overview") elif "undelete" in kw: h.log_action(log, "undelete project").info("") M.AuditLog.log("undelete project") plugin.ProjectRegistrationProvider.get().undelete_project(c.project, c.user) redirect("overview") if name != c.project.name: h.log_action(log, "change project name").info("") M.AuditLog.log("change project name to %s", name) c.project.name = name if short_description != c.project.short_description: h.log_action(log, "change project short description").info("") M.AuditLog.log("change short description to %s", short_description) c.project.short_description = short_description if summary != c.project.summary: h.log_action(log, "change project summary").info("") M.AuditLog.log("change summary to %s", summary) c.project.summary = summary category = category and ObjectId(category) or None if category != c.project.category_id: h.log_action(log, "change project category").info("") M.AuditLog.log("change category to %s", category) c.project.category_id = category if external_homepage != c.project.external_homepage: h.log_action(log, "change external home page").info("") M.AuditLog.log("change external home page to %s", external_homepage) c.project.external_homepage = external_homepage if support_page != c.project.support_page: h.log_action(log, "change project support page").info("") M.AuditLog.log("change project support page to %s", support_page) c.project.support_page = support_page if support_page_url != c.project.support_page_url: h.log_action(log, "change project support page url").info("") M.AuditLog.log("change project support page url to %s", support_page_url) c.project.support_page_url = support_page_url if moved_to_url != c.project.moved_to_url: h.log_action(log, "change project moved to url").info("") M.AuditLog.log("change project moved to url to %s", moved_to_url) c.project.moved_to_url = moved_to_url if export_controlled != c.project.export_controlled: h.log_action(log, "change project export controlled status").info("") M.AuditLog.log("change project export controlled status to %s", export_controlled) c.project.export_controlled = not not export_controlled if not export_controlled: export_control_type = None if export_control_type != c.project.export_control_type: h.log_action(log, "change project export control type").info("") M.AuditLog.log("change project export control type to %s", export_control_type) c.project.export_control_type = export_control_type if tracking_id != c.project.tracking_id: h.log_action(log, "change project tracking ID").info("") M.AuditLog.log("change project tracking ID to %s", tracking_id) c.project.tracking_id = tracking_id if icon is not None and icon != "": if c.project.icon: M.ProjectFile.remove(dict(project_id=c.project._id, category="icon")) M.AuditLog.log("update project icon") M.ProjectFile.save_image( icon.filename, icon.file, content_type=icon.type, square=True, thumbnail_size=(48, 48), thumbnail_meta=dict(project_id=c.project._id, category="icon"), ) g.post_event("project_updated") redirect("overview")