Invoke auth handler when deleting a user via importer

plus some misc. tweaks i needed to cleanup some user accounts
This commit is contained in:
Lance Edgar 2021-10-14 14:17:58 -04:00
parent a8d820fe99
commit d98afd2c0f
4 changed files with 58 additions and 4 deletions

View file

@ -28,6 +28,8 @@ See also :doc:`rattail-manual:base/handlers/other/auth`.
from __future__ import unicode_literals, absolute_import
import sqlalchemy_continuum as continuum
from rattail.app import GenericHandler
@ -189,3 +191,39 @@ class AuthHandler(GenericHandler):
include_guest=include_guest,
include_authenticated=include_authenticated)
return permission in perms
def delete_user(self, user, **kwargs):
"""
Delete the given user account. Use with caution! As this
generally cannot be undone.
Default behavior here is of course to delete the account, but
it also must try to "remove" the user association from various
places, in particular the continuum transactions table.
Please note that this will leave certain record versions as
appearing to be "without an author".
"""
session = self.app.get_session(user)
# disassociate user from transactions
self.remove_user_from_continuum_transactions(user)
# finally, delete the user outright
session.delete(user)
return True
def remove_user_from_continuum_transactions(self, user):
"""
Remove the given user from all Continuum transactions.
"""
session = self.app.get_session(user)
model = self.model
# remove the user from any continuum transactions
# nb. we can use "any" model class here, to obtain Transaction
Transaction = continuum.transaction_class(model.User)
transactions = session.query(Transaction)\
.filter(Transaction.user_id == user.uuid)\
.all()
for txn in transactions:
txn.user_id = None

View file

@ -543,6 +543,15 @@ class UserImporter(ToRattail):
auth.set_user_password(user, data['plain_password'])
return user
def delete_object(self, user):
"""
Override this to invoke the auth handler for user deletion,
since it may have extra smarts.
"""
auth = self.app.get_auth_handler()
auth.delete_user(user)
return True
class AdminUserImporter(UserImporter):
"""

View file

@ -349,15 +349,17 @@ class GlobalRoleImporter(RoleImporter):
for new_user in new_users:
if new_user not in old_users:
user = self.session.query(model.User).get(new_user)
user.roles.append(role)
changed = True
if user:
user.roles.append(role)
changed = True
# remove some users
for old_user in old_users:
if old_user not in new_users:
user = self.session.query(model.User).get(old_user)
user.roles.remove(role)
changed = True
if user:
user.roles.remove(role)
changed = True
if changed:
# also record a change to the role, for datasync.

View file

@ -314,6 +314,7 @@ class PeopleHandler(GenericHandler):
F('last_name'),
F('display_name'),
F('usernames', additive=True),
F('employee_uuid'),
F('member_uuids', additive=True),
]
@ -328,6 +329,7 @@ class PeopleHandler(GenericHandler):
'last_name': person.last_name,
'display_name': person.display_name,
'usernames': [u.username for u in person.users],
'employee_uuid': person.employee.uuid if person.employee else None,
'member_uuids': [m.uuid for m in person.members],
}
@ -379,6 +381,9 @@ class PeopleHandler(GenericHandler):
merge happen.
:returns: String indicating reason not to merge, or ``None``.
"""
if removing.employee and keeping.employee:
if removing.employee is not keeping.employee:
return "Cannot merge 2 people who are distinct employees"
def perform_merge(self, removing, keeping, **kwargs):
"""