Source code for api.simple_authentication
from flask_babel import lazy_gettext as _
from .authenticator import (
BasicAuthenticationProvider,
PatronData,
)
from .config import (
CannotLoadConfiguration,
)
from core.model import Patron
[docs]class SimpleAuthenticationProvider(BasicAuthenticationProvider):
"""An authentication provider that authenticates a single patron.
This serves only one purpose: to set up a working circulation
manager before connecting it to an ILS.
"""
NAME = "Simple Authentication Provider"
DESCRIPTION = _("""
An internal authentication service that authenticates a single patron.
This is useful for testing a circulation manager before connecting
it to an ILS.""")
ADDITIONAL_TEST_IDENTIFIERS = 'additional_test_identifiers'
TEST_NEIGHBORHOOD = 'neighborhood'
basic_settings = list(BasicAuthenticationProvider.SETTINGS)
for i, setting in enumerate(basic_settings):
if setting['key'] == BasicAuthenticationProvider.TEST_IDENTIFIER:
s = dict(**setting)
s['description'] = BasicAuthenticationProvider.TEST_IDENTIFIER_DESCRIPTION_FOR_REQUIRED_PASSWORD
basic_settings[i] = s
elif setting['key'] == BasicAuthenticationProvider.TEST_PASSWORD:
s = dict(**setting)
s['required'] = True
s['description'] = BasicAuthenticationProvider.TEST_PASSWORD_DESCRIPTION_REQUIRED
basic_settings[i] = s
SETTINGS = basic_settings + [
{ "key": ADDITIONAL_TEST_IDENTIFIERS,
"label": _("Additional test identifiers"),
"type": "list",
"description": _("Identifiers for additional patrons to use in testing. The identifiers will all use the same test password as the first identifier."),
},
{ "key": TEST_NEIGHBORHOOD,
"label": _("Test neighborhood"),
"description": _("For analytics purposes, all patrons will be 'from' this neighborhood."),
}
]
def __init__(self, library, integration, analytics=None):
super(SimpleAuthenticationProvider, self).__init__(
library, integration, analytics
)
self.test_password = integration.setting(self.TEST_PASSWORD).value
test_identifier = integration.setting(self.TEST_IDENTIFIER).value
if not (test_identifier and self.test_password):
raise CannotLoadConfiguration(
"Test identifier and password not set."
)
self.test_identifiers = [test_identifier, test_identifier + "_username"]
additional_identifiers = integration.setting(self.ADDITIONAL_TEST_IDENTIFIERS).json_value
if additional_identifiers:
for identifier in additional_identifiers:
self.test_identifiers += [identifier, identifier + "_username"]
self.test_neighborhood = integration.setting(self.TEST_NEIGHBORHOOD).value or None
[docs] def remote_authenticate(self, username, password):
"Fake 'remote' authentication."
if not username or (self.collects_password and not password):
return None
if not self.valid_patron(username, password):
return None
return self.generate_patrondata(username, self.test_neighborhood)
[docs] @classmethod
def generate_patrondata(cls, authorization_identifier, neighborhood=None):
if authorization_identifier.endswith("_username"):
username = authorization_identifier
identifier = authorization_identifier[:-9]
else:
identifier = authorization_identifier
username = authorization_identifier + "_username"
personal_name = "PersonalName" + identifier
patrondata = PatronData(
authorization_identifier=identifier,
permanent_id=identifier + "_id",
username=username,
personal_name=personal_name,
authorization_expires = None,
fines = None,
neighborhood=neighborhood,
)
return patrondata
# End implementation of BasicAuthenticationProvider abstract
# methods.
[docs] def valid_patron(self, username, password):
"""Is this patron associated with the given password in
the given dictionary?
"""
if self.collects_password:
password_match = (password==self.test_password)
else:
password_match = (password in (None, ''))
return password_match and username in self.test_identifiers
def _remote_patron_lookup(self, patron_or_patrondata):
if not patron_or_patrondata:
return None
if ((isinstance(patron_or_patrondata, PatronData)
or isinstance(patron_or_patrondata, Patron))
and patron_or_patrondata.authorization_identifier in self.test_identifiers):
return self.generate_patrondata(patron_or_patrondata.authorization_identifier)
AuthenticationProvider = SimpleAuthenticationProvider