From 4d875f8c8f8260ddd3a7cd57d390983761821eea Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 21 Oct 2013 22:41:31 +0200 Subject: [PATCH 6/6] qommon.saml2: use new idp settings to fill user attribute at SAML 2 login fixes #3852 --- wcs/qommon/saml2.ptl | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/wcs/qommon/saml2.ptl b/wcs/qommon/saml2.ptl index b299fa5..9a2626c 100644 --- a/wcs/qommon/saml2.ptl +++ b/wcs/qommon/saml2.ptl @@ -91,6 +91,11 @@ def saml2_status_summary(response): code += ':' + response.status.statusCode.statusCode.value return code +def get_remote_provider_cfg(profile): + '''Lookup the configuration for a remote provider given a profile''' + remote_provider_key = misc.get_provider_key(profile.remoteProviderId) + return get_cfg('idp', {}).get(remote_provider_key) + class Saml2Directory(Directory): _q_exports = ['login', 'singleSignOnArtifact', 'singleSignOnPost', 'singleSignOnSOAP', 'singleSignOnRedirect', @@ -353,6 +358,59 @@ class Saml2Directory(Directory): return error_page(_('Unknown error')) return self.sso_after_response(login) + def fill_user_attributes(self, session, login, user): + '''Fill user fields from SAML2 assertion attributes''' + logger = get_logger() + + save = False + idp = get_remote_provider_cfg(login) + # lookup for attributes in assertion and automatically create identity + lasso_session = lasso.Session.newFromDump(session.lasso_session_dump) + try: + assertion = lasso_session.getAssertions(None)[0] + except: + get_logger().warn('failed to lookup assertion') + return user + + d = {} + m = {} + try: + for attribute in assertion.attributeStatement[0].attribute: + try: + d[attribute.name] = attribute.attributeValue[0].any[0].content + for attribute_value in attribute.attributeValue: + l = m.setdefault(attribute.name, []) + l.append(attribute_value.any[0].content) + except IndexError: + pass + except IndexError: + pass + logger.debug('fill_user_attributes: received attributes %r', m) + admin_attributes = idp.get('admin-attributes') or {} + if admin_attributes: + is_admin = False + for key, matching_value in admin_attributes.iteritems(): + for value in m.get(key, []): + if value == matching_value: + is_admin = True + if user.is_admin != is_admin: + user.is_admin = is_admin + if user.is_admin: + logger.info('giving user %s the admin rights', user.id) + else: + logger.info('taking user %s the admin rights', user.id) + save = True + attribute_mapping = idp.get('attribute-mapping') or {} + if user.form_data is None: + user.form_data = {} + for key, field_id in attribute_mapping.iteritems(): + if key in d and user.form_data.get(field_id) != d[key]: + user.form_data[field_id] = d[key] + logger.info('setting field %s of user %s to value %r', field_id, user.id, d[key]) + save = True + if save: + user.store() + def lookup_user(self, session, login = None, name_id = None): if login: ni = login.nameIdentifier.content @@ -380,6 +438,8 @@ class Saml2Directory(Directory): user.lasso_dump = login.identity.dump() user.store() + self.fill_user_attributes(session, login, user) + return user def slo_sp(self, method = None): -- 1.7.10.4