2
0
Fork 0

fix: make AuthHandler.get_user() do lookups for uuid, username

This commit is contained in:
Lance Edgar 2024-07-17 17:46:13 -05:00
parent ca997807e4
commit 86997397de
2 changed files with 44 additions and 6 deletions

View file

@ -133,7 +133,7 @@ class AuthHandler(GenericHandler):
if key: if key:
return self.get_role(session, key) return self.get_role(session, key)
def get_user(self, obj, **kwargs): def get_user(self, obj, session=None, **kwargs):
""" """
Return the :class:`~wuttjamaican.db.model.auth.User` Return the :class:`~wuttjamaican.db.model.auth.User`
associated with the given object, if one can be found. associated with the given object, if one can be found.
@ -143,19 +143,49 @@ class AuthHandler(GenericHandler):
"first, most obvious" user in the event that the given object "first, most obvious" user in the event that the given object
is associated with multiple users. is associated with multiple users.
The default logic only knows how to navigate the Person/User For instance ``obj`` may be a string in which case a lookup
relationship, so if ``obj`` is a may be tried on
:class:`~wuttjamaican.db.model.base.Person` then it will :attr:`~wuttjamaican.db.model.auth.User.username`. Or it may
return the "first" user account for the person (according to be a :class:`~wuttjamaican.db.model.base.Person` in which case
:attr:`~wuttjamaican.db.model.base.Person.user`). their :attr:`~wuttjamaican.db.model.base.Person.user` may be
returned.
:param obj: Object for which user should be returned.
:param session: Open :term:`db session`. This is optional in
some cases, i.e. one can be determined automatically if
``obj`` is some kind of object already contained in a
session (e.g. ``Person``). But a ``session`` must be
provided if ``obj`` is a simple string and you need to do a
lookup by username etc.
:returns: :class:`~wuttjamaican.db.model.auth.User` or ``None``. :returns: :class:`~wuttjamaican.db.model.auth.User` or ``None``.
""" """
model = self.app.model model = self.app.model
# maybe obj is already a user
if isinstance(obj, model.User): if isinstance(obj, model.User):
return obj return obj
# or maybe it is a string
# (nb. these lookups require a db session)
if isinstance(obj, str) and session:
# try to match on User.uuid
user = session.get(model.User, obj)
if user:
return user
# try to match on User.username
user = session.query(model.User)\
.filter(model.User.username == obj)\
.first()
if user:
return user
# nb. obj is presumbly another type of object, e.g. Person
# maybe we can find a person, then get user
person = self.app.get_person(obj) person = self.app.get_person(obj)
if person: if person:
return person.user return person.user

View file

@ -102,6 +102,14 @@ else:
user = self.handler.get_user(myuser) user = self.handler.get_user(myuser)
self.assertIs(user, myuser) self.assertIs(user, myuser)
# match on User.uuid
user = self.handler.get_user(myuser.uuid, session=self.session)
self.assertIs(user, myuser)
# match on User.username
user = self.handler.get_user(myuser.username, session=self.session)
self.assertIs(user, myuser)
# find user from person # find user from person
myperson = model.Person(full_name='My Name') myperson = model.Person(full_name='My Name')
self.session.add(myperson) self.session.add(myperson)