def save(self, commit=True): if self.sso_profile: self.instance = self.sso_profile.user user = super(RegistrationForm, self).save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() # This generates a default UserProfile instance user_profile = UserProfile.objects.get(user=user) user_profile.has_opted_in = self.cleaned_data.get('has_opted_in', False) user_profile.is_sso = False user_profile.is_verified = settings.ACCOUNT_EMAIL_VERIFICATION_DEFAULT self.save_profile_image(user_profile, commit=True) if self.open_profile: save_open_profile(user, self.open_profile) user._profile = user_profile return user
def save(self, commit=True): if self.sso_profile: self.instance = self.sso_profile.user user = super(RegistrationForm, self).save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() # This generates a default UserProfile instance user_profile = UserProfile.objects.get(user=user) user_profile.has_opted_in = self.cleaned_data.get( 'has_opted_in', False) user_profile.is_sso = False user_profile.is_verified = settings.ACCOUNT_EMAIL_VERIFICATION_DEFAULT self.save_profile_image(user_profile, commit=True) if self.open_profile: save_open_profile(user, self.open_profile) user._profile = user_profile return user
def callback(request): """This is where Twitter will redirect the user after this app has been authorized.""" try: unauthed_token = request.session.get('TWITTER_UNAUTH_TOKEN', None) oauth_verifier = request.GET.get('oauth_verifier', None) try: if unauthed_token: del request.session['TWITTER_UNAUTH_TOKEN'] except KeyError: pass if not unauthed_token: _log.debug("Unauthenticated token not found in session") return _denied_response(request) token = oauth.OAuthToken.from_string(unauthed_token) oauth_token = request.GET.get('oauth_token', None) if token.key != oauth_token: _log.debug("Tokens did not match %s - %s", token.key, oauth_token) return _denied_response(request) tw = TwitterAPI() try: access_token = tw.exchange_request_token_for_access_token(token, oauth_verifier) except KeyError: tw.close() return _denied_response(request) twitter_profile = tw.get_profile(access_token) tw.close() if twitter_profile: _log.debug("Twitter profile downloaded:\n%s", twitter_profile) try: p = simplejson.loads(twitter_profile) except Exception, e: # try one more time try: tw = TwitterAPI() twitter_profile = tw.get_profile(access_token) tw.close() _log.debug("Twitter profile downloaded on retry:\n%s", twitter_profile) if not twitter_profile: raise Exception("OAuth error: retry failed on get_profile") p = simplejson.loads(twitter_profile) except Exception, e: _log.warn("Twitter profile could not be JSON decoded.\n%s", twitter_profile) _log.exception(e) add_message(request, u"We are unable to connect to Twitter at the moment. Please try again in a few minutes.") return _denied_response(request) _log.debug(p) screen_name = p.get('screen_name') full_name = p.get('name', p['screen_name']) # Split full_name into first name and last name x = full_name.split(' ', 1) first_name, last_name = u'', u'' if len(x) > 1: first_name, last_name = x[0], x[1] elif len(x) == 1: first_name, last_name = u'', x[0] profile_image = p.get('profile_image_url', '') if '/images/default_profile' in profile_image: profile_image = '' profile = dict( profile_type=u'twitter', screen_name=screen_name, first_name=first_name, last_name=last_name, appuser_id=p['id'], profile_image_url=profile_image, access_token=access_token.to_string() ) if request.user.is_authenticated(): user = request.user p = save_open_profile(user, profile) add_message(request, u"You've connected your Twitter account successfully.") # user.message_set.create(message=_(u"Thank you for authorizing us to update your Twitter status!")) else: request.session['OPEN_PROFILE'] = profile
def sso_authorized(request): """Process Single Sign-On (SSO) authorization from Twitter. If authorized: If account doesn't already exist: - Create dummy user account with disabled password () - Create user profile with sso (including avatar image) - Save Twitter profile - Initiate AMQP tasks for user - Log the user in - Redirect to saved HTTP_REFERER or ``next`` value from sso_initiate """ from event.amqp.tasks import build_recommended_events next = request.session.get('SSO_NEXT', '/') if request.user.is_authenticated(): return HttpResponseRedirect(next) if 'OPEN_PROFILE' not in request.session: _log.debug("Lost session data during SSO authorization. Retrying.") return sso_initiate(request) oprofile = request.session['OPEN_PROFILE'] screen_name = oprofile['screen_name'].lower() new_signup = False try: # Use already created SSO account if one exists prof = UserProfile.objects.select_related('user').get(sso_username__iexact=screen_name) user = prof.user except UserProfile.DoesNotExist: try: # Use latest existing account if one linked to this twitter screen name exists prof = UserProfile.objects.select_related('user').filter( twitterprofile__screen_name__iexact=screen_name, twitterprofile__pk__isnull=False ).order_by("-pk")[:1].get() user = prof.user except UserProfile.DoesNotExist: # Create a new SSO account # If screenname is available, use it as username. # If not, suffix it with a number and use that. new_signup = True email = request.session.get("email", None) if not email: add_message(request, u"Create a new account below in two easy steps before signing in with Twitter.") return HttpResponseRedirect(reverse("signup") + "?next=" + next) screen_name = screen_name.strip()[:32] user = None if User.objects.filter(username=screen_name).count(): screen_name = screen_name[:27] # make room for suffixed digits for x in range(2, 100): uname = u"%s%s" % (screen_name, x) if not User.objects.filter(username=uname).count(): user = User.objects.create( username=uname, first_name=oprofile['first_name'], last_name=oprofile['last_name'], email=email, ) break else: user = User.objects.create( username=screen_name, first_name=oprofile['first_name'], last_name=oprofile['last_name'], email=email, ) if not user: # use a randomly suffixed username user = User.objects.create( username=u''.join([screen_name[:25], u'-', uuid4().hex[::6]]), first_name=oprofile['first_name'], last_name=oprofile['last_name'], email=email, ) prof = user.get_profile() prof.is_sso = True prof.sso_username = screen_name prof.send_reminders = False prof.send_favorites = False prof.save() # build AMQP headers so that recommended events are built right after # this user's friendships have been computed amqp_headers = { 'final_reply_to':'signal/signal.events.build_recommended_events', 'user_profile_id':prof.pk } save_open_profile(user, oprofile, amqp_headers) # this will also initiate the friendship builder AMQP task if not prof.avatar_image: url = oprofile.get('profile_image_url', None) copy_avatar_from_url_to_profile(url, prof, commit=True) # annotate the user object with the path of the backend so that # login() works without a password: backend = get_backends()[0] user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) login(request, user) if new_signup: user.message_set.create(message=_(u'Thank you for signing-up with Twitter!')) _log.debug("SSO user %s logged in" % prof.username) return HttpResponseRedirect(next)