def get_or_create_user(self, **kwargs): details = kwargs['details'] user = None email = details.get('email') if email and ASSOCIATE_BY_MAIL: # try to associate accounts registered with the same email # address, only if it's a single object. ValueError is # raised if multiple objects are returned try: user = User.objects.get(email=email) except MultipleObjectsReturned: raise ValueError('Not unique email address supplied') except User.DoesNotExist: pass if user is None and create_user.receivers: sender = self.__class__ for receiver in create_user._live_receivers(_make_id(sender)): user = receiver(signal=create_user, sender=sender, **kwargs) if user is not None: user.is_new = True break if user is None and CREATE_USERS: username = self.username(details) user = User.objects.create_user(username=username, email=email) user.is_new = True return user
def authenticate(self, *args, **kwargs): """Authenticate user using social credentials Authentication is made if this is the correct backend, backend verification is made by kwargs inspection for current backend name presence. """ # Validate backend and arguments. Require that the Social Auth # response be passed in as a keyword argument, to make sure we # don't match the username/password calling conventions of # authenticate. if not (self.name and kwargs.get(self.name) and 'response' in kwargs): return None response = kwargs.get('response') details = self.get_user_details(response) kwargs['details'] = details uid = self.get_user_id(details, response) is_new = False user = kwargs.get('user') try: social_user = self.get_social_auth_user(uid) except UserSocialAuth.DoesNotExist: if user is None and create_user.receivers: sender = self.__class__ for receiver in create_user._live_receivers(_make_id(sender)): user = receiver(signal=create_user, sender=sender, **kwargs) if user is not None: is_new = True break if user is None: # new user if not CREATE_USERS or not kwargs.get('create_user', True): # Send signal for cases where tracking failed registering # is useful. socialauth_not_registered.send(sender=self.__class__, uid=uid, response=response, details=details) return None email = details.get('email') if email and ASSOCIATE_BY_MAIL: # try to associate accounts registered with the same email # address, only if it's a single object. ValueError is # raised if multiple objects are returned try: user = User.objects.get(email=email) except MultipleObjectsReturned: raise ValueError('Not unique email address supplied') except User.DoesNotExist: user = None if not user: username = self.username(details) logger.debug('Creating new user with username %s and email %s', username, sanitize_log_data(email)) user = User.objects.create_user(username=username, email=email) is_new = True try: social_user = self.associate_auth(user, uid, response, details) except IntegrityError: # Protect for possible race condition, those bastard with FTL # clicking capabilities social_user = self.get_social_auth_user(uid) # Raise ValueError if this account was registered by another user. if user and user != social_user.user: logger.info('Account already in use', extra=dict(data=details)) return None user = social_user.user # Flag user "new" status setattr(user, 'is_new', is_new) # Update extra_data storage, unless disabled by setting if LOAD_EXTRA_DATA: extra_data = self.extra_data(user, uid, response, details) if extra_data and social_user.extra_data != extra_data: social_user.extra_data = extra_data social_user.save() user.social_user = social_user # Update user account data. self.update_user_details(user, response, details, is_new) return user