From 7640a819f72116cda21233d610da1c35a26ab248 Mon Sep 17 00:00:00 2001 From: Elwin Arens Date: Thu, 21 Jun 2018 13:46:58 +0200 Subject: [PATCH] Opt move cookie init to backend and add optional ignore connection error --- django_crowd_auth/backends.py | 30 ++++++++++++++++++++---------- django_crowd_auth/client.py | 13 ++++++++++--- django_crowd_auth/middlewares.py | 21 +++++++++++---------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/django_crowd_auth/backends.py b/django_crowd_auth/backends.py index ba04db5..dc914bd 100644 --- a/django_crowd_auth/backends.py +++ b/django_crowd_auth/backends.py @@ -7,6 +7,7 @@ from django_crowd_auth.client import Client from django_crowd_auth import user +from requests.exceptions import ConnectionError LOGGER = logging.getLogger(__name__) @@ -19,16 +20,25 @@ class Backend(ModelBackend): def authenticate(self, request, **credentials): """Authenticate an user. """ - client = Client.from_settings() - remote_addr = request.META['REMOTE_ADDR'] - - if 'token' in credentials: - session = client.validate_session( - credentials['token'], remote_addr) - elif 'username' in credentials and 'password' in credentials: - session = client.get_session( - credentials['username'], credentials['password'], remote_addr) - else: + + try: + # Only try and init cookie config if it is None + client = Client.from_settings() + if client.cookie_config is None: + client.init_cookie_config() + + remote_addr = request.META['REMOTE_ADDR'] + if 'token' in credentials: + session = client.validate_session( + credentials['token'], remote_addr) + elif 'username' in credentials and 'password' in credentials: + session = client.get_session( + credentials['username'], credentials['password'], + remote_addr) + except ConnectionError as ex: + LOGGER.exception(ex) + if getattr(settings, 'CROWD_RAISE_CONNECTION_ERROR', True): + raise ex session = None if session: diff --git a/django_crowd_auth/client.py b/django_crowd_auth/client.py index 3ba84f7..5c7b215 100644 --- a/django_crowd_auth/client.py +++ b/django_crowd_auth/client.py @@ -6,14 +6,21 @@ class Client(crowd.CrowdServer): """Crowd client. """ - def get_cookie_config(self): + cookie_config = None + + def init_cookie_config(self): """Get Crowd's cookie configuration. """ url = self.rest_url + '/config/cookie.json' response = self._get(url) - if response.ok: - return response.json() + Client.cookie_config = self.cookie_config = response.json() + assert 'domain' in self.cookie_config, \ + 'Missing crowd cookie config property domain' + assert 'name' in self.cookie_config, \ + 'Missing crowd cookie config property name' + assert 'secure' in self.cookie_config, \ + 'Missing crowd cookie config property secure' @classmethod def from_settings(cls): diff --git a/django_crowd_auth/middlewares.py b/django_crowd_auth/middlewares.py index 064dcbc..e7a0483 100644 --- a/django_crowd_auth/middlewares.py +++ b/django_crowd_auth/middlewares.py @@ -13,16 +13,15 @@ def sso(get_response): """Crowd SSO middleware. """ - client = Client.from_settings() - cookie_config = client.get_cookie_config() - cookie_name = cookie_config['name'] - cookie_domain = cookie_config['domain'] - cookie_secure = cookie_config['secure'] - LOGGER.debug('Crowd cookie config %r', cookie_config) def middleware(request): """Authenticate users having a Crowd cookie. """ + if Client.cookie_config is None: + return get_response(request) + + cookie_config = Client.cookie_config + crowd_session_last_validation = \ request.session.get('crowd_session_last_validation') @@ -40,7 +39,7 @@ def middleware(request): request.user.username) logout(request) - cookie_token = request.COOKIES.get(cookie_name) + cookie_token = request.COOKIES.get(cookie_config.get('name')) if not request.user.is_authenticated and cookie_token: LOGGER.debug('Trying to auth from cookie %s', cookie_token) @@ -60,13 +59,15 @@ def middleware(request): cookie_token = request.session['crowd_session_token'] response.set_cookie( - key=cookie_name, value=cookie_token, + key=cookie_config.get('name'), value=cookie_token, max_age=None, expires=crowd_session_expiry, path='/', - domain=cookie_domain, secure=cookie_secure, httponly=True) + domain=cookie_config.get('domain'), + secure=cookie_config.get('secure'), httponly=True) else: response.delete_cookie( - key=cookie_name, path='/', domain=cookie_domain) + key=cookie_config.get('name'), path='/', + domain=cookie_config.get('domain')) return response