def resend_confirmation(auth): user = auth.user data = request.get_json() validate_user(data, user) try: primary = data['email']['primary'] confirmed = data['email']['confirmed'] address = data['email']['address'].strip().lower() except KeyError: raise HTTPError(httplib.BAD_REQUEST) if primary or confirmed: raise HTTPError(httplib.BAD_REQUEST, data={'message_long': 'Cannnot resend confirmation for confirmed emails'}) user.add_unconfirmed_email(address) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) user.save() return _profile_view(user, is_profile=True)
def resend_confirmation(auth): user = auth.user data = request.get_json() validate_user(data, user) try: primary = data['email']['primary'] confirmed = data['email']['confirmed'] address = data['email']['address'].strip().lower() except KeyError: raise HTTPError(httplib.BAD_REQUEST) if primary or confirmed: raise HTTPError(httplib.BAD_REQUEST, data={ 'message_long': 'Cannnot resend confirmation for confirmed emails' }) user.add_unconfirmed_email(address) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) user.save() return _profile_view(user, is_profile=True)
def resend_confirmation(auth): user = auth.user data = request.get_json() validate_user(data, user) if not throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE): raise HTTPError( httplib.BAD_REQUEST, data={"message_long": "Too many requests. Please wait a while before sending another confirmation email."}, ) try: primary = data["email"]["primary"] confirmed = data["email"]["confirmed"] address = data["email"]["address"].strip().lower() except KeyError: raise HTTPError(httplib.BAD_REQUEST) if primary or confirmed: raise HTTPError(httplib.BAD_REQUEST, data={"message_long": "Cannnot resend confirmation for confirmed emails"}) user.add_unconfirmed_email(address) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) user.email_last_sent = datetime.datetime.utcnow() user.save() return _profile_view(user, is_profile=True)
def resend_confirmation(auth): user = auth.user data = request.get_json() validate_user(data, user) if not throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE): raise HTTPError(http_status.HTTP_400_BAD_REQUEST, data={'message_long': 'Too many requests. Please wait a while before sending another confirmation email.'}) try: primary = data['email']['primary'] confirmed = data['email']['confirmed'] address = data['email']['address'].strip().lower() except KeyError: raise HTTPError(http_status.HTTP_400_BAD_REQUEST) if primary or confirmed: raise HTTPError(http_status.HTTP_400_BAD_REQUEST, data={'message_long': 'Cannnot resend confirmation for confirmed emails'}) user.add_unconfirmed_email(address) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) user.email_last_sent = timezone.now() user.save() return _profile_view(user, is_profile=True)
def create(self, validated_data): user = self.context['request'].user address = validated_data['address'] is_merge = Email.objects.filter(address=address).exists() if address in user.unconfirmed_emails or address in user.emails.all( ).values_list('address', flat=True): raise Conflict( 'This user already has registered with the email address {}'. format(address)) try: token = user.add_unconfirmed_email(address) user.save() if CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) user.email_last_sent = timezone.now() user.save() except ValidationError as e: raise exceptions.ValidationError(e.args[0]) except BlacklistedEmailError: raise exceptions.ValidationError( 'This email address domain is blacklisted.') return UserEmail(email_id=token, address=address, confirmed=False, verified=False, primary=False, is_merge=is_merge)
def test_user_external_unconfirmed(self, app, institution, url_auth_institution): # Create an unconfirmed user with pending external identity username, fullname = '*****@*****.**', 'Foo Bar' external_id_provider, external_id, status = 'ORCID', '1234-1234-1234-1234', 'CREATE' external_identity = {external_id_provider: {external_id: status}} accepted_terms_of_service = timezone.now() user = OSFUser.create_unconfirmed( username=username, password=None, fullname=fullname, external_identity=external_identity, campaign=None, accepted_terms_of_service=accepted_terms_of_service ) user.save() assert not user.has_usable_password() assert user.external_identity # Send confirm email in order to add new email verifications send_confirm_email( user, user.username, external_id_provider=external_id_provider, external_id=external_id ) user.save() assert user.email_verifications email_verifications = user.email_verifications with capture_signals() as mock_signals: res = app.post( url_auth_institution, make_payload( institution, username, family_name='User', given_name='Fake', fullname='Fake User', department='Fake User', ), expect_errors=True ) assert res.status_code == 403 assert not mock_signals.signals_sent() user = OSFUser.objects.filter(username=username).first() assert user # User remains untouched, including affiliation, external identity email verifcaitons assert user.fullname == fullname assert user.given_name == 'Foo' assert user.family_name == 'Bar' assert institution not in user.affiliated_institutions.all() assert external_identity == user.external_identity assert email_verifications == user.email_verifications assert accepted_terms_of_service == user.accepted_terms_of_service assert not user.has_usable_password()
def create(self, validated_data): user = self.context['request'].user address = validated_data['address'] if address in user.unconfirmed_emails or address in user.emails.all().values_list('address', flat=True): raise Conflict('This user already has registered with the email address {}'.format(address)) try: token = user.add_unconfirmed_email(address) user.save() if CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) except ValidationError as e: raise exceptions.ValidationError(e.args[0]) return UserEmail(email_id=token, address=address, confirmed=False, primary=False)
def get_object(self): email_id = self.kwargs['email_id'] user = self.get_user() email = None # check to see if it's a confirmed email with hashed id decoded_id = hashids.decode(email_id) if decoded_id: try: email = user.emails.get(id=decoded_id[0]) except Email.DoesNotExist: email = None else: primary = email.address == user.username address = email.address confirmed = True verified = True is_merge = False # check to see if it's an unconfirmed email with a token elif user.unconfirmed_emails: try: email = user.email_verifications[email_id] address = email['email'] confirmed = email['confirmed'] verified = False primary = False is_merge = Email.objects.filter(address=address).exists() except KeyError: email = None if not email: raise NotFound # check for resend confirmation email query parameter in a GET request if self.request.method == 'GET' and is_truthy( self.request.query_params.get('resend_confirmation')): if not confirmed and settings.CONFIRM_REGISTRATIONS_BY_EMAIL: if throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE): send_confirm_email(user, email=address, renew=True) user.email_last_sent = timezone.now() user.save() return UserEmail(email_id=email_id, address=address, confirmed=confirmed, verified=verified, primary=primary, is_merge=is_merge)
def create(self, validated_data): user = self.context['request'].user address = validated_data['address'] if address in user.unconfirmed_emails or address in user.emails.all().values_list('address', flat=True): raise Conflict('This user already has registered with the email address {}'.format(address)) try: token = user.add_unconfirmed_email(address) user.save() if CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) except ValidationError as e: raise exceptions.ValidationError(e.args[0]) except BlacklistedEmailError: raise exceptions.ValidationError('This email address domain is blacklisted.') return UserEmail(email_id=token, address=address, confirmed=False, primary=False)
def get_object(self): email_id = self.kwargs['email_id'] user = self.get_user() email = None # check to see if it's a confirmed email with hashed id decoded_id = hashids.decode(email_id) if decoded_id: try: email = user.emails.get(id=decoded_id[0]) except Email.DoesNotExist: email = None else: primary = email.address == user.username address = email.address confirmed = True verified = True is_merge = False # check to see if it's an unconfirmed email with a token elif user.unconfirmed_emails: try: email = user.email_verifications[email_id] address = email['email'] confirmed = email['confirmed'] verified = False primary = False is_merge = Email.objects.filter(address=address).exists() except KeyError: email = None if not email: raise NotFound # check for resend confirmation email query parameter in a GET request if self.request.method == 'GET' and is_truthy(self.request.query_params.get('resend_confirmation')): if not confirmed and settings.CONFIRM_REGISTRATIONS_BY_EMAIL: if throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE): send_confirm_email(user, email=address, renew=True) user.email_last_sent = timezone.now() user.save() return UserEmail(email_id=email_id, address=address, confirmed=confirmed, verified=verified, primary=primary, is_merge=is_merge)
def create(self, validated_data): username = validated_data.get('username', '').lower() or None full_name = validated_data.get('fullname') if not full_name: raise JSONAPIException('A `full_name` is required to create a user.') user = User.create_unregistered(full_name, email=username) user.registered_by = self.context['request'].user if username: user.add_unconfirmed_email(user.username) try: user.save() except ValidationValueError: raise Conflict('User with specified username already exists.') if self.context['request'].GET.get('send_email', False) and username: send_confirm_email(user, user.username) return user
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() validate_user(data, user) # TODO: Expand this to support other user attributes ########## # Emails # ########## if 'emails' in data: emails_list = [x['address'].strip().lower() for x in data['emails']] if user.username not in emails_list: raise HTTPError(httplib.FORBIDDEN) # removals removed_emails = [ each for each in user.emails + user.unconfirmed_emails if each not in emails_list ] if user.username in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if address in user.emails: try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) user.remove_unconfirmed_email(address) # additions added_emails = [ each['address'].strip().lower() for each in data['emails'] if each['address'].strip().lower() not in user.emails and each['address'].strip().lower() not in user.unconfirmed_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): continue # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next( ( each for each in data['emails'] # email is primary if each.get('primary') and each.get('confirmed') # an address is specified (can't trust those sneaky users!) and each.get('address') ) ) if primary_email: primary_email_address = primary_email['address'].strip().lower() if primary_email_address not in user.emails: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username in user.emails and username != user.username: mails.send_mail(user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username) user.username = username ################### # Timezone/Locale # ################### if 'locale' in data: if data['locale']: locale = data['locale'].replace('-', '_') user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if 'timezone' in data: if data['timezone']: user.timezone = data['timezone'] user.save() return _profile_view(user)
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() validate_user(data, user) # TODO: Expand this to support other user attributes ########## # Emails # ########## if "emails" in data: emails_list = [x["address"].strip().lower() for x in data["emails"]] if user.username.strip().lower() not in emails_list: raise HTTPError(httplib.FORBIDDEN) available_emails = [each.strip().lower() for each in user.emails + user.unconfirmed_emails] # removals removed_emails = [each.strip().lower() for each in available_emails if each not in emails_list] if user.username.strip().lower() in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if address in user.emails: try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) user.remove_unconfirmed_email(address) # additions added_emails = [ each["address"].strip().lower() for each in data["emails"] if each["address"].strip().lower() not in available_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): raise HTTPError(http.BAD_REQUEST, data=dict(message_long="Invalid Email")) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next( ( each for each in data["emails"] # email is primary if each.get("primary") and each.get("confirmed") # an address is specified (can't trust those sneaky users!) and each.get("address") ) ) if primary_email: primary_email_address = primary_email["address"].strip().lower() if primary_email_address not in [each.strip().lower() for each in user.emails]: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username in user.emails and username != user.username: mails.send_mail(user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username) # Remove old primary email from subscribed mailing lists for list_name, subscription in user.mailchimp_mailing_lists.iteritems(): if subscription: mailchimp_utils.unsubscribe_mailchimp_async(list_name, user._id, username=user.username) user.username = username ################### # Timezone/Locale # ################### if "locale" in data: if data["locale"]: locale = data["locale"].replace("-", "_") user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if "timezone" in data: if data["timezone"]: user.timezone = data["timezone"] user.save() # Update subscribed mailing lists with new primary email # TODO: move to user.save() for list_name, subscription in user.mailchimp_mailing_lists.iteritems(): if subscription: mailchimp_utils.subscribe_mailchimp(list_name, user._id) return _profile_view(user, is_profile=True)
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() validate_user(data, user) # TODO: Expand this to support other user attributes ########## # Emails # ########## if 'emails' in data: emails_list = [x['address'].strip().lower() for x in data['emails']] if user.username.strip().lower() not in emails_list: raise HTTPError(httplib.FORBIDDEN) available_emails = [ each.strip().lower() for each in list(user.emails.values_list('address', flat=True)) + user.unconfirmed_emails ] # removals removed_emails = [ each.strip().lower() for each in available_emails if each not in emails_list ] if user.username.strip().lower() in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if user.emails.filter(address=address): try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) user.remove_unconfirmed_email(address) # additions added_emails = [ each['address'].strip().lower() for each in data['emails'] if each['address'].strip().lower() not in available_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): raise HTTPError(http.BAD_REQUEST, data=dict( message_long='Invalid Email') ) except BlacklistedEmailError: raise HTTPError(http.BAD_REQUEST, data=dict( message_long=language.BLACKLISTED_EMAIL) ) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next( ( each for each in data['emails'] # email is primary if each.get('primary') and each.get('confirmed') # an address is specified (can't trust those sneaky users!) and each.get('address') ) ) if primary_email: primary_email_address = primary_email['address'].strip().lower() if primary_email_address not in [each.strip().lower() for each in user.emails.values_list('address', flat=True)]: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username != user.username and user.emails.filter(address=username).exists(): mails.send_mail( user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username, can_change_preferences=False, osf_contact_email=settings.OSF_CONTACT_EMAIL ) # Remove old primary email from subscribed mailing lists for list_name, subscription in user.mailchimp_mailing_lists.iteritems(): if subscription: mailchimp_utils.unsubscribe_mailchimp_async(list_name, user._id, username=user.username) user.username = username ################### # Timezone/Locale # ################### if 'locale' in data: if data['locale']: locale = data['locale'].replace('-', '_') user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if 'timezone' in data: if data['timezone']: user.timezone = data['timezone'] user.save() # Update subscribed mailing lists with new primary email # TODO: move to user.save() for list_name, subscription in user.mailchimp_mailing_lists.iteritems(): if subscription: mailchimp_utils.subscribe_mailchimp(list_name, user._id) return _profile_view(user, is_profile=True)
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() validate_user(data, user) # TODO: Expand this to support other user attributes ########## # Emails # ########## if 'emails' in data: emails_list = [x['address'].strip().lower() for x in data['emails']] if user.username.strip().lower() not in emails_list: raise HTTPError(httplib.FORBIDDEN) available_emails = [ each.strip().lower() for each in user.emails + user.unconfirmed_emails ] # removals removed_emails = [ each.strip().lower() for each in available_emails if each not in emails_list ] if user.username.strip().lower() in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if address in user.emails: try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) user.remove_unconfirmed_email(address) # additions added_emails = [ each['address'].strip().lower() for each in data['emails'] if each['address'].strip().lower() not in available_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): raise HTTPError(http.BAD_REQUEST, data=dict(message_long="Invalid Email")) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next(( each for each in data['emails'] # email is primary if each.get('primary') and each.get('confirmed') # an address is specified (can't trust those sneaky users!) and each.get('address'))) if primary_email: primary_email_address = primary_email['address'].strip().lower() if primary_email_address not in [ each.strip().lower() for each in user.emails ]: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username in user.emails and username != user.username: mails.send_mail(user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username) # Remove old primary email from subscribed mailing lists for list_name, subscription in user.mailchimp_mailing_lists.iteritems( ): if subscription: mailchimp_utils.unsubscribe_mailchimp_async( list_name, user._id, username=user.username) user.username = username ################### # Timezone/Locale # ################### if 'locale' in data: if data['locale']: locale = data['locale'].replace('-', '_') user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if 'timezone' in data: if data['timezone']: user.timezone = data['timezone'] user.save() # Update subscribed mailing lists with new primary email # TODO: move to user.save() for list_name, subscription in user.mailchimp_mailing_lists.iteritems(): if subscription: mailchimp_utils.subscribe_mailchimp(list_name, user._id) return _profile_view(user, is_profile=True)
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() validate_user(data, user) # TODO: Expand this to support other user attributes ########## # Emails # ########## if 'emails' in data: emails_list = [x['address'].strip().lower() for x in data['emails']] if user.username.strip().lower() not in emails_list: raise HTTPError(httplib.FORBIDDEN) available_emails = [ each.strip().lower() for each in list(user.emails.values_list('address', flat=True)) + user.unconfirmed_emails ] # removals removed_emails = [ each.strip().lower() for each in available_emails if each not in emails_list ] if user.username.strip().lower() in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if user.emails.filter(address=address): try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, str(e)) user.remove_unconfirmed_email(address) # additions added_emails = [ each['address'].strip().lower() for each in data['emails'] if each['address'].strip().lower() not in available_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): raise HTTPError(http.BAD_REQUEST, data=dict(message_long='Invalid Email')) except BlacklistedEmailError: sentry.log_message('User attempted to add a blacklisted email', extra_data={ 'user_id': user.id, 'address': address, }) raise HTTPError( http.BAD_REQUEST, data=dict(message_long=language.BLACKLISTED_EMAIL)) # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: if not throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE): raise HTTPError( httplib.BAD_REQUEST, data={ 'message_long': 'Too many requests. Please wait a while before adding an email to your account.' }) send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next(( each for each in data['emails'] # email is primary if each.get('primary') and each.get('confirmed') # an address is specified (can't trust those sneaky users!) and each.get('address'))) if primary_email: primary_email_address = primary_email['address'].strip().lower() if primary_email_address not in [ each.strip().lower() for each in user.emails.values_list('address', flat=True) ]: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username != user.username and user.emails.filter( address=username).exists(): mails.send_mail(user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username, can_change_preferences=False, osf_contact_email=settings.OSF_CONTACT_EMAIL) # Remove old primary email from subscribed mailing lists for list_name, subscription in user.mailchimp_mailing_lists.items( ): if subscription: mailchimp_utils.unsubscribe_mailchimp_async( list_name, user._id, username=user.username) user.username = username ################### # Timezone/Locale # ################### if 'locale' in data: if data['locale']: locale = data['locale'].replace('-', '_') user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if 'timezone' in data: if data['timezone']: user.timezone = data['timezone'] user.save() # Update subscribed mailing lists with new primary email # TODO: move to user.save() for list_name, subscription in user.mailchimp_mailing_lists.items(): if subscription: mailchimp_utils.subscribe_mailchimp(list_name, user._id) return _profile_view(user, is_profile=True)
def update_user(auth): """Update the logged-in user's profile.""" # trust the decorator to handle auth user = auth.user data = request.get_json() # check if the user in request is the user who log in if 'id' in data: if data['id'] != user._id: raise HTTPError(httplib.FORBIDDEN) else: # raise an error if request doesn't have user id raise HTTPError(httplib.BAD_REQUEST, data={'message_long': '"id" is required'}) # TODO: Expand this to support other user attributes ########## # Emails # ########## if 'emails' in data: emails_list = [x['address'].strip().lower() for x in data['emails']] if user.username not in emails_list: raise HTTPError(httplib.FORBIDDEN) # removals removed_emails = [ each for each in user.emails + user.unconfirmed_emails if each not in emails_list ] if user.username in removed_emails: raise HTTPError(httplib.FORBIDDEN) for address in removed_emails: if address in user.emails: try: user.remove_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) try: user.remove_unconfirmed_email(address) except PermissionsError as e: raise HTTPError(httplib.FORBIDDEN, e.message) # additions added_emails = [ each['address'].strip().lower() for each in data['emails'] if each['address'].strip().lower() not in user.emails and each['address'].strip().lower() not in user.unconfirmed_emails ] for address in added_emails: try: user.add_unconfirmed_email(address) except (ValidationError, ValueError): continue # TODO: This setting is now named incorrectly. if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=address) ############ # Username # ############ # get the first email that is set to primary and has an address primary_email = next( ( each for each in data['emails'] # email is primary if each.get('primary') and each.get('confirmed') # an address is specified (can't trust those sneaky users!) and each.get('address') ) ) if primary_email: primary_email_address = primary_email['address'].strip().lower() if primary_email_address not in user.emails: raise HTTPError(httplib.FORBIDDEN) username = primary_email_address # make sure the new username has already been confirmed if username and username in user.emails and username != user.username: mails.send_mail(user.username, mails.PRIMARY_EMAIL_CHANGED, user=user, new_address=username) user.username = username ################### # Timezone/Locale # ################### if 'locale' in data: if data['locale']: locale = data['locale'].replace('-', '_') user.locale = locale # TODO: Refactor to something like: # user.timezone = data.get('timezone', user.timezone) if 'timezone' in data: if data['timezone']: user.timezone = data['timezone'] user.save() return _profile_view(user)