@@ -214,10 +214,16 @@ def _translate_response(self, response, state):
214
214
issuer = response .response .issuer .text
215
215
216
216
auth_info = AuthenticationInformation (auth_class_ref , timestamp , issuer )
217
- internal_resp = InternalResponse (auth_info = auth_info )
217
+ internal_resp = SAMLInternalResponse (auth_info = auth_info )
218
218
219
219
internal_resp .user_id = response .get_subject ().text
220
220
internal_resp .attributes = self .converter .to_internal (self .attribute_profile , response .ava )
221
+
222
+ # The SAML response may not include a NameID
223
+ try :
224
+ internal_resp .name_id = response .assertion .subject .name_id
225
+ except AttributeError :
226
+ pass
221
227
222
228
satosa_logging (logger , logging .DEBUG , "received attributes:\n %s" % json .dumps (response .ava , indent = 4 ), state )
223
229
return internal_resp
@@ -315,3 +321,32 @@ def get_metadata_desc(self):
315
321
316
322
entity_descriptions .append (description )
317
323
return entity_descriptions
324
+
325
+ class SAMLInternalResponse (InternalResponse ):
326
+ """
327
+ Like the parent InternalResponse, holds internal representation of
328
+ service related data, but includes additional details relevant to
329
+ SAML interoperability.
330
+
331
+ :type name_id: instance of saml2.saml.NameID from pysaml2
332
+ """
333
+ def __init__ (self , auth_info = None ):
334
+ super ().__init__ (auth_info )
335
+
336
+ self .name_id = None
337
+
338
+ def to_dict (self ):
339
+ """
340
+ Converts a SAMLInternalResponse object to a dict
341
+ :rtype: dict[str, dict[str, str] | str]
342
+ :return: A dict representation of the object
343
+ """
344
+ _dict = super ().to_dict ()
345
+
346
+ if self .name_id :
347
+ _dict ['name_id' ] = {self .name_id .format : self .name_id .text }
348
+ else :
349
+ _dict ['name_id' ] = None
350
+
351
+ return _dict
352
+
0 commit comments