Skip to content

Commit

Permalink
Patron authentication providers know their lookup provider.
Browse files Browse the repository at this point in the history
  • Loading branch information
tdilauro committed Sep 20, 2023
1 parent 33c58b9 commit 1d07982
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 18 deletions.
8 changes: 8 additions & 0 deletions api/authentication/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ def identifies_individuals(self):
# it should override this value and set it to False.
...

@property
def patron_lookup_provider(self):
"""Return the provider responsible for patron lookup.
By default, we'll put ourself forward for this task.
"""
return self

@abstractmethod
def authenticated_patron(
self, _db: Session, header: dict | str
Expand Down
4 changes: 4 additions & 0 deletions api/authentication/basic_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ def __init__(
# An access token provider is a companion authentication to the basic providers
self.basic_provider = basic_provider

@property
def patron_lookup_provider(self):
return self.basic_provider

def authenticated_patron(
self, _db: Session, token: dict | str
) -> Patron | ProblemDetail | None:
Expand Down
33 changes: 15 additions & 18 deletions api/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,32 +428,29 @@ def providers(self) -> Iterable[AuthenticationProvider]:
yield self.basic_auth_provider
yield from self.saml_providers_by_name.values()

def _unique_basic_lookup_providers(
self, auth_providers: Iterable[AuthenticationProvider | None]
) -> Iterable[AuthenticationProvider]:
providers: filter[AuthenticationProvider] = filter(
None,
(p.patron_lookup_provider for p in auth_providers if p is not None),
)
# De-dupe, but preserve provider order.
return dict.fromkeys(list(providers)).keys()

@property
def unique_patron_lookup_providers(self) -> Iterable[AuthenticationProvider]:
"""Iterator over unique patron data providers for registered AuthenticationProviders.
We want to these providers to be unique to avoid performing the same
lookup multiple times. Otherwise, this would be likely to happen when
the lookup failed for a given provider.
We want a unique list of providers in order to avoid hitting the same
provider multiple times, most likely in the case of failing lookups.
"""

# For `BasicTokenAuthenticationProvider`s, the lookup provider is
# its `basic_provider`. `BasicAuthenticationProvider`s are their
# own lookup providers.
basic_providers = filter(
None,
yield from self._unique_basic_lookup_providers(
[
(
self.access_token_authentication_provider.basic_provider
if self.access_token_authentication_provider
else None
),
self.access_token_authentication_provider,
self.basic_auth_provider,
],
]
)
# De-dupe, but preserve provider order.
unique_basic_provider = dict.fromkeys(basic_providers)
yield from unique_basic_provider
yield from self.saml_providers_by_name.values()

def authenticated_patron(
Expand Down

0 comments on commit 1d07982

Please sign in to comment.