Skip to content
Snippets Groups Projects
Commit d67d84c6ebc0 authored by Florent Aide's avatar Florent Aide
Browse files

implement real attribute matching instead of using subject.nameId.content for everything

parent 010cf843cdd9
No related branches found
No related tags found
No related merge requests found
......@@ -33,6 +33,16 @@
return lasso.Login(server)
@api.multi
def _get_matching_attr_for_provider(self):
"""internal helper to fetch the matching attribute for this SAML
provider. Returns a unicode object.
"""
self.ensure_one()
return self.matching_attribute
@api.multi
def _get_auth_request(self, state):
"""build an authentication request and give it back to our client
WARNING: this method cannot be used for multiple ids
......@@ -58,6 +68,11 @@
sp_pkey = fields.Text(
'Private key of our service provider (this openerpserver)'
)
matching_attribute = fields.Text(
string='Matching Attribute',
default='subject.nameId',
required=True,
),
enabled = fields.Boolean('Enabled', default=False)
sequence = fields.Integer('Sequence')
css_class = fields.Char('CSS Class')
......
......@@ -72,6 +72,7 @@
# we are not yet logged in, so the userid cannot have access to the
# fields we need yet
login = p.sudo()._get_lasso_for_provider()
matching_attribute = p._get_matching_attr_for_provider()
try:
login.processAuthnResponseMsg(token)
......@@ -79,8 +80,8 @@
raise Exception('Lasso Profile cannot verify signature')
except lasso.ProfileStatusNotSuccessError:
raise Exception('Profile Status Not Success Error')
except lasso.Error, e:
except lasso.Error as e:
raise Exception(repr(e))
try:
login.acceptSso()
......@@ -83,7 +84,11 @@
raise Exception(repr(e))
try:
login.acceptSso()
except lasso.Error:
raise Exception('Invalid assertion')
except lasso.Error as error:
raise Exception(
'Invalid assertion : %s' % lasso.strError(error[0])
)
attrs = {}
......@@ -89,7 +94,62 @@
# TODO use a real token validation from LASSO
# TODO push into the validation result a real UPN
return {'user_id': login.assertion.subject.nameId.content}
for att_statement in login.assertion.attributeStatement:
for attribute in att_statement.attribute:
name = None
lformat = lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC
nickname = None
try:
name = attribute.name.decode('ascii')
except Exception as e:
_logger.warning('sso_after_response: error decoding name of \
attribute %s' % attribute.dump())
else:
try:
if attribute.nameFormat:
lformat = attribute.nameFormat.decode('ascii')
if attribute.friendlyName:
nickname = attribute.friendlyName
except Exception as e:
message = 'sso_after_response: name or format of an \
attribute failed to decode as ascii: %s due to %s'
_logger.warning(message % (attribute.dump(), str(e)))
try:
if name:
if lformat:
if nickname:
key = (name, lformat, nickname)
else:
key = (name, lformat)
else:
key = name
attrs[key] = list()
for value in attribute.attributeValue:
content = [a.exportToXml() for a in value.any]
content = ''.join(content)
attrs[key].append(content.decode('utf8'))
except Exception as e:
message = 'sso_after_response: value of an \
attribute failed to decode as ascii: %s due to %s'
_logger.warning(message % (attribute.dump(), str(e)))
matching_value = None
for k in attrs:
if isinstance(k, tuple) and k[0] == matching_attribute:
matching_value = attrs[k][0]
break
if not matching_value and matching_attribute == "subject.nameId":
matching_value = login.assertion.subject.nameId.content
elif not matching_value and matching_attribute != "subject.nameId":
raise Exception(
"Matching attribute %s not found in user attrs: %s" % (
matching_attribute,
attrs,
)
)
validation = {'user_id': matching_value}
return validation
@api.multi
def _auth_saml_signin(self, provider, validation, saml_response):
......
......@@ -43,6 +43,7 @@
<field name="name" />
<field name="enabled" />
<field name="body" />
<field name="matching_attribute" />
</group>
<group>
<field name="idp_metadata" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment