[#8364] remove user roles if they are emptied
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index ae55943..064108e 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -1167,6 +1167,9 @@
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_role.roles.remove(group._id)
+ if len(user_role.roles) == 0:
+ # user has no roles in this project any more, so don't leave a useless doc around
+ user_role.delete()
g.post_event('project_updated')
return dict()
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 01b6572..3c678b3 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -829,14 +829,13 @@
class ProjectRole(MappedClass):
"""
- Per-project roles, called "Groups" in the UI.
- This can be a proxy for a single user. It can also inherit roles.
+ The roles that a single user holds in a project.
+ Also the named roles (called "Groups" in the UI) are in this model (and can include other named roles)
- :var user_id: used if this role is for a single user
- :var project_id:
- :var name:
- :var roles: a list of other :class:`ProjectRole` ``ObjectId`` values. These roles are delegated through the
- current role.
+ :var user_id: used if this role is for a single user. Empty for named roles
+ :var project_id: the project id
+ :var name: named roles (like Admin, Developer, custom-names-too)
+ :var roles: a list of other :class:`ProjectRole` ``ObjectId`` values which this user/group has access to
"""
class __mongometa__:
diff --git a/scripts/add_user_to_group.py b/scripts/add_user_to_group.py
index f175faa..8c9a757 100644
--- a/scripts/add_user_to_group.py
+++ b/scripts/add_user_to_group.py
@@ -94,15 +94,18 @@
found_any_replace_users = False
for replace_user in replace_users:
- replace_user_roles = M.ProjectRole.by_user(replace_user, project=project, upsert=True).roles
- if project_role._id not in replace_user_roles:
+ replace_user_perm = M.ProjectRole.by_user(replace_user, project=project)
+ if not replace_user_perm or project_role._id not in replace_user_perm.roles:
log.info('Cannot replace %s they are not %s of %s', replace_user.username, options.group, project.url())
continue
found_any_replace_users = True
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)
+ replace_user_perm.roles.remove(project_role._id)
+ if len(replace_user_perm.roles) == 0:
+ # user has no roles in this project any more, so don't leave a useless doc around
+ replace_user_perm.delete()
ThreadLocalORMSession.flush_all()
if replace_users and not found_any_replace_users:
log.info('Not adding %s since no replace-users found on %s', user.username, project.url())