You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by ke...@apache.org on 2020/06/01 19:10:24 UTC

[allura] branch master updated: Add more functionality to the add_user_to_group.py script

This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
     new 59863ea  Add more functionality to the add_user_to_group.py script
59863ea is described below

commit 59863eae3c231e46d4bce67a93b83037f8c1facc
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Thu May 28 17:07:20 2020 -0400

    Add more functionality to the add_user_to_group.py script
---
 scripts/add_user_to_group.py | 72 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 61 insertions(+), 11 deletions(-)

diff --git a/scripts/add_user_to_group.py b/scripts/add_user_to_group.py
index 7ca1012..8d36b37 100644
--- a/scripts/add_user_to_group.py
+++ b/scripts/add_user_to_group.py
@@ -38,42 +38,92 @@ Example:
 
 from __future__ import unicode_literals
 from __future__ import absolute_import
+
+import logging
+
 from allura import model as M
+from allura.lib.utils import chunked_find
 from ming.orm import ThreadLocalORMSession
 
 
+log = logging.getLogger(__name__)
+
+
 def main(options):
     nbhd = M.Neighborhood.query.get(url_prefix=options.nbhd)
     if not nbhd:
         return "Couldn't find neighborhood with url_prefix '%s'" % options.nbhd
-    project = M.Project.query.get(neighborhood_id=nbhd._id,
-                                  shortname=options.project)
-    if not project:
-        return "Couldn't find project with shortname '%s'" % options.project
+
     user = M.User.by_username(options.user)
     if not user:
         return "Couldn't find user with username '%s'" % options.user
+
+    if options.replace_user:
+        replace_user = M.User.by_username(options.replace_user)
+        if not replace_user:
+            return "Couldn't find user with username '%s'" % options.replace_user
+    else:
+        replace_user = None
+
+    if options.project == 'ALLPROJECTS':
+        for chunk in chunked_find(M.Project, dict(
+                neighborhood_id=nbhd._id,
+                shortname={'$ne': '--init--'},
+        )):
+            for p in chunk:
+                update_project(options, user, p, replace_user=replace_user)
+    else:
+        project = M.Project.query.get(neighborhood_id=nbhd._id,
+                                      shortname=options.project)
+        if not project:
+            return "Couldn't find project with shortname '%s'" % options.project
+        update_project(options, user, project, replace_user=replace_user)
+
+
+def update_project(options, user, project, replace_user=None):
     project_role = M.ProjectRole.by_name(options.group, project=project)
     if not project_role:
-        return "Couldn't find group (ProjectRole) with name '%s'" % options.group
-    user_roles = M.ProjectRole.by_user(
-        user, project=project, upsert=True).roles
-    if project_role._id not in user_roles:
+        return "Couldn't find group (ProjectRole) with name '%s' in %s" % (options.group, project.url())
+
+    if replace_user:
+        replace_user_roles = M.ProjectRole.by_user(replace_user, project=project, upsert=True).roles
+        if project_role._id not in replace_user_roles:
+            log.info('Cannot replace %s they are not %s of %s', replace_user.username, options.group, project.url())
+            return
+        if options.dry_run:
+            log.info('Would remove %s as %s of %s', replace_user.username, options.group, project.url())
+        else:
+            replace_user_roles.remove(project_role._id)
+            ThreadLocalORMSession.flush_all()
+
+    user_roles = M.ProjectRole.by_user(user, project=project, upsert=True).roles
+    if project_role._id in user_roles:
+        log.info('%s is already %s of %s', user.username, options.group, project.url())
+        return
+
+    if options.dry_run:
+        log.info('Would add %s as %s of %s', user.username, options.group, project.url())
+    else:
         user_roles.append(project_role._id)
-    ThreadLocalORMSession.flush_all()
+        ThreadLocalORMSession.flush_all()
 
 
 def parse_options():
     import argparse
     parser = argparse.ArgumentParser(description=__doc__,
                                      formatter_class=argparse.RawDescriptionHelpFormatter)
-    parser.add_argument('user', help='Username')
+    parser.add_argument('user', help='Username to add')
     parser.add_argument('group', help='Group (ProjectRole) name, e.g. Admin, '
                         'Member, Developer, etc.')
     parser.add_argument('project', nargs='?', default='--init--',
-                        help='Project shortname. Default is --init--.')
+                        help='Project shortname. Default is --init-- (the neighborhood itself).'
+                             'Use "ALLPROJECTS" for all projects within a neighborhood')
     parser.add_argument('--nbhd', default='/p/', help='Neighborhood '
                         'url_prefix. Default is /p/.')
+    parser.add_argument('--replace-user', help='If this is specified, remove this user and only add the new user if '
+                                               'this user was found and removed from the project(s)')
+    parser.add_argument('--dry-run', action='store_true',
+                        help='Dry-run actions logged to log file')
     return parser.parse_args()