0002-auth_saml-rename-attributes-using-model-67025.patch
src/authentic2_auth_saml/adapters.py | ||
---|---|---|
127 | 127 |
If an attribute is not mandatory any error is just logged, if the attribute is |
128 | 128 |
mandatory, login will fail. |
129 | 129 |
""" |
130 | ||
131 | 130 |
saml_attributes = saml_attributes.copy() |
132 | 131 |
attribute_mapping = get_setting(idp, 'A2_ATTRIBUTE_MAPPING', []) |
133 | 132 | |
134 |
if not attribute_mapping: |
|
135 |
return |
|
136 | ||
137 | 133 |
if not isinstance(attribute_mapping, list): |
138 | 134 |
raise MappingError(_('invalid A2_ATTRIBUTE_MAPPING')) |
139 | 135 | |
... | ... | |
141 | 137 |
user.save() |
142 | 138 | |
143 | 139 |
def apply_attribute_mapping(self, user, idp, saml_attributes, attribute_mapping): |
140 |
self.rename_attributes(idp, saml_attributes) |
|
141 | ||
144 | 142 |
user_modified = False |
145 | 143 |
for mapping in attribute_mapping: |
146 | 144 |
if not isinstance(mapping, dict): |
... | ... | |
166 | 164 |
logger.warning('auth_saml: mapping action failed: %s', e) |
167 | 165 |
return user_modified |
168 | 166 | |
169 |
def action_rename(self, user, idp, saml_attributes, mapping): |
|
170 |
from_name = mapping.get('from') |
|
171 |
if not from_name or not isinstance(from_name, str): |
|
172 |
raise MappingError(_('missing from in rename')) |
|
173 |
to_name = mapping.get('to') |
|
174 |
if not to_name or not isinstance(to_name, str): |
|
175 |
raise MappingError(_('missing to in rename')) |
|
176 |
if from_name in saml_attributes: |
|
177 |
saml_attributes[to_name] = saml_attributes[from_name] |
|
167 |
def rename_attributes(self, idp, saml_attributes): |
|
168 |
for action in idp['authenticator'].rename_attribute_actions.all(): |
|
169 |
if action.from_name in saml_attributes: |
|
170 |
saml_attributes[action.to_name] = saml_attributes[action.from_name] |
|
178 | 171 | |
179 | 172 |
def action_set_attribute(self, user, idp, saml_attributes, mapping): |
180 | 173 |
attribute = mapping.get('attribute') |
src/authentic2_auth_saml/models.py | ||
---|---|---|
191 | 191 |
if not settings[setting]: |
192 | 192 |
del settings[setting] |
193 | 193 | |
194 |
settings['authenticator'] = self |
|
194 | 195 |
return settings |
195 | 196 | |
196 | 197 |
@property |
tests/test_auth_saml.py | ||
---|---|---|
28 | 28 |
from authentic2.custom_user.models import DeletedUser |
29 | 29 |
from authentic2.models import Attribute |
30 | 30 |
from authentic2_auth_saml.adapters import AuthenticAdapter, MappingError |
31 |
from authentic2_auth_saml.models import SAMLAuthenticator |
|
31 |
from authentic2_auth_saml.models import RenameAttributeAction, SAMLAuthenticator
|
|
32 | 32 | |
33 | 33 |
from .utils import login |
34 | 34 | |
... | ... | |
84 | 84 |
'saml_attribute': 'mail', |
85 | 85 |
'mandatory': True, |
86 | 86 |
}, |
87 |
{'action': 'rename', 'from': 'http://fucking/attribute/givenName', 'to': 'first_name'}, |
|
88 | 87 |
{ |
89 | 88 |
'attribute': 'title', |
90 | 89 |
'saml_attribute': 'title', |
... | ... | |
95 | 94 |
}, |
96 | 95 |
], |
97 | 96 |
) |
97 |
RenameAttributeAction.objects.create( |
|
98 |
authenticator=authenticator, |
|
99 |
from_name='http://nice/attribute/givenName', |
|
100 |
to_name='first_name', |
|
101 |
) |
|
98 | 102 |
return authenticator.settings |
99 | 103 | |
100 | 104 | |
... | ... | |
111 | 115 |
'name_id_format': lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT, |
112 | 116 |
'mail': ['john.doe@example.com'], |
113 | 117 |
'title': ['Mr.'], |
114 |
'http://fucking/attribute/givenName': ['John'],
|
|
118 |
'http://nice/attribute/givenName': ['John'],
|
|
115 | 119 |
} |
116 | 120 | |
117 | 121 | |
... | ... | |
144 | 148 |
caplog, adapter, idp, saml_attributes, title_attribute, user |
145 | 149 |
): |
146 | 150 |
caplog.set_level('WARNING') |
147 |
saml_attributes['http://fucking/attribute/givenName'] = []
|
|
151 |
saml_attributes['http://nice/attribute/givenName'] = []
|
|
148 | 152 |
adapter.apply_attribute_mapping(user, idp, saml_attributes, idp['A2_ATTRIBUTE_MAPPING']) |
149 | 153 |
assert re.match('.*no value.*first_name', caplog.records[-1].message) |
150 | 154 | |
... | ... | |
152 | 156 |
def test_apply_attribute_mapping_missing_attribute_exception( |
153 | 157 |
adapter, idp, saml_attributes, title_attribute, user, rf |
154 | 158 |
): |
155 |
saml_attributes['http://fucking/attribute/givenName'] = []
|
|
159 |
saml_attributes['http://nice/attribute/givenName'] = []
|
|
156 | 160 |
idp['A2_ATTRIBUTE_MAPPING'][-1]['mandatory'] = True |
157 | 161 |
with pytest.raises(MappingError, match='no value'): |
158 | 162 |
adapter.apply_attribute_mapping(user, idp, saml_attributes, idp['A2_ATTRIBUTE_MAPPING']) |
159 |
- |