diff --git a/auth_oidc/README.rst b/auth_oidc/README.rst index c4bac3fb3c..df52d5a34a 100644 --- a/auth_oidc/README.rst +++ b/auth_oidc/README.rst @@ -7,7 +7,7 @@ Authentication OpenID Connect !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:71510d7bf0aa7f001922c23a7610ad556deef38538d265989fb70ddc010547d6 + !! source digest: sha256:c0b511a2aa2ce3715f6c903369015852d573c98a028d2d9919c6b789578e2d21 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/auth_oidc/static/description/index.html b/auth_oidc/static/description/index.html index 744d414d9c..fbe5ac27f1 100644 --- a/auth_oidc/static/description/index.html +++ b/auth_oidc/static/description/index.html @@ -366,7 +366,7 @@
This module allows users to login through an OpenID Connect provider using the
diff --git a/auth_saml/models/auth_saml_provider.py b/auth_saml/models/auth_saml_provider.py
index ccd36b1e92..85f6e316b9 100644
--- a/auth_saml/models/auth_saml_provider.py
+++ b/auth_saml/models/auth_saml_provider.py
@@ -9,13 +9,17 @@
import tempfile
import urllib.parse
+import requests
+
# dependency name is pysaml2 # pylint: disable=W7936
import saml2
import saml2.xmldsig as ds
from saml2.client import Saml2Client
from saml2.config import Config as Saml2Config
+from saml2.sigver import SignatureError
from odoo import api, fields, models
+from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
@@ -42,6 +46,14 @@ class AuthSamlProvider(models.Model):
),
required=True,
)
+ idp_metadata_url = fields.Char(
+ string="Identity Provider Metadata URL",
+ help="Some SAML providers, notably Office365 can have a metadata "
+ "document which changes over time, and they provide a URL to the "
+ "document instead. When this field is set, the metadata can be "
+ "fetched from the provided URL.",
+ )
+
sp_baseurl = fields.Text(
string="Override Base URL",
help="""Base URL sent to Odoo with this, rather than automatically
@@ -282,11 +294,24 @@ def _validate_auth_response(self, token: str, base_url: str = None):
self.ensure_one()
client = self._get_client_for_provider(base_url)
- response = client.parse_authn_request_response(
- token,
- saml2.entity.BINDING_HTTP_POST,
- self._get_outstanding_requests_dict(),
- )
+ try:
+ response = client.parse_authn_request_response(
+ token,
+ saml2.entity.BINDING_HTTP_POST,
+ self._get_outstanding_requests_dict(),
+ )
+ except SignatureError:
+ # we have a metadata url: try to refresh the metadata document
+ if self.idp_metadata_url:
+ self.action_refresh_metadata_from_url()
+ # retry: if it fails again, we let the exception flow
+ response = client.parse_authn_request_response(
+ token,
+ saml2.entity.BINDING_HTTP_POST,
+ self._get_outstanding_requests_dict(),
+ )
+ else:
+ raise
matching_value = None
if self.matching_attribute == "subject.nameId":
@@ -370,3 +395,28 @@ def _hook_validate_auth_response(self, response, matching_value):
vals[attribute.field_name] = attribute_value
return {"mapped_attrs": vals}
+
+ def action_refresh_metadata_from_url(self):
+ providers = self.search(
+ [("idp_metadata_url", "ilike", "http%"), ("id", "in", self.ids)]
+ )
+ if not providers:
+ return False
+ # lock the records we might update, so that multiple simultaneous login
+ # attempts will not cause concurrent updates
+ self.env.cr.execute(
+ "SELECT id FROM auth_saml_provider WHERE id in %s FOR UPDATE",
+ (list(providers.ids),),
+ )
+ updated = False
+ for provider in providers:
+ document = requests.get(provider.idp_metadata_url)
+ if document.status_code != 200:
+ raise UserError(
+ f"Unable to download the metadata for {provider.name}: {document.reason}"
+ )
+ if document.text != provider.idp_metadata:
+ provider.idp_metadata = document.text
+ _logger.info("Updated provider metadata for %s", provider.name)
+ updated = True
+ return updated
diff --git a/auth_saml/views/auth_saml.xml b/auth_saml/views/auth_saml.xml
index 960905213b..c9c5926cec 100644
--- a/auth_saml/views/auth_saml.xml
+++ b/auth_saml/views/auth_saml.xml
@@ -76,6 +76,15 @@