Merge pull request #2558 from chrismeyersfsu/saml_admin_user_feature_cherry_pick

Saml admin user feature cherry pick
This commit is contained in:
Chris Meyers
2018-07-17 09:27:18 -04:00
committed by GitHub
4 changed files with 51 additions and 21 deletions

View File

@@ -1196,7 +1196,9 @@ register(
category_slug='saml', category_slug='saml',
placeholder=collections.OrderedDict([ placeholder=collections.OrderedDict([
('saml_attr', 'organization'), ('saml_attr', 'organization'),
('saml_admin_attr', 'organization_admin'),
('remove', True), ('remove', True),
('remove_admins', True),
]), ]),
feature_required='enterprise_auth', feature_required='enterprise_auth',
) )

View File

@@ -82,6 +82,33 @@ def _update_m2m_from_expression(user, rel, expr, remove=True):
rel.remove(user) rel.remove(user)
def _update_org_from_attr(user, rel, attr, remove, remove_admins):
from awx.main.models import Organization
multiple_orgs = feature_enabled('multiple_organizations')
org_ids = []
for org_name in attr:
if multiple_orgs:
org = Organization.objects.get_or_create(name=org_name)[0]
else:
try:
org = Organization.objects.order_by('pk')[0]
except IndexError:
continue
org_ids.append(org.id)
getattr(org, rel).members.add(user)
if remove:
[o.member_role.members.remove(user) for o in
Organization.objects.filter(Q(member_role__members=user) & ~Q(id__in=org_ids))]
if remove_admins:
[o.admin_role.members.remove(user) for o in
Organization.objects.filter(Q(admin_role__members=user) & ~Q(id__in=org_ids))]
def update_user_orgs(backend, details, user=None, *args, **kwargs): def update_user_orgs(backend, details, user=None, *args, **kwargs):
''' '''
Update organization memberships for the given user based on mapping rules Update organization memberships for the given user based on mapping rules
@@ -150,32 +177,19 @@ def update_user_teams(backend, details, user=None, *args, **kwargs):
def update_user_orgs_by_saml_attr(backend, details, user=None, *args, **kwargs): def update_user_orgs_by_saml_attr(backend, details, user=None, *args, **kwargs):
if not user: if not user:
return return
from awx.main.models import Organization
from django.conf import settings from django.conf import settings
multiple_orgs = feature_enabled('multiple_organizations')
org_map = settings.SOCIAL_AUTH_SAML_ORGANIZATION_ATTR org_map = settings.SOCIAL_AUTH_SAML_ORGANIZATION_ATTR
if org_map.get('saml_attr') is None: if org_map.get('saml_attr') is None and org_map.get('saml_admin_attr') is None:
return return
remove = bool(org_map.get('remove', True))
remove_admins = bool(org_map.get('remove_admins', True))
attr_values = kwargs.get('response', {}).get('attributes', {}).get(org_map['saml_attr'], []) attr_values = kwargs.get('response', {}).get('attributes', {}).get(org_map['saml_attr'], [])
attr_admin_values = kwargs.get('response', {}).get('attributes', {}).get(org_map['saml_admin_attr'], [])
org_ids = [] _update_org_from_attr(user, "member_role", attr_values, remove, False)
_update_org_from_attr(user, "admin_role", attr_admin_values, False, remove_admins)
for org_name in attr_values:
if multiple_orgs:
org = Organization.objects.get_or_create(name=org_name)[0]
else:
try:
org = Organization.objects.order_by('pk')[0]
except IndexError:
continue
org_ids.append(org.id)
org.member_role.members.add(user)
if org_map.get('remove', True):
[o.member_role.members.remove(user) for o in
Organization.objects.filter(Q(member_role__members=user) & ~Q(id__in=org_ids))]
def update_user_teams_by_saml_attr(backend, details, user=None, *args, **kwargs): def update_user_teams_by_saml_attr(backend, details, user=None, *args, **kwargs):

View File

@@ -149,6 +149,7 @@ class TestSAMLAttr():
'idp_name': u'idp', 'idp_name': u'idp',
'attributes': { 'attributes': {
'memberOf': ['Default1', 'Default2'], 'memberOf': ['Default1', 'Default2'],
'admins': ['Default3'],
'groups': ['Blue', 'Red'], 'groups': ['Blue', 'Red'],
'User.email': ['cmeyers@redhat.com'], 'User.email': ['cmeyers@redhat.com'],
'User.LastName': ['Meyers'], 'User.LastName': ['Meyers'],
@@ -176,7 +177,9 @@ class TestSAMLAttr():
class MockSettings(): class MockSettings():
SOCIAL_AUTH_SAML_ORGANIZATION_ATTR = { SOCIAL_AUTH_SAML_ORGANIZATION_ATTR = {
'saml_attr': 'memberOf', 'saml_attr': 'memberOf',
'saml_admin_attr': 'admins',
'remove': True, 'remove': True,
'remove_admins': True,
} }
SOCIAL_AUTH_SAML_TEAM_ATTR = { SOCIAL_AUTH_SAML_TEAM_ATTR = {
'saml_attr': 'groups', 'saml_attr': 'groups',

View File

@@ -21,18 +21,29 @@ Below is an example SAML attribute that embeds user organization membership in t
<saml2:AttributeValue>HR</saml2:AttributeValue> <saml2:AttributeValue>HR</saml2:AttributeValue>
<saml2:AttributeValue>Sales</saml2:AttributeValue> <saml2:AttributeValue>Sales</saml2:AttributeValue>
</saml2:Attribute> </saml2:Attribute>
<saml2:Attribute FriendlyName="administrator-of" Name="administrator-of" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue>IT</saml2:AttributeValue>
<saml2:AttributeValue>HR</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement> </saml2:AttributeStatement>
``` ```
Below, the corresponding AWX configuration. Below, the corresponding AWX configuration.
``` ```
{ {
"saml_attr": "member-of", "saml_attr": "member-of",
"remove": true "saml_admin_attr": "administrator-of",
"remove": true,
'remove_admins': true
} }
``` ```
**saml_attr:** The saml attribute name where the organization array can be found. **saml_attr:** The saml attribute name where the organization array can be found.
**remove:** True to remove user from all organizations before adding the user to the list of Organizations. False to keep the user in whatever Organization(s) they are in while adding the user to the Organization(s) in the SAML attribute. **remove:** True to remove user from all organizations before adding the user to the list of Organizations. False to keep the user in whatever Organization(s) they are in while adding the user to the Organization(s) in the SAML attribute.
**saml_admin_attr:** The saml attribute name where the organization administrators array can be found.
**remove_admins:** True to remove user from all organizations that it is admin before adding the user to the list of Organizations admins. False to keep the user in whatever Organization(s) they are in as admin while adding the user as an Organization administrator in the SAML attribute.
**Example SAML Team Map** **Example SAML Team Map**
Below is another example of a SAML attribute that contains a Team membership in a list. Below is another example of a SAML attribute that contains a Team membership in a list.
``` ```