Skip to content

Commit 942200b

Browse files
relroddmzoneill
authored andcommitted
Store essential SAML attrs by default
Signed-off-by: Rick Elrod <[email protected]>
1 parent 4bcccce commit 942200b

File tree

2 files changed

+104
-0
lines changed
  • ansible_base/authentication/authenticator_plugins
  • test_app/tests/authentication/authenticator_plugins

2 files changed

+104
-0
lines changed

ansible_base/authentication/authenticator_plugins/saml.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,24 @@ def extra_data(self, user, backend, response, *args, **kwargs):
296296
if "Group" in attrs:
297297
response["Group"] = attrs["Group"]
298298
data = super().extra_data(user, backend, response, *args, **kwargs)
299+
300+
# Ideally we would always have a DB instance
301+
# But if something was mocked in a test or somehow a db_instance just wasn't past in we don't want to error here
302+
if self.database_instance is None:
303+
return data
304+
305+
# The fields we want in extra get embedded into the ENABLED_IDPS field so we need to get them out from there
306+
idp_data = self.database_instance.configuration.get('ENABLED_IDPS', {}).get(idp_string, {})
307+
308+
# We are going to auto-include all of the fields like USER_FIRST_NAME, USER_EMAIL, etc.
309+
for field, attr_name in SAMLConfiguration.settings_to_enabled_idps_fields.items():
310+
if field in ('IDP_URL', 'IDP_X509_CERT', 'IDP_ENTITY_ID'):
311+
continue
312+
313+
field_name = idp_data.get(attr_name, None)
314+
if field_name in attrs:
315+
data[field_name] = attrs[field_name]
316+
299317
return data
300318

301319
def get_user_groups(self, extra_groups=[]):

test_app/tests/authentication/authenticator_plugins/test_saml.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from types import SimpleNamespace
12
from unittest import mock
23

34
import pytest
@@ -213,6 +214,91 @@ def __init__(self):
213214
assert "mygroup" in rDict["Group"]
214215

215216

217+
@pytest.mark.django_db
218+
@pytest.mark.parametrize(
219+
"idp_fields,expected_results",
220+
[
221+
(
222+
{
223+
'attr_email': 'email',
224+
'attr_groups': 'Groups',
225+
'attr_username': 'username',
226+
'attr_last_name': 'last_name',
227+
'attr_first_name': 'first_name',
228+
'attr_user_permanent_id': 'name_id',
229+
},
230+
{
231+
'email': ['[email protected]'],
232+
'last_name': ['Admin'],
233+
'username': ['gateway_admin'],
234+
'first_name': ['Gateway'],
235+
'name_id': 'gateway_admin',
236+
},
237+
),
238+
(
239+
{
240+
'attr_email': 'not_email',
241+
'attr_groups': 'Groups',
242+
'attr_username': 'username',
243+
'attr_last_name': 'last_name',
244+
'attr_first_name': 'first_name',
245+
'attr_user_permanent_id': 'name_id',
246+
},
247+
{
248+
'last_name': ['Admin'],
249+
'username': ['gateway_admin'],
250+
'first_name': ['Gateway'],
251+
'name_id': 'gateway_admin',
252+
},
253+
),
254+
(
255+
{
256+
'attr_username': 'username',
257+
'attr_last_name': 'last_name',
258+
'attr_first_name': 'first_name',
259+
'attr_user_permanent_id': 'name_id',
260+
},
261+
{
262+
'last_name': ['Admin'],
263+
'username': ['gateway_admin'],
264+
'first_name': ['Gateway'],
265+
'name_id': 'gateway_admin',
266+
},
267+
),
268+
],
269+
)
270+
def test_extra_data_default_attrs(idp_fields, expected_results):
271+
from ansible_base.authentication.authenticator_plugins.saml import idp_string
272+
from ansible_base.authentication.models import AuthenticatorUser
273+
274+
ap = AuthenticatorPlugin()
275+
database_instance = SimpleNamespace()
276+
enabled_idps = {
277+
'ENABLED_IDPS': {
278+
idp_string: idp_fields,
279+
}
280+
}
281+
database_instance.configuration = enabled_idps
282+
ap.database_instance = database_instance
283+
284+
response = {
285+
'idp_name': 'IdP',
286+
'attributes': {
287+
'email': ['[email protected]'],
288+
'last_name': ['Admin'],
289+
'is_superuser': ['true'],
290+
'username': ['gateway_admin'],
291+
'first_name': ['Gateway'],
292+
'Role': ['default-roles-gateway realm', 'manage-account', 'uma_authorization', 'view-profile', 'offline_access', 'manage-account-links'],
293+
'name_id': 'gateway_admin',
294+
},
295+
}
296+
au = AuthenticatorUser()
297+
with mock.patch('social_core.backends.saml.SAMLAuth.extra_data', return_value={}):
298+
results = ap.extra_data(None, 'IdP:gateway_admin', response, **{'social': au})
299+
assert results == expected_results
300+
301+
216302
def test_saml_create_via_api_without_callback_url(admin_api_client, saml_configuration):
217303
del saml_configuration['CALLBACK_URL']
218304

0 commit comments

Comments
 (0)