From 6f94d387640d4176765747a5962e9778a81f4886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 6 Mar 2019 13:08:46 +0100 Subject: [PATCH] keep local cache of fedict metadata (#31128) --- src/authentic2_auth_fedict/adapters.py | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/authentic2_auth_fedict/adapters.py b/src/authentic2_auth_fedict/adapters.py index 28fc62a..ffbf2db 100644 --- a/src/authentic2_auth_fedict/adapters.py +++ b/src/authentic2_auth_fedict/adapters.py @@ -15,15 +15,20 @@ # along with this program. If not, see . import datetime +import hashlib import logging +import os + import requests from django.conf import settings from django.contrib.auth import get_user_model +from django.core.files.storage import default_storage import lasso -from mellon.adapters import DefaultAdapter +from mellon.adapters import DefaultAdapter, app_settings +import mellon.utils as mellon_utils from authentic2.models import Attribute from authentic2 import utils from authentic2.a2_rbac.utils import get_default_ou @@ -46,6 +51,34 @@ class AuthenticAdapter(DefaultAdapter): def auth_login(self, request, user): utils.login(request, user, 'fedict') + def get_identity_providers_setting(self): + providers = app_settings.IDENTITY_PROVIDERS + cache_path = default_storage.path('fedict-cache') + if not os.path.exists(cache_path): + os.makedirs(cache_path) + for idp in providers: + if 'METADATA_URL' in idp and 'METADATA' not in idp: + url_hash = hashlib.sha1(idp['METADATA_URL']).hexdigest() + metadata_cache_filename = os.path.join(cache_path, url_hash) + if os.path.exists(metadata_cache_filename): + stat_info = os.stat(metadata_cache_filename) + if stat_info.st_size and stat_info.st_mtime > (time.time() - 86400): + idp['METADATA'] = open(metadata_cache_filename).read().decode('utf-8') + continue + verify_ssl_certificate = mellon_utils.get_setting(idp, 'VERIFY_SSL_CERTIFICATE') + try: + response = requests.get(idp['METADATA_URL'], verify=verify_ssl_certificate) + response.raise_for_status() + except requests.exceptions.RequestException as e: + if os.path.exists(metadata_cache_filename): + # accept older cache in case of error + idp['METADATA'] = open(metadata_cache_filename).read().decode('utf-8') + continue + idp['METADATA'] = response.text + with open(metadata_cache_filename, 'w') as fd: + fd.write(response.text.encode('utf-8')) + return providers + def lookup_user(self, idp, saml_attributes): if 'email' in saml_attributes: # XXX: remove email from received attributes for now, this