diff --git a/awx/conf/fields.py b/awx/conf/fields.py index 8e93ad7ad3..6a17d8b0ce 100644 --- a/awx/conf/fields.py +++ b/awx/conf/fields.py @@ -136,3 +136,25 @@ class KeyValueField(DictField): if not isinstance(value, six.string_types + six.integer_types + (float,)): self.fail('invalid_child', input=value) return ret + + +class ListTuplesField(ListField): + default_error_messages = { + 'type_error': _('Expected a list of tuples but got {input_type} instead.'), + } + + def to_representation(self, value): + if isinstance(value, (list, tuple)): + return super(ListTuplesField, self).to_representation(value) + else: + self.fail('type_error', input_type=type(value)) + + def to_internal_value(self, data): + if isinstance(data, list): + for x in data: + if not isinstance(x, (list, tuple)): + self.fail('type_error', input_type=type(x)) + + return super(ListTuplesField, self).to_internal_value(data) + else: + self.fail('type_error', input_type=type(data)) diff --git a/awx/sso/conf.py b/awx/sso/conf.py index 001c527f45..63fba340a5 100644 --- a/awx/sso/conf.py +++ b/awx/sso/conf.py @@ -70,11 +70,6 @@ SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER = collections.OrderedDict([ ])), ]) -SOCIAL_AUTH_SAML_SECURITY_CONFIG_HELP_TEXT = _('''\ -Extra https://github.com/onelogin/python-saml#settings\ -''') - - ############################################################################### # AUTHENTICATION BACKENDS DYNAMIC SETTING ############################################################################### @@ -1070,16 +1065,67 @@ register( 'SOCIAL_AUTH_SAML_SECURITY_CONFIG', field_class=fields.SAMLSecurityField, allow_null=True, - default=None, + default={'requestedAuthnContext': False}, label=_('SAML Security Config'), - help_text=SOCIAL_AUTH_SAML_SECURITY_CONFIG_HELP_TEXT, + help_text=_('A dict of key value pairs that are passed to the underlying' + ' python-saml security setting' + ' https://github.com/onelogin/python-saml#settings'), + category=_('SAML'), + category_slug='saml', + placeholder=collections.OrderedDict([ + ("nameIdEncrypted", False), + ("authnRequestsSigned", False), + ("logoutRequestSigned", False), + ("logoutResponseSigned", False), + ("signMetadata", False), + ("wantMessagesSigned", False), + ("wantAssertionsSigned", False), + ("wantAssertionsEncrypted", False), + ("wantNameId", True), + ("wantNameIdEncrypted", False), + ("wantAttributeStatement", True), + ("requestedAuthnContext", True), + ("requestedAuthnContextComparison", "exact"), + ("metadataValidUntil", "2015-06-26T20:00:00Z"), + ("metadataCacheDuration", "PT518400S"), + ("signatureAlgorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1"), + ("digestAlgorithm", "http://www.w3.org/2000/09/xmldsig#sha1"), + ]), + feature_required='enterprise_auth', +) + +register( + 'SOCIAL_AUTH_SAML_SP_EXTRA', + field_class=fields.DictField, + allow_null=True, + default=None, + label=_('SAML Service Provider extra configuration data'), + help_text=_('A dict of key value pairs to be passed to the underlying' + ' python-saml Service Provider configuration setting.'), category=_('SAML'), category_slug='saml', - #placeholder=SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER, placeholder=collections.OrderedDict(), feature_required='enterprise_auth', ) +register( + 'SOCIAL_AUTH_SAML_EXTRA_DATA', + field_class=fields.ListTuplesField, + allow_null=True, + default=None, + label=_('SAML IDP to extra_data attribute mapping'), + help_text=_('A list of tuples that maps IDP attributes to extra_attributes.' + ' Each attribute will be a list of values, even if only 1 value.'), + category=_('SAML'), + category_slug='saml', + placeholder=[ + ('attribute_name', 'extra_data_name_for_attribute'), + ('department', 'department'), + ('manager_full_name', 'manager_full_name') + ], + feature_required='enterprise_auth', +) + register( 'SOCIAL_AUTH_SAML_ORGANIZATION_MAP', field_class=fields.SocialOrganizationMapField,