From: Matías Aguirre Date: Fri, 10 Dec 2010 17:39:47 +0000 (-0200) Subject: Signal user updating, still pending extra arguments request X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=573540f9fc1bc6d8216ed6275f35955bc8a507ec;p=django-social-auth.git Signal user updating, still pending extra arguments request --- diff --git a/README.rst b/README.rst index e1cce53..2a181db 100644 --- a/README.rst +++ b/README.rst @@ -26,7 +26,8 @@ some features are: * `Facebook OAuth`_ * `Orkut OAuth`_ -- Basic user data population +- Basic user data population and signaling, to allows custom fields values + from providers response - Multiple social accounts association to single users @@ -144,6 +145,25 @@ Installation it might solve your case. +------- +Signals +------- +A pre_update signal is sent when user data is about to be updated with new +values from auth service provider, this apply to new users and already +existent ones. This is useful to update custom user fields or `User Profiles`_, +for example, to store user gender, location, etc. Example:: + + from django.dispatch import receiver + + from social_auth.signals import pre_save + from social_auth.backends import FacebookBackend + + @receiver(pre_save, sender=FacebookBackend) + def facebook_extra_values(sender, user, response, details): + user.gender = response.get('gender') + return True + + ------ OpenId ------ diff --git a/social_auth/backends.py b/social_auth/backends.py index e27a02f..865d050 100644 --- a/social_auth/backends.py +++ b/social_auth/backends.py @@ -11,6 +11,7 @@ from django.contrib.auth.models import UNUSABLE_PASSWORD from .models import UserSocialAuth from .conf import OLD_AX_ATTRS, AX_SCHEMA_ATTRS +from .signals import pre_update # get User class, could not be auth.User User = UserSocialAuth._meta.get_field('user').rel.to @@ -47,7 +48,7 @@ class SocialAuthBackend(ModelBackend): user = self.create_user(details=details, *args, **kwargs) else: user = auth_user.user - self.update_user_details(user, details) + self.update_user_details(user, response, details) return user def get_username(self, details): @@ -95,8 +96,11 @@ class SocialAuthBackend(ModelBackend): password=UNUSABLE_PASSWORD) # update details and associate account with social credentials - self.update_user_details(user, details) - self.associate_auth(user, response, details) + try: + self.update_user_details(user, response, details) + self.associate_auth(user, response, details) + except Exception, e: + print str(e) return user def associate_auth(self, user, response, details): @@ -124,19 +128,22 @@ class SocialAuthBackend(ModelBackend): """Return default blank user extra data""" return '' - def update_user_details(self, user, details): + def update_user_details(self, user, response, details): """Update user details with new (maybe) data""" - fields = (name for name in ('first_name', 'last_name', 'email') - if user._meta.get_field(name)) changed = False - - for name in fields: - value = details.get(name) + for name, value in details.iteritems(): if value and value != getattr(user, name, value): setattr(user, name, value) changed = True - if changed: + # Fire a pre-update signal sending current backend instance, + # user instance (created or retrieved from database), service + # response and processed details, signal handlers must return + # True or False to signal that something has changed + updated = filter(bool, pre_update.send(sender=self, user=user, + response=response, + details=details)) + if changed or len(updated) > 0: user.save() def get_user_id(self, details, response): @@ -204,6 +211,8 @@ class FacebookBackend(OAuthBackend): def get_user_details(self, response): """Return user details from Facebook account""" + import pprint + pprint.pprint(response) return {'email': response.get('email', ''), 'username': response['name'], 'fullname': response['name'], diff --git a/social_auth/models.py b/social_auth/models.py index 84469b0..8ef3a96 100644 --- a/social_auth/models.py +++ b/social_auth/models.py @@ -2,7 +2,8 @@ from django.db import models from django.conf import settings -# If User class is overrided, it must provide the following fields: +# If User class is overrided, it must provide the following fields, +# or it won't be playing nicely with auth module: # # username = CharField() # email = EmailField() diff --git a/social_auth/views.py b/social_auth/views.py index bb47689..5334a65 100644 --- a/social_auth/views.py +++ b/social_auth/views.py @@ -34,6 +34,7 @@ def complete(request, backend): return HttpResponseServerError('Incorrect authentication service') backend = BACKENDS[backend](request, request.path) user = backend.auth_complete() + print "USER:", user if user and user.is_active: login(request, user) url = request.session.pop(REDIRECT_FIELD_NAME, '') or \