def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: raise wtforms.ValidationError(Markup( u'This email address is already registered. Do you want to <a href="{loginurl}">login</a> instead?'.format( loginurl=escape(url_for('.login')))))
def get_user_extid(service, userdata): """ Retrieves a 'user', 'extid' and 'useremail' from the given service and userdata. """ provider = login_registry[service] extid = getextid(service=service, userid=userdata['userid']) user = None useremail = None if userdata.get('email'): useremail = UserEmail.get(email=userdata['email']) if extid is not None: user = extid.user # It is possible at this time that extid.user and useremail.user are different. # We do not handle it here, but in the parent function login_service_postcallback. elif useremail is not None and useremail.user is not None: user = useremail.user else: # Cross-check with all other instances of the same LoginProvider (if we don't have a user) # This is (for eg) for when we have two Twitter services with different access levels. for other_service, other_provider in login_registry.items(): if other_service != service and other_provider.__class__ == provider.__class__: other_extid = getextid(service=other_service, userid=userdata['userid']) if other_extid is not None: user = other_extid.user break # TODO: Make this work when we have multiple confirmed email addresses available return user, extid, useremail
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: raise wtforms.ValidationError( Markup( u'This email address is already registered. Do you want to <a href="{loginurl}">login</a> instead?' .format(loginurl=escape(url_for('.login')))))
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: if existing.user == g.user: raise forms.ValidationError(_("You have already registered this email address")) else: raise forms.ValidationError(_("This email address has already been claimed")) existing = UserEmailClaim.get(email=field.data, user=g.user) if existing is not None: raise forms.ValidationError(_("This email address is pending verification"))
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: if existing.user == g.user: raise wtforms.ValidationError( "You have already registered this email address.") else: raise wtforms.ValidationError( "This email address has already been claimed.") existing = UserEmailClaim.get(email=field.data, user=g.user) if existing is not None: raise wtforms.ValidationError( "This email address is pending verification.")
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: if existing.user == current_auth.user: raise forms.ValidationError( _("You have already registered this email address")) else: raise forms.ValidationError( _("This email address has already been claimed")) existing = UserEmailClaim.get_for(user=current_auth.user, email=field.data) if existing is not None: raise forms.ValidationError( _("This email address is pending verification"))
def login_service_postcallback(service, userdata): """ Called from :func:login_service_callback after receiving data from the upstream login service """ # 1. Check whether we have an existing UserExternalId user, extid, useremail = get_user_extid(service, userdata) # If extid is not None, user.extid == user, guaranteed. # If extid is None but useremail is not None, user == useremail.user # However, if both extid and useremail are present, they may be different users if extid is not None: extid.oauth_token = userdata.get('oauth_token') extid.oauth_token_secret = userdata.get('oauth_token_secret') extid.oauth_token_type = userdata.get('oauth_token_type') extid.username = userdata.get('username') # TODO: Save refresh token and expiry date where present extid.oauth_refresh_token = userdata.get('oauth_refresh_token') extid.oauth_expiry_date = userdata.get('oauth_expiry_date') extid.oauth_refresh_expiry = userdata.get( 'oauth_refresh_expiry') # TODO: Check this extid.last_used_at = db.func.utcnow() else: # New external id. Register it. extid = UserExternalId( user=user, # This may be None right now. Will be handled below service=service, userid=userdata['userid'], username=userdata.get('username'), oauth_token=userdata.get('oauth_token'), oauth_token_secret=userdata.get('oauth_token_secret'), oauth_token_type=userdata.get('oauth_token_type'), last_used_at=db.func.utcnow() # TODO: Save refresh token ) if user is None: if current_auth: # Attach this id to currently logged-in user user = current_auth.user extid.user = user else: # Register a new user user = register_internal(None, userdata.get('fullname'), None) extid.user = user if userdata.get('username'): if valid_username(userdata['username']) and user.is_valid_name( userdata['username']): # Set a username for this user if it's available user.username = userdata['username'] else: # We have an existing user account from extid or useremail if current_auth and current_auth.user != user: # Woah! Account merger handler required # Always confirm with user before doing an account merger session['merge_buid'] = user.buid elif useremail and useremail.user != user: # Once again, account merger required since the extid and useremail are linked to different users session['merge_buid'] = useremail.user.buid # Check for new email addresses if userdata.get('email') and not useremail: user.add_email(userdata['email']) # If there are multiple email addresses, add any that are not already claimed. # If they are already claimed by another user, this calls for an account merge # request, but we can only merge two users at a time. Ask for a merge if there # isn't already one pending if userdata.get('emails'): for email in userdata['emails']: existing = UserEmail.get(email) if existing: if existing.user != user and 'merge_buid' not in session: session['merge_buid'] = existing.user.buid else: user.add_email(email) if userdata.get('emailclaim'): emailclaim = UserEmailClaim(user=user, email=userdata['emailclaim']) db.session.add(emailclaim) send_email_verify_link(emailclaim) # Is the user's fullname missing? Populate it. if not user.fullname and userdata.get('fullname'): user.fullname = userdata['fullname'] if not current_auth: # If a user isn't already logged in, login now. login_internal(user) flash( _("You have logged in via {service}").format( service=login_registry[service].title), 'success', ) next_url = get_next_url(session=True) db.session.add(extid) # If we made a new extid, add it to the session now db.session.commit() # Finally: set a login method cookie and send user on their way if not current_auth.user.is_profile_complete(): login_next = url_for('.account_new', next=next_url) else: login_next = next_url if 'merge_buid' in session: return set_loginmethod_cookie( redirect(url_for('.account_merge', next=login_next), code=303), service) else: return set_loginmethod_cookie(redirect(login_next, code=303), service)
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None and existing.user != self.edit_obj: raise wtforms.ValidationError("This email address has been claimed by another user")
def validate_email(self, field): existing = UserEmail.get(email=field.data) if existing is not None and existing.user != self.edit_obj: raise forms.ValidationError(_("This email address has been claimed by another user"))
def validate_email(self, field): existing = UserEmail.get(email=field.data) if existing is not None and existing.user != self.edit_obj: raise forms.ValidationError( _("This email address has been claimed by another user"))
def login_service_postcallback(service, userdata): """ Called from :func:login_service_callback after receiving data from the upstream login service """ # 1. Check whether we have an existing UserExternalId user, extid, useremail = get_user_extid(service, userdata) # If extid is not None, user.extid == user, guaranteed. # If extid is None but useremail is not None, user == useremail.user # However, if both extid and useremail are present, they may be different users if extid is not None: extid.oauth_token = userdata.get('oauth_token') extid.oauth_token_secret = userdata.get('oauth_token_secret') extid.oauth_token_type = userdata.get('oauth_token_type') extid.username = userdata.get('username') # TODO: Save refresh token and expiry date where present extid.oauth_refresh_token = userdata.get('oauth_refresh_token') extid.oauth_expiry_date = userdata.get('oauth_expiry_date') extid.oauth_refresh_expiry = userdata.get('oauth_refresh_expiry') # TODO: Check this extid.last_used_at = db.func.utcnow() else: # New external id. Register it. extid = UserExternalId( user=user, # This may be None right now. Will be handled below service=service, userid=userdata['userid'], username=userdata.get('username'), oauth_token=userdata.get('oauth_token'), oauth_token_secret=userdata.get('oauth_token_secret'), oauth_token_type=userdata.get('oauth_token_type'), last_used_at=db.func.utcnow() # TODO: Save refresh token ) if user is None: if current_auth: # Attach this id to currently logged-in user user = current_auth.user extid.user = user else: # Register a new user user = register_internal(None, userdata.get('fullname'), None) extid.user = user if userdata.get('username'): if valid_username(userdata['username']) and user.is_valid_name(userdata['username']): # Set a username for this user if it's available user.username = userdata['username'] else: # We have an existing user account from extid or useremail if current_auth and current_auth.user != user: # Woah! Account merger handler required # Always confirm with user before doing an account merger session['merge_buid'] = user.buid elif useremail and useremail.user != user: # Once again, account merger required since the extid and useremail are linked to different users session['merge_buid'] = useremail.user.buid # Check for new email addresses if userdata.get('email') and not useremail: user.add_email(userdata['email']) # If there are multiple email addresses, add any that are not already claimed. # If they are already claimed by another user, this calls for an account merge # request, but we can only merge two users at a time. Ask for a merge if there # isn't already one pending if userdata.get('emails'): for email in userdata['emails']: existing = UserEmail.get(email) if existing: if existing.user != user and 'merge_buid' not in session: session['merge_buid'] = existing.user.buid else: user.add_email(email) if userdata.get('emailclaim'): emailclaim = UserEmailClaim(user=user, email=userdata['emailclaim']) db.session.add(emailclaim) send_email_verify_link(emailclaim) # Is the user's fullname missing? Populate it. if not user.fullname and userdata.get('fullname'): user.fullname = userdata['fullname'] if not current_auth: # If a user isn't already logged in, login now. login_internal(user) flash(_(u"You have logged in via {service}").format(service=login_registry[service].title), 'success') next_url = get_next_url(session=True) db.session.add(extid) # If we made a new extid, add it to the session now db.session.commit() # Finally: set a login method cookie and send user on their way if not current_auth.user.is_profile_complete(): login_next = url_for('.account_new', next=next_url) else: login_next = next_url if 'merge_buid' in session: return set_loginmethod_cookie(redirect(url_for('.account_merge', next=login_next), code=303), service) else: return set_loginmethod_cookie(redirect(login_next, code=303), service)
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None and existing.user != self.edit_obj: raise wtforms.ValidationError( "This email address has been claimed by another user")
def login_service_postcallback(service, userdata): user, extid, useremail = get_user_extid(service, userdata) if extid is not None: extid.oauth_token = userdata.get("oauth_token") extid.oauth_token_secret = userdata.get("oauth_token_secret") extid.oauth_token_type = userdata.get("oauth_token_type") extid.username = userdata.get("username") # TODO: Save refresh token and expiry date where present extid.oauth_refresh_token = userdata.get("oauth_refresh_token") extid.oauth_expiry_date = userdata.get("oauth_expiry_date") extid.oauth_refresh_expiry = userdata.get("oauth_refresh_expiry") # TODO: Check this else: # New external id. Register it. extid = UserExternalId( user=user, # This may be None right now. Will be handled below service=service, userid=userdata["userid"], username=userdata.get("username"), oauth_token=userdata.get("oauth_token"), oauth_token_secret=userdata.get("oauth_token_secret"), oauth_token_type=userdata.get("oauth_token_type") # TODO: Save refresh token ) db.session.add(extid) if user is None: if g.user: # Attach this id to currently logged-in user user = g.user extid.user = user else: # Register a new user user = register_internal(None, userdata.get("fullname"), None) extid.user = user if userdata.get("username"): if valid_username(userdata["username"]) and user.is_valid_username(userdata["username"]): # Set a username for this user if it's available user.username = userdata["username"] else: # This id is attached to a user if g.user and g.user != user: # Woah! Account merger handler required # Always confirm with user before doing an account merger session["merge_userid"] = user.userid # Check for new email addresses if userdata.get("email") and not useremail: user.add_email(userdata["email"]) # If there are multiple email addresses, add any that are not already claimed. # If they are already claimed by another user, this calls for an account merge # request, but we can only merge two users at a time. Ask for a merge if there # isn't already one pending if userdata.get("emails"): for email in userdata["emails"]: existing = UserEmail.get(email) if existing: if existing.user != user and "merge_userid" not in session: session["merge_userid"] = existing.user.userid else: user.add_email(email) if userdata.get("emailclaim"): emailclaim = UserEmailClaim(user=user, email=userdata["emailclaim"]) db.session.add(emailclaim) send_email_verify_link(emailclaim) # Is the user's fullname missing? Populate it. if not user.fullname and userdata.get("fullname"): user.fullname = userdata["fullname"] if not g.user: # If a user isn't already logged in, login now. login_internal(user) flash(_(u"You have logged in via {service}").format(service=login_registry[service].title), "success") next_url = get_next_url(session=True) db.session.commit() # Finally: set a login method cookie and send user on their way if not user.is_profile_complete(): login_next = url_for(".profile_new", next=next_url) else: login_next = next_url if "merge_userid" in session: return set_loginmethod_cookie(redirect(url_for(".profile_merge", next=login_next), code=303), service) else: return set_loginmethod_cookie(redirect(login_next, code=303), service)
def confirm_email(md5sum, secret): emailclaim = UserEmailClaim.get_by(md5sum=md5sum, verification_code=secret) if emailclaim is not None: if 'verify' in emailclaim.permissions(current_auth.user): existing = UserEmail.get(email=emailclaim.email) if existing is not None: claimed_email = emailclaim.email claimed_user = emailclaim.user db.session.delete(emailclaim) db.session.commit() if claimed_user != current_auth.user: return render_message( title=_("Email address already claimed"), message=Markup( _( "The email address <code>{email}</code> has already been verified by another user" ).format(email=escape(claimed_email)) ), ) else: return render_message( title=_("Email address already verified"), message=Markup( _( "Hello <strong>{fullname}</strong>! " "Your email address <code>{email}</code> has already been verified" ).format( fullname=escape(claimed_user.fullname), email=escape(claimed_email), ) ), ) useremail = emailclaim.user.add_email( emailclaim.email, primary=emailclaim.user.email is None, type=emailclaim.type, private=emailclaim.private, ) db.session.delete(emailclaim) UserEmailClaim.all(useremail.email).delete(synchronize_session=False) db.session.commit() user_data_changed.send(current_auth.user, changes=['email']) return render_message( title=_("Email address verified"), message=Markup( _( "Hello <strong>{fullname}</strong>! " "Your email address <code>{email}</code> has now been verified" ).format( fullname=escape(emailclaim.user.fullname), email=escape(useremail.email), ) ), ) else: return render_message( title=_("This was not for you"), message=_( "You’ve opened an email verification link that was meant for another user. " "If you are managing multiple accounts, please login with the correct account " "and open the link again" ), code=403, ) else: return render_message( title=_("Expired confirmation link"), message=_( "The confirmation link you clicked on is either invalid or has expired" ), code=404, )