16 |
16 |
|
17 |
17 |
|
18 |
18 |
import logging
|
|
19 |
from contextlib import contextmanager
|
19 |
20 |
|
20 |
21 |
from django.contrib import messages
|
21 |
22 |
from django.core.exceptions import MultipleObjectsReturned
|
... | ... | |
53 |
54 |
return self.msg % self.kwargs
|
54 |
55 |
|
55 |
56 |
|
|
57 |
@contextmanager
|
|
58 |
def wrap_mapping_errors(action):
|
|
59 |
try:
|
|
60 |
yield
|
|
61 |
except MappingError as e:
|
|
62 |
if action.mandatory:
|
|
63 |
# it's mandatory, provisionning should fail completely
|
|
64 |
raise e
|
|
65 |
logger.warning('auth_saml: mapping action failed: %s', e)
|
|
66 |
|
|
67 |
|
56 |
68 |
class SamlConditionContextProxy:
|
57 |
69 |
def __init__(self, saml_attributes):
|
58 |
70 |
self.saml_attributes = saml_attributes
|
... | ... | |
133 |
145 |
if not isinstance(attribute_mapping, list):
|
134 |
146 |
raise MappingError(_('invalid A2_ATTRIBUTE_MAPPING'))
|
135 |
147 |
|
136 |
|
if self.apply_attribute_mapping(user, idp, saml_attributes, attribute_mapping):
|
137 |
|
user.save()
|
|
148 |
self.apply_attribute_mapping(user, idp, saml_attributes, attribute_mapping)
|
138 |
149 |
|
139 |
150 |
def apply_attribute_mapping(self, user, idp, saml_attributes, attribute_mapping):
|
140 |
151 |
self.rename_attributes(idp, saml_attributes)
|
|
152 |
self.set_attributes(user, idp, saml_attributes)
|
141 |
153 |
|
142 |
|
user_modified = False
|
143 |
154 |
for mapping in attribute_mapping:
|
144 |
155 |
if not isinstance(mapping, dict):
|
145 |
156 |
raise MappingError(_('invalid mapping action "%(mapping)s"'), mapping=mapping)
|
... | ... | |
155 |
166 |
if not method:
|
156 |
167 |
raise MappingError(_('invalid action'))
|
157 |
168 |
logger.debug('auth_saml: applying provisionning mapping %s', mapping)
|
158 |
|
if method(user, idp, saml_attributes, mapping):
|
159 |
|
user_modified = True
|
|
169 |
method(user, idp, saml_attributes, mapping)
|
160 |
170 |
except MappingError as e:
|
161 |
171 |
if mandatory:
|
162 |
172 |
# it's mandatory, provisionning should fail completely
|
163 |
173 |
raise e
|
164 |
174 |
logger.warning('auth_saml: mapping action failed: %s', e)
|
165 |
|
return user_modified
|
166 |
175 |
|
167 |
176 |
def rename_attributes(self, idp, saml_attributes):
|
168 |
177 |
for action in idp['authenticator'].rename_attribute_actions.all():
|
169 |
178 |
if action.from_name in saml_attributes:
|
170 |
179 |
saml_attributes[action.to_name] = saml_attributes[action.from_name]
|
171 |
180 |
|
172 |
|
def action_set_attribute(self, user, idp, saml_attributes, mapping):
|
173 |
|
attribute = mapping.get('attribute')
|
174 |
|
if not attribute or not isinstance(attribute, str):
|
175 |
|
raise MappingError(_('missing attribute key'))
|
|
181 |
def set_attributes(self, user, idp, saml_attributes):
|
|
182 |
user_modified = False
|
|
183 |
for action in idp['authenticator'].set_attribute_actions.all():
|
|
184 |
with wrap_mapping_errors(action):
|
|
185 |
user_modified |= self.set_user_attribute(user, action, saml_attributes)
|
176 |
186 |
|
177 |
|
saml_attribute = mapping.get('saml_attribute')
|
178 |
|
if not saml_attribute or not isinstance(saml_attribute, str):
|
179 |
|
raise MappingError(_('missing saml_attribute key'))
|
|
187 |
if user_modified:
|
|
188 |
user.save()
|
180 |
189 |
|
181 |
|
if saml_attribute not in saml_attributes:
|
182 |
|
raise MappingError(_('unknown saml_attribute (%s)') % saml_attribute)
|
183 |
|
value = saml_attributes[saml_attribute]
|
184 |
|
return self.set_user_attribute(user, attribute, value)
|
|
190 |
def set_user_attribute(self, user, action, saml_attributes):
|
|
191 |
if action.saml_attribute not in saml_attributes:
|
|
192 |
raise MappingError(_('unknown saml_attribute (%s)') % action.saml_attribute)
|
185 |
193 |
|
186 |
|
def set_user_attribute(self, user, attribute, value):
|
|
194 |
attribute = action.attribute
|
|
195 |
value = saml_attributes[action.saml_attribute]
|
187 |
196 |
if isinstance(value, list):
|
188 |
197 |
if len(value) == 0:
|
189 |
198 |
raise MappingError(_('no value for attribute "%(attribute)s"'), attribute=attribute)
|