Compare commits

...

2 Commits

Author SHA1 Message Date
semantic-release-bot 5e83b9f43a chore(release): 8.2.1 [skip ci]
## [8.2.1](https://github.com/mediacms-io/mediacms/compare/v8.2.0...v8.2.1) (2026-06-07)

### Bug Fixes

* SAML provider add guard to skip empty mappings before iterating ([#1536](https://github.com/mediacms-io/mediacms/issues/1536)) ([9da6a85](https://github.com/mediacms-io/mediacms/commit/9da6a85ad86f5092edb96495eeb1cca22d5334bf))
2026-06-07 14:55:57 +00:00
Markos Gogoulos 9da6a85ad8 fix: SAML provider add guard to skip empty mappings before iterating (#1536) 2026-06-07 17:55:32 +03:00
5 changed files with 30 additions and 7 deletions
+6
View File
@@ -1,5 +1,11 @@
# Changelog # Changelog
## [8.2.1](https://github.com/mediacms-io/mediacms/compare/v8.2.0...v8.2.1) (2026-06-07)
### Bug Fixes
* SAML provider add guard to skip empty mappings before iterating ([#1536](https://github.com/mediacms-io/mediacms/issues/1536)) ([9da6a85](https://github.com/mediacms-io/mediacms/commit/9da6a85ad86f5092edb96495eeb1cca22d5334bf))
## [8.2.0](https://github.com/mediacms-io/mediacms/compare/v8.1.3...v8.2.0) (2026-05-31) ## [8.2.0](https://github.com/mediacms-io/mediacms/compare/v8.1.3...v8.2.0) (2026-05-31)
### Features ### Features
+1 -1
View File
@@ -1 +1 @@
VERSION = "8.2.0" VERSION = "8.2.1"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "mediacms", "name": "mediacms",
"version": "8.2.0", "version": "8.2.1",
"devDependencies": { "devDependencies": {
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
+7 -4
View File
@@ -73,7 +73,7 @@ def perform_user_actions(user, social_account, common_fields=None):
if social_app: if social_app:
saml_configuration = social_app.saml_configurations.first() saml_configuration = social_app.saml_configurations.first()
add_user_logo(user, extra_data) add_user_logo(user, extra_data, saml_configuration)
handle_role_mapping(user, extra_data, social_app, saml_configuration) handle_role_mapping(user, extra_data, social_app, saml_configuration)
if saml_configuration and saml_configuration.save_saml_response_logs: if saml_configuration and saml_configuration.save_saml_response_logs:
handle_saml_logs_save(user, extra_data, social_app) handle_saml_logs_save(user, extra_data, social_app)
@@ -81,10 +81,13 @@ def perform_user_actions(user, social_account, common_fields=None):
return user return user
def add_user_logo(user, extra_data): def add_user_logo(user, extra_data, saml_configuration=None):
# use the attribute name configured in the SAML Configuration, falling
# back to "jpegPhoto" when it is left empty
logo_key = (saml_configuration.user_logo if saml_configuration and saml_configuration.user_logo else None) or "jpegPhoto"
try: try:
if extra_data.get("jpegPhoto") and user.logo.name in ["userlogos/user.jpg", "", None]: if extra_data.get(logo_key) and user.logo.name in ["userlogos/user.jpg", "", None]:
base64_string = extra_data.get("jpegPhoto")[0] base64_string = extra_data.get(logo_key)[0]
image_data = base64.b64decode(base64_string) image_data = base64.b64decode(base64_string)
image_content = ContentFile(image_data) image_content = ContentFile(image_data)
user.logo.save('user.jpg', image_content, save=True) user.logo.save('user.jpg', image_content, save=True)
+15 -1
View File
@@ -18,14 +18,28 @@ class CustomSAMLProvider(SAMLProvider):
provider_config = self.app.settings provider_config = self.app.settings
raw_attributes = data.get_attributes() raw_attributes = data.get_attributes()
# get_attributes() keys attributes by their full Name. Some IdPs send
# certain attributes only under their FriendlyName, so fall back to the
# FriendlyName-keyed attributes when a Name lookup misses. The Name
# lookup is always preferred, so attributes that already resolve are
# unaffected.
try:
friendly_attributes = data.get_friendlyname_attributes()
except AttributeError:
friendly_attributes = {}
attributes = {} attributes = {}
attribute_mapping = provider_config.get("attribute_mapping", self.default_attribute_mapping) attribute_mapping = provider_config.get("attribute_mapping", self.default_attribute_mapping)
# map configured provider attributes # map configured provider attributes
for key, provider_keys in attribute_mapping.items(): for key, provider_keys in attribute_mapping.items():
# skip mappings left empty/None in the SAML Configuration
if not provider_keys:
continue
if isinstance(provider_keys, str): if isinstance(provider_keys, str):
provider_keys = [provider_keys] provider_keys = [provider_keys]
for provider_key in provider_keys: for provider_key in provider_keys:
attribute_list = raw_attributes.get(provider_key, None) attribute_list = raw_attributes.get(provider_key)
if attribute_list is None:
attribute_list = friendly_attributes.get(provider_key)
# if more than one keys, get them all comma separated # if more than one keys, get them all comma separated
if attribute_list is not None and len(attribute_list) > 1: if attribute_list is not None and len(attribute_list) > 1:
attributes[key] = ",".join(attribute_list) attributes[key] = ",".join(attribute_list)