Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e8ea3ec

Browse files
wip #287
1 parent 7ea562f commit e8ea3ec

File tree

4 files changed

+330
-34
lines changed

4 files changed

+330
-34
lines changed

‎CHANGES‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changes
22
=======
33

4+
v1.3.0 (future)
5+
6+
- Add signals
7+
- Refactoring some classes to facilitate inheritance / customisation
8+
- Documentation for signals and inheritance / customisation
9+
410
v1.2.2 (2021年05月27日)
511
-------------------
612

‎djangosaml2/backends.py‎

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
from django.core.exceptions import (ImproperlyConfigured,
2525
MultipleObjectsReturned)
2626

27+
from .signals import authenticate, pre_user_save, post_user_save
28+
2729

2830
logger = logging.getLogger('djangosaml2')
2931

@@ -123,6 +125,13 @@ def authenticate(self, request, session_info=None, attribute_mapping=None, creat
123125

124126
if not self.is_authorized(attributes, attribute_mapping, idp_entityid, assertion_info):
125127
logger.error('Request not authorized')
128+
authenticate.send(sender=self,
129+
request=request,
130+
is_authorized=False,
131+
can_authenticate=None,
132+
user=None,
133+
user_created=None,
134+
attributes=attributes)
126135
return None
127136

128137
user_lookup_key, user_lookup_value = self._extract_user_identifier_params(
@@ -141,7 +150,15 @@ def authenticate(self, request, session_info=None, attribute_mapping=None, creat
141150
user = self._update_user(
142151
user, attributes, attribute_mapping, force_save=created)
143152

144-
if self.user_can_authenticate(user):
153+
can_authenticate = self.user_can_authenticate(user)
154+
authenticate.send(sender=self,
155+
request=request,
156+
is_authorized=True,
157+
can_authenticate=can_authenticate,
158+
user=user,
159+
user_created=created,
160+
attributes=attributes)
161+
if can_authenticate:
145162
return user
146163

147164
def _update_user(self, user, attributes: dict, attribute_mapping: dict, force_save: bool = False):
@@ -156,46 +173,54 @@ def _update_user(self, user, attributes: dict, attribute_mapping: dict, force_sa
156173
if not attribute_mapping:
157174
# Always save a brand new user instance
158175
if user.pk is None:
176+
pre_user_save.send(sender=self, user=user, attributes=attributes)
159177
user = self.save_user(user)
178+
post_user_save.send(sender=self, user=user, attributes=attributes)
160179
return user
161180

162181
# Lookup key
163-
user_lookup_key = self._user_lookup_attribute
182+
has_updated_fields = self.lookup_and_set_attributes(user, attributes, attribute_mapping)
183+
184+
if has_updated_fields or force_save:
185+
pre_user_save.send(sender=self, user=user, attributes=attributes)
186+
user = self.save_user(user)
187+
post_user_save.send(sender=self, user=user, attributes=attributes)
188+
189+
return user
190+
191+
# ################################################
192+
# Methods to override by end-users in subclasses #
193+
# ################################################
194+
195+
def lookup_and_set_attributes(self, user, attributes: dict, attribute_mapping: dict) -> bool:
164196
has_updated_fields = False
165197
for saml_attr, django_attrs in attribute_mapping.items():
166198
attr_value_list = attributes.get(saml_attr)
167199
if not attr_value_list:
168200
logger.debug(
169201
f'Could not find value for "{saml_attr}", not updating fields "{django_attrs}"')
170-
continue
171-
202+
return has_updated_fields
172203
for attr in django_attrs:
173-
if attr == user_lookup_key:
174-
# Don't update user_lookup_key (e.g. username) (issue #245)
175-
# It was just used to find/create this user and might have
176-
# been changed by `clean_user_main_attribute`
177-
continue
178-
elif hasattr(user, attr):
179-
user_attr = getattr(user, attr)
180-
if callable(user_attr):
181-
modified = user_attr(attr_value_list)
182-
else:
183-
modified = set_attribute(
184-
user, attr, attr_value_list[0])
185-
186-
has_updated_fields = has_updated_fields or modified
187-
else:
188-
logger.debug(
189-
f'Could not find attribute "{attr}" on user "{user}"')
190-
191-
if has_updated_fields or force_save:
192-
user = self.save_user(user)
193-
194-
return user
195-
196-
# ############################################
197-
# Hooks to override by end-users in subclasses
198-
# ############################################
204+
has_updated_fields = has_updated_fields or self.lookup_and_set_attribute(
205+
user, attr, attr_value_list
206+
)
207+
return has_updated_fields
208+
209+
def lookup_and_set_attribute(self, user, attr, attr_value_list) -> bool:
210+
if attr == self._user_lookup_attribute:
211+
# Don't update user_lookup_key (e.g. username) (issue #245)
212+
# It was just used to find/create this user and might have
213+
# been changed by `clean_user_main_attribute`
214+
return False
215+
elif hasattr(user, attr):
216+
user_attr = getattr(user, attr)
217+
if callable(user_attr):
218+
return user_attr(attr_value_list)
219+
else:
220+
return set_attribute(user, attr, attr_value_list[0])
221+
else:
222+
logger.debug(f'Could not find attribute "{attr}" on user "{user}"')
223+
return False
199224

200225
def clean_attributes(self, attributes: dict, idp_entityid: str, **kwargs) -> dict:
201226
""" Hook to clean or filter attributes from the SAML response. No-op by default. """

‎djangosaml2/signals.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
import django.dispatch
1616

17-
pre_user_save = django.dispatch.Signal(
18-
providing_args=['attributes', 'user_modified'])
19-
post_authenticated = django.dispatch.Signal(
20-
providing_args=['session_info', 'request'])
17+
pre_user_save = django.dispatch.Signal(providing_args=['user', 'attributes'])
18+
post_user_save = django.dispatch.Signal(providing_args=['user', 'attributes'])
19+
authenticate = django.dispatch.Signal(providing_args=[
20+
'request', 'is_authorized', 'can_authenticate', 'user', 'user_created', 'attributes'
21+
])

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /