Example #1
0
def change_profile(request, old_password=None, new_password=None, new_email=None, bio=None):
    if bio is not None:
        request.user.userinfo.bio_text = bio
        request.user.userinfo.save()
        request.user.details.force()

    if new_email is not None:
        if not User.validate_email(new_email):
            raise ValidationError({'new_email': "Please enter a valid email address."})

        if request.user.email != new_email:
            if not User.email_is_unused(new_email):
                raise ValidationError({'new_email': "Sorry! That email address is already being used for an account."})

            request.user.email = new_email
            request.user.save()
            request.user.details.force()

    if old_password is not None and new_password is not None:
        if not User.validate_password(new_password):
            raise ValidationError({
                'new_password': "******"
                                "Please use {} or more characters.".format(User.MINIMUM_PASSWORD_LENGTH),
            })

        form = PasswordChangeForm(user=request.user, data={
            'old_password': old_password,
            'new_password1': new_password,
            'new_password2': new_password,
        })

        api_forms.validate(form)
        form.save()
        request.user.details.force()
Example #2
0
def twitter_followers_on_drawquest(request, twitter_access_token,
                                   twitter_access_token_secret):
    """ Returns one field, `users`, a list of `User` dicts. """
    twitter_user = TwitterUser.get_or_create_from_access_token(
        twitter_access_token, twitter_access_token_secret)
    twitter_friends = twitter_user.followers_on_drawquest(
        twitter_access_token, twitter_access_token_secret)
    twitter_friends = list(twitter_friends.select_related('user'))

    twitter_friend_uids = dict(
        (friend.user_id, friend.twitter_uid) for friend in twitter_friends)

    users = CachedCall.multicall([
        User.details_by_id(twitter_friend.user_id)
        for twitter_friend in twitter_friends
        if twitter_friend.user_id is not None
    ])

    for user in users:
        user.twitter_uid = twitter_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #3
0
def username_available(request, username):
    if User.objects.filter(username__iexact=username):
        return {'available': False}

    return {
        'available': True,
        'reserved_from_canvas': User.is_username_reserved(username),
    }
Example #4
0
def username_available(request, username):
    if User.objects.filter(username__iexact=username):
        return {'available': False}

    return {
        'available': True,
        'reserved_from_canvas': User.is_username_reserved(username),
    }
Example #5
0
def change_profile(request,
                   old_password=None,
                   new_password=None,
                   new_email=None,
                   bio=None):
    if bio is not None:
        request.user.userinfo.bio_text = bio
        request.user.userinfo.save()
        request.user.details.force()

    if new_email is not None:
        if not User.validate_email(new_email):
            raise ValidationError(
                {'new_email': "Please enter a valid email address."})

        if request.user.email != new_email:
            if not User.email_is_unused(new_email):
                raise ValidationError({
                    'new_email':
                    "Sorry! That email address is already being used for an account.",
                })

            request.user.email = new_email
            request.user.save()
            request.user.userinfo.update_hashes()
            request.user.details.force()

    if old_password is not None and new_password is not None:
        if not User.validate_password(new_password):
            raise ValidationError({
                'new_password':
                "******"
                "Please use {} or more characters.".format(
                    User.MINIMUM_PASSWORD_LENGTH),
            })

        form = PasswordChangeForm(user=request.user,
                                  data={
                                      'old_password': old_password,
                                      'new_password1': new_password,
                                      'new_password2': new_password,
                                  })

        api_forms.validate(form)
        form.save()
        request.user.details.force()
 def get_stars(self):
     """
     Returns a list of `{username, timestamp, id}` dicts.
     """
     stickers = CommentSticker.objects.filter(comment=self, type_id=settings.STAR_STICKER_TYPE_ID)
     stickers = stickers.values("user_id", "timestamp", "id")
     return [
         {"user": User.details_by_id(sticker["user_id"])(), "timestamp": sticker["timestamp"], "id": sticker["id"]}
         for sticker in stickers
     ]
    def user(self):
        from drawquest.apps.drawquest_auth.models import User

        if self.ugq:
            return UserDetails.from_id(self.author_id)

        try:
            return User.details_by_username('QuestBot')()
        except User.DoesNotExist:
            return UserDetails.from_id(self.author_id)
Example #8
0
    def user(self):
        from drawquest.apps.drawquest_auth.models import User

        if self.ugq:
            return UserDetails.from_id(self.author_id)

        try:
            return User.details_by_username('QuestBot')()
        except User.DoesNotExist:
            return UserDetails.from_id(self.author_id)
Example #9
0
 def get_stars(self):
     """
     Returns a list of `{username, timestamp, id}` dicts.
     """
     stickers = CommentSticker.objects.filter(
         comment=self, type_id=settings.STAR_STICKER_TYPE_ID)
     stickers = stickers.values('user_id', 'timestamp', 'id')
     return [{
         'user': User.details_by_id(sticker['user_id'])(),
         'timestamp': sticker['timestamp'],
         'id': sticker['id'],
     } for sticker in stickers]
def _share_by_email(sender, recipients, subject, template_name, context):
    _context = {"sender": sender}
    _context.update(context)

    headers = {"Reply-To": sender.email}

    for recipient in recipients:
        if not User.validate_email(recipient["email"]):
            continue

        try:
            send_email(recipient["email"], settings.UPDATES_EMAIL, subject, template_name, _context, headers=headers)
        except Exception, e:
            client.captureException()
Example #11
0
 def get_stars(self):
     """
     Returns a list of `{username, timestamp, id}` dicts.
     """
     stickers = CommentSticker.objects.filter(comment=self, type_id=settings.STAR_STICKER_TYPE_ID)
     stickers = stickers.values('user_id', 'timestamp', 'id')
     return [
         {
             'user': User.details_by_id(sticker['user_id'])(),
             'timestamp': sticker['timestamp'],
             'id': sticker['id'],
         }
         for sticker in stickers
     ]
def _share_by_email(sender, recipients, subject, template_name, context):
    _context = {'sender': sender}
    _context.update(context)

    headers = {'Reply-To': sender.email}

    for recipient in recipients:
        if not User.validate_email(recipient['email']):
            continue

        try:
            send_email(recipient['email'],
                       settings.UPDATES_EMAIL,
                       subject,
                       template_name,
                       _context,
                       headers=headers)
        except Exception, e:
            client.captureException()
Example #13
0
def twitter_followers_on_drawquest(request, twitter_access_token, twitter_access_token_secret):
    """ Returns one field, `users`, a list of `User` dicts. """
    twitter_user = TwitterUser.get_or_create_from_access_token(twitter_access_token, twitter_access_token_secret)
    twitter_friends = twitter_user.followers_on_drawquest(twitter_access_token, twitter_access_token_secret)
    twitter_friends = list(twitter_friends.select_related('user'))

    twitter_friend_uids = dict((friend.user_id, friend.twitter_uid) for friend in twitter_friends)

    users = CachedCall.multicall([User.details_by_id(twitter_friend.user_id) for twitter_friend in twitter_friends
                                  if twitter_friend.user_id is not None])

    for user in users:
        user.twitter_uid = twitter_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #14
0
def facebook_friends_on_drawquest(request, facebook_access_token):
    """ Returns one field, `users`, a list of `User` dicts. """
    fb_user = FacebookUser.get_or_create_from_access_token(facebook_access_token)
    fb_friends = fb_user.friends_on_drawquest(facebook_access_token).select_related('user')

    fb_friend_uids = dict((friend.user_id, friend.fb_uid) for friend in fb_friends)

    users = CachedCall.multicall([User.details_by_id(fb_friend.user_id) for fb_friend in fb_friends
                                  if fb_friend.user_id is not None])


    for user in users:
        user.fb_uid = fb_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #15
0
def facebook_friends_on_drawquest(request, facebook_access_token):
    """ Returns one field, `users`, a list of `User` dicts. """
    fb_user = FacebookUser.get_or_create_from_access_token(
        facebook_access_token)
    fb_friends = fb_user.friends_on_drawquest(
        facebook_access_token).select_related('user')

    fb_friend_uids = dict(
        (friend.user_id, friend.fb_uid) for friend in fb_friends)

    users = CachedCall.multicall([
        User.details_by_id(fb_friend.user_id) for fb_friend in fb_friends
        if fb_friend.user_id is not None
    ])

    for user in users:
        user.fb_uid = fb_friend_uids[user.id]

        if request.user.is_authenticated() and request.user.id != user.id:
            user.viewer_is_following = request.user.is_following(user.id)

    return {
        'users': users,
    }
Example #16
0
def email_is_unused(request, email):
    return {'email_is_unused': User.email_is_unused(email)}
Example #17
0
def signup(request, username, password, email, facebook_access_token=None):
    if check_rate_limit(request, username):
        raise ServiceError("Too many signup attempts. Wait a minute and try again.")

    try:
        return _login(request, password, username=username, email=email)
    except ValidationError:
        pass

    migrated_from_canvas_account = False
    errors = defaultdict(list)

    fb_user = None
    if facebook_access_token:
        fb_user = FacebookUser.create_from_access_token(facebook_access_token)

    def username_taken():
        # Ugly hack.
        for error in errors['username']:
            if 'taken' in error:
                return

        errors['username'].append("Sorry! That username is already taken.")

    if not password:
        errors['password'].append("Please enter a password.")

    if not User.validate_password(password):
        errors['password'].append("Sorry, your password is too short. "
                                  "Please use {} or more characters.".format(User.MINIMUM_PASSWORD_LENGTH))

    if not email:
        errors['email'].append("Please enter your email address.")
    elif not User.validate_email(email):
        errors['email'].append("Please enter a valid email address.")

    username_error = User.validate_username(username)
    if username_error:
        errors['username'].append(username_error)

    if not User.email_is_unused(email):
        errors['email'].append("Sorry! That email address is already being used for an account.")
    elif User.is_username_reserved(username):
        try:
            user = User.migrate_canvas_user(request, username, password, email=email)
        except IntegrityError:
            username_taken()
        except ValidationError:
            errors['username'] = ["""Sorry! This username is taken. Please pick a different username, """ +
                                  """or if you are "{}," enter your password to sign in.""".format(username)]
        else:
            migrated_from_canvas_account = True

    if errors:
        if fb_user:
            fb_user.delete()
        raise ValidationError(errors)

    if not migrated_from_canvas_account:
        try:
            user = User.objects.create_user(username, email, password)
        except IntegrityError:
            username_taken()
            raise ValidationError(errors)

        UserInfo.objects.create(user=user)

    if fb_user:
        fb_user.user = user
        fb_user.save()
        fb_user.notify_friends_of_signup(facebook_access_token)

        user.migrate_facebook_avatar(request, facebook_access_token)

    user = auth.authenticate(username=username, password=password)

    # auth.login starts a new session and copies the session data from the old one to the new one
    auth.login(request, user)

    return {
        'user': PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio': user.userinfo.bio_text,
        'user_subscribed_to_starred': is_subscribed(user, 'starred'),
        'sessionid': request.session.session_key,
        'migrated_from_canvas_account': migrated_from_canvas_account,
    }
Example #18
0
def email_is_unused(request, email):
    return {'email_is_unused': User.email_is_unused(email)}
Example #19
0
def _login(request, password, username=None, email=None):
    migrated_from_canvas_account = False

    def wrong_password():
        raise ValidationError({
            'password': "******"
                        "Please try again (make sure your caps lock is off)."
        })

    def wrong_username(username):
        raise ValidationError({
            'username': """The username you entered, "{}", doesn't exist. """.format(username) +
                        """Please try again, or enter the e-mail address you used to sign up."""
        })

    def get_username_from_email(email):
        if not email:
            wrong_username(email)

        try:
            return User.objects.get(email=email).username
        except User.DoesNotExist:
            wrong_username(email)

    if not username and not email:
        raise ValidationError({'username': "******"})

    if not username:
        username = get_username_from_email(email)

    user = auth.authenticate(username=username, password=password)

    if user is None:
        # Maybe they entered an email into the username field?
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            try:
                #TODO This might be broken - should probably pass username.
                username = get_username_from_email(email)
                user = auth.authenticate(username=username, password=password)
            except ValidationError:
                # No such username exists.
                # See if it's a example.com account we need to migrate over.
                if User.is_username_reserved(username):
                    try:
                        user = User.migrate_canvas_user(request, username, password, email=email)
                    except ValidationError as e:
                        wrong_password()
                    else:
                        migrated_from_canvas_account = True

    if user is None:
        wrong_password()

    if not user.is_active:
        return inactive_user_http_response()

    auth.login(request, user)

    return {
        'user': PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio': user.userinfo.bio_text,
        'user_subscribed_to_starred': is_subscribed(user, 'starred'),
        'sessionid': request.session.session_key,
        'migrated_from_canvas_account': migrated_from_canvas_account,
    }
 def from_ids(cls, user_ids):
     from drawquest.apps.drawquest_auth.models import User
     return CachedCall.multicall([
         User.details_by_id(user_id, promoter=cls) for user_id in user_ids
     ])
 def from_id(cls, user_id):
     from drawquest.apps.drawquest_auth.models import User
     return User.details_by_id(user_id, promoter=cls)()
 def from_ids(cls, user_ids):
     from drawquest.apps.drawquest_auth.models import User
     return CachedCall.multicall([User.details_by_id(user_id, promoter=cls)
                                  for user_id in user_ids])
Example #23
0
def signup(request,
           username,
           password,
           email,
           facebook_access_token=None,
           twitter_access_token=None,
           twitter_access_token_secret=None):
    if check_rate_limit(request, username):
        raise ServiceError(
            _("Too many signup attempts. Wait a minute and try again."))

    if not _validate_charset(username):
        raise ValidationError({
            'username': [
                _("Usernames can only contain the letters a-z or A-Z, digits, and underscores."
                  )
            ],
        })

    if not _validate_charset(email):
        raise ValidationError({
            'email': [
                _("Sorry, your email address contains invalid characters. Please remove them and try again."
                  )
            ],
        })

    try:
        return _login(request, password, username=username, email=email)
    except ValidationError:
        pass

    errors = defaultdict(list)

    fb_user = None
    twitter_user = None

    if facebook_access_token:
        fb_user = FacebookUser.get_or_create_from_access_token(
            facebook_access_token)
    elif twitter_access_token and twitter_access_token_secret:
        twitter_user = TwitterUser.get_or_create_from_access_token(
            twitter_access_token, twitter_access_token_secret)

    def username_taken():
        # Ugly hack.
        for error in errors['username']:
            if 'taken' in error:
                return

        errors['username'].append(_("Sorry! That username is already taken."))

    if not password:
        errors['password'].append(_("Please enter a password."))

    if not User.validate_password(password):
        errors['password'].append(
            _(u"Sorry, your password is too short. Please use %(count)d or more characters."
              % {'count': User.MINIMUM_PASSWORD_LENGTH}))

    if not email:
        errors['email'].append(_("Please enter your email address."))
    elif not User.validate_email(email):
        errors['email'].append(_("Please enter a valid email address."))

    username_error = User.validate_username(username)
    if username_error:
        errors['username'].append(username_error)

    if not User.email_is_unused(email):
        errors['email'].append(
            _("Sorry! That email address is already being used for an account. Try signing in instead, or use another email address."
              ))

    if errors:
        if fb_user:
            fb_user.delete()
        raise ValidationError(errors)

    try:
        user = User.objects.create_user(username, email, password)
    except IntegrityError:
        username_taken()
        raise ValidationError(errors)

    ui = UserInfo.objects.create(user=user)
    ui.update_hashes()

    if request.app_version is not None:
        user.kv.signup_app_version.set(request.app_version)

    if fb_user:
        fb_user.user = user
        fb_user.save()

        fb_user.notify_friends_of_signup(facebook_access_token)
        fb_user.respond_to_apprequest_invites(facebook_access_token)

        user.migrate_facebook_avatar(request, facebook_access_token)
    elif twitter_user:
        twitter_user.user = user
        twitter_user.save()

        twitter_user.notify_followers_of_signup(twitter_access_token,
                                                twitter_access_token_secret)
        twitter_user.auto_follow_from_invite(twitter_access_token,
                                             twitter_access_token_secret)

        @bgwork.defer
        def migrate_twitter_avatar():
            user.migrate_twitter_avatar(request, twitter_access_token,
                                        twitter_access_token_secret)

    user = auth.authenticate(username=username, password=password)

    # auth.login starts a new session and copies the session data from the old one to the new one
    auth.login(request, user)

    return {
        'user':
        PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio':
        user.userinfo.bio_text,
        'user_subscribed_to_starred':
        is_subscribed(user, 'starred'),
        'comment_count':
        0,
        'quest_count':
        Quest.all_objects.filter(author=user).count(),
        'sessionid':
        request.session.session_key,
        'migrated_from_canvas_account':
        False,
        'login':
        False,
        'heavy_state_sync':
        heavy_state_sync(request.user,
                         app_version=request.app_version,
                         app_version_tuple=request.app_version_tuple),
    }
Example #24
0
def _login(request, password, username=None, email=None):
    migrated_from_canvas_account = False

    def wrong_password():
        raise ValidationError({
            'password':
            "******"
            "Please try again (make sure your caps lock is off)."
        })

    def wrong_username(username):
        raise ValidationError({
            'username':
            """The username you entered, "{}", doesn't exist. """.format(
                username) +
            """Please try again, or enter the e-mail address you used to sign up."""
        })

    def get_username_from_email(email):
        if not email:
            wrong_username(email)

        try:
            return User.objects.get(email=email).username
        except User.DoesNotExist:
            wrong_username(email)

    if not username and not email:
        raise ValidationError({'username': "******"})

    if not username:
        username = get_username_from_email(email)

    user = auth.authenticate(username=username, password=password)

    if user is None:
        # Maybe they entered an email into the username field?
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            try:
                #TODO This might be broken - should probably pass username.
                username = get_username_from_email(email)
                user = auth.authenticate(username=username, password=password)
            except ValidationError:
                # No such username exists.
                # See if it's a example.com account we need to migrate over.
                if User.is_username_reserved(username):
                    try:
                        user = User.migrate_canvas_user(request,
                                                        username,
                                                        password,
                                                        email=email)
                    except ValidationError as e:
                        wrong_password()
                    else:
                        migrated_from_canvas_account = True

    if user is None:
        wrong_password()

    if not user.is_active:
        return inactive_user_http_response()

    auth.login(request, user)

    return {
        'user': PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio': user.userinfo.bio_text,
        'user_subscribed_to_starred': is_subscribed(user, 'starred'),
        'sessionid': request.session.session_key,
        'migrated_from_canvas_account': migrated_from_canvas_account,
    }
Example #25
0
 def from_id(cls, user_id):
     from drawquest.apps.drawquest_auth.models import User
     return User.details_by_id(user_id, promoter=cls)()
Example #26
0
def signup(request, username, password, email, facebook_access_token=None):
    if check_rate_limit(request, username):
        raise ServiceError(
            "Too many signup attempts. Wait a minute and try again.")

    try:
        return _login(request, password, username=username, email=email)
    except ValidationError:
        pass

    migrated_from_canvas_account = False
    errors = defaultdict(list)

    fb_user = None
    if facebook_access_token:
        fb_user = FacebookUser.create_from_access_token(facebook_access_token)

    def username_taken():
        # Ugly hack.
        for error in errors['username']:
            if 'taken' in error:
                return

        errors['username'].append("Sorry! That username is already taken.")

    if not password:
        errors['password'].append("Please enter a password.")

    if not User.validate_password(password):
        errors['password'].append("Sorry, your password is too short. "
                                  "Please use {} or more characters.".format(
                                      User.MINIMUM_PASSWORD_LENGTH))

    if not email:
        errors['email'].append("Please enter your email address.")
    elif not User.validate_email(email):
        errors['email'].append("Please enter a valid email address.")

    username_error = User.validate_username(username)
    if username_error:
        errors['username'].append(username_error)

    if not User.email_is_unused(email):
        errors['email'].append(
            "Sorry! That email address is already being used for an account.")
    elif User.is_username_reserved(username):
        try:
            user = User.migrate_canvas_user(request,
                                            username,
                                            password,
                                            email=email)
        except IntegrityError:
            username_taken()
        except ValidationError:
            errors['username'] = [
                """Sorry! This username is taken. Please pick a different username, """
                + """or if you are "{}," enter your password to sign in.""".
                format(username)
            ]
        else:
            migrated_from_canvas_account = True

    if errors:
        if fb_user:
            fb_user.delete()
        raise ValidationError(errors)

    if not migrated_from_canvas_account:
        try:
            user = User.objects.create_user(username, email, password)
        except IntegrityError:
            username_taken()
            raise ValidationError(errors)

        UserInfo.objects.create(user=user)

    if fb_user:
        fb_user.user = user
        fb_user.save()
        fb_user.notify_friends_of_signup(facebook_access_token)

        user.migrate_facebook_avatar(request, facebook_access_token)

    user = auth.authenticate(username=username, password=password)

    # auth.login starts a new session and copies the session data from the old one to the new one
    auth.login(request, user)

    return {
        'user': PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio': user.userinfo.bio_text,
        'user_subscribed_to_starred': is_subscribed(user, 'starred'),
        'sessionid': request.session.session_key,
        'migrated_from_canvas_account': migrated_from_canvas_account,
    }
Example #27
0
def signup(request, username, password, email,
           facebook_access_token=None,
           twitter_access_token=None, twitter_access_token_secret=None):
    if check_rate_limit(request, username):
        raise ServiceError(_("Too many signup attempts. Wait a minute and try again."))

    if not _validate_charset(username):
        raise ValidationError({
            'username': [_("Usernames can only contain the letters a-z or A-Z, digits, and underscores.")],
        })

    if not _validate_charset(email):
        raise ValidationError({
            'email': [_("Sorry, your email address contains invalid characters. Please remove them and try again.")],
        })

    try:
        return _login(request, password, username=username, email=email)
    except ValidationError:
        pass

    errors = defaultdict(list)

    fb_user = None
    twitter_user = None

    if facebook_access_token:
        fb_user = FacebookUser.get_or_create_from_access_token(facebook_access_token)
    elif twitter_access_token and twitter_access_token_secret:
        twitter_user = TwitterUser.get_or_create_from_access_token(twitter_access_token, twitter_access_token_secret)

    def username_taken():
        # Ugly hack.
        for error in errors['username']:
            if 'taken' in error:
                return

        errors['username'].append(_("Sorry! That username is already taken."))

    if not password:
        errors['password'].append(_("Please enter a password."))

    if not User.validate_password(password):
        errors['password'].append(_(u"Sorry, your password is too short. Please use %(count)d or more characters." % {'count': User.MINIMUM_PASSWORD_LENGTH}))

    if not email:
        errors['email'].append(_("Please enter your email address."))
    elif not User.validate_email(email):
        errors['email'].append(_("Please enter a valid email address."))

    username_error = User.validate_username(username)
    if username_error:
        errors['username'].append(username_error)

    if not User.email_is_unused(email):
        errors['email'].append(_("Sorry! That email address is already being used for an account. Try signing in instead, or use another email address."))

    if errors:
        if fb_user:
            fb_user.delete()
        raise ValidationError(errors)

    try:
        user = User.objects.create_user(username, email, password)
    except IntegrityError:
        username_taken()
        raise ValidationError(errors)

    ui = UserInfo.objects.create(user=user)
    ui.update_hashes()

    if request.app_version is not None:
        user.kv.signup_app_version.set(request.app_version)

    if fb_user:
        fb_user.user = user
        fb_user.save()

        fb_user.notify_friends_of_signup(facebook_access_token)
        fb_user.respond_to_apprequest_invites(facebook_access_token)

        user.migrate_facebook_avatar(request, facebook_access_token)
    elif twitter_user:
        twitter_user.user = user
        twitter_user.save()

        twitter_user.notify_followers_of_signup(twitter_access_token, twitter_access_token_secret)
        twitter_user.auto_follow_from_invite(twitter_access_token, twitter_access_token_secret)

        @bgwork.defer
        def migrate_twitter_avatar():
            user.migrate_twitter_avatar(request, twitter_access_token, twitter_access_token_secret)

    user = auth.authenticate(username=username, password=password)

    # auth.login starts a new session and copies the session data from the old one to the new one
    auth.login(request, user)

    return {
        'user': PrivateUserDetails.from_id(user.id).to_client(),
        'user_bio': user.userinfo.bio_text,
        'user_subscribed_to_starred': is_subscribed(user, 'starred'),
        'comment_count': 0,
        'quest_count': Quest.all_objects.filter(author=user).count(),
        'sessionid': request.session.session_key,
        'migrated_from_canvas_account': False,
        'login': False,
        'heavy_state_sync': heavy_state_sync(request.user, app_version=request.app_version, app_version_tuple=request.app_version_tuple),
    }