def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) username = d.get_sysname(form.username) # Determine the user associated with `username`; if the user is not found, # raise an exception user = d.engine.execute( "SELECT userid, email FROM login WHERE login_name = %(username)s", username=username).first() if not user: raise WeasylError("loginRecordMissing") # Check the user's email address against the provided e-mail address, # raising an exception if there is a mismatch if email != emailer.normalize_address(user.email): raise WeasylError("emailInvalid") # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() d.engine.execute(""" INSERT INTO forgotpassword (userid, token, set_time, address) VALUES (%(id)s, %(token)s, %(time)s, %(address)s) ON CONFLICT (userid) DO UPDATE SET token = %(token)s, set_time = %(time)s, address = %(address)s """, id=user.userid, token=token, time=now, address=address) # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def control_editemailpassword_post_(request): form = request.web_input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) # Check if the email was invalid; Both fields must be valid (not None), and have the form fields set if not newemail and not newemailcheck and form.newemail != "" and form.newemailcheck != "": raise WeasylError("emailInvalid") return_message = profile.edit_email_password(request.userid, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck) if not return_message: # No changes were made message = "No changes were made to your account." else: # Changes were made, so inform the user of this message = "**Success!** " + return_message # Finally return the message about what (if anything) changed to the user return Response( define.errorpage(request.userid, message, [["Go Back", "/control"], ["Return Home", "/"]]))
def create(form): # Normalize form data username = d.plaintext(form.username[:_USERNAME]) sysname = d.get_sysname(username) email = emailer.normalize_address(form.email) emailcheck = emailer.normalize_address(form.emailcheck) password = form.password passcheck = form.passcheck if form.day and form.month and form.year: try: birthday = arrow.Arrow(int(form.year), int(form.month), int(form.day)) except ValueError: raise WeasylError("birthdayInvalid") else: birthday = None # Check mismatched form data if password != passcheck: raise WeasylError("passwordMismatch") if email != emailcheck: raise WeasylError("emailMismatch") # Check invalid form data if birthday is None or d.age_in_years(birthday) < 13: raise WeasylError("birthdayInvalid") if not password_secure(password): raise WeasylError("passwordInsecure") if not email: raise WeasylError("emailInvalid") if not sysname or ";" in username: raise WeasylError("usernameInvalid") if sysname in ["admin", "administrator", "mod", "moderator", "weasyl", "weasyladmin", "weasylmod", "staff", "security"]: raise WeasylError("usernameInvalid") if email_exists(email): raise WeasylError("emailExists") if username_exists(sysname): raise WeasylError("usernameExists") # Create pending account token = security.generate_key(40) d.engine.execute(d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": email, "birthday": birthday, "unixtime": arrow.now(), }) # Queue verification email emailer.append([email], None, "Weasyl Account Creation", d.render( "email/verify_account.html", [token, sysname])) d.metric('increment', 'createdusers')
def control_editemailpassword_post_(request): form = request.web_input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) profile.edit_email_password(request.userid, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck) return Response(define.errorpage( request.userid, "**Success!** Your settings have been updated.", [["Go Back", "/control"], ["Return Home", "/"]]))
def POST(self): form = web.input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) profile.edit_email_password(self.user_id, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck) return define.errorpage( self.user_id, "**Success!** Your settings have been updated.", [["Go Back", "/control"], ["Return Home", "/"]])
def control_editemailpassword_post_(request): form = request.web_input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) profile.edit_email_password(request.userid, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck) return Response(define.errorpage( request.userid, "**Success!** Your settings have been updated.", [["Go Back", "/control"], ["Return Home", "/"]]))
def reset(form): from weasyl import login # Raise an exception if `password` does not enter `passcheck` (indicating # that the user mistyped one of the fields) or if `password` does not meet # the system's password security requirements if form.password != form.passcheck: raise WeasylError("passwordMismatch") elif not login.password_secure(form.password): raise WeasylError("passwordInsecure") # Select the user information and record data from the forgotpassword table # pertaining to `token`, requiring that the link associated with the record # be visited no more than five minutes prior; if the forgotpassword record is # not found or does not meet this requirement, raise an exception query = d.engine.execute(""" SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address FROM login lo INNER JOIN userinfo ui USING (userid) INNER JOIN forgotpassword fp USING (userid) WHERE fp.token = %(token)s AND fp.link_time > %(cutoff)s """, token=form.token, cutoff=d.get_time() - 300).first() if not query: raise WeasylError("forgotpasswordRecordMissing") USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query # Check `username` and `email` against known correct values and raise an # exception if there is a mismatch if emailer.normalize_address( form.email) != emailer.normalize_address(EMAIL): raise WeasylError("emailIncorrect") elif d.get_sysname(form.username) != USERNAME: raise WeasylError("usernameIncorrect") elif d.get_address() != ADDRESS: raise WeasylError("addressInvalid") # Update the authbcrypt table with a new password hash d.engine.execute( 'INSERT INTO authbcrypt (userid, hashsum) VALUES (%(user)s, %(hash)s) ' 'ON CONFLICT (userid) DO UPDATE SET hashsum = %(hash)s', user=USERID, hash=login.passhash(form.password)) d.engine.execute("DELETE FROM forgotpassword WHERE token = %(token)s", token=form.token)
def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) # Determine the user associated with `username`; if the user is not found, # raise an exception user_id = d.engine.scalar(""" SELECT userid FROM login WHERE email = %(email)s """, email=email) # If `user_id` exists, then the supplied email was valid; if not valid, do nothing, raising # no errors for plausible deniability of email existence if user_id: # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() d.engine.execute(""" INSERT INTO forgotpassword (userid, token, set_time, address) VALUES (%(id)s, %(token)s, %(time)s, %(address)s) ON CONFLICT (userid) DO UPDATE SET token = %(token)s, set_time = %(time)s, address = %(address)s """, id=user_id, token=token, time=now, address=address) # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) # Determine the user associated with `username`; if the user is not found, # raise an exception user_id = d.engine.scalar(""" SELECT userid FROM login WHERE email = %(email)s """, email=email) # If `user_id` exists, then the supplied email was valid; if not valid, do nothing, raising # no errors for plausible deniability of email existence if user_id: # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() d.engine.execute(""" INSERT INTO forgotpassword (userid, token, set_time, address) VALUES (%(id)s, %(token)s, %(time)s, %(address)s) ON CONFLICT (userid) DO UPDATE SET token = %(token)s, set_time = %(time)s, address = %(address)s """, id=user_id, token=token, time=now, address=address) # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def reset(form): import login # Raise an exception if `password` does not enter `passcheck` (indicating # that the user mistyped one of the fields) or if `password` does not meet # the system's password security requirements if form.password != form.passcheck: raise WeasylError("passwordMismatch") elif not login.password_secure(form.password): raise WeasylError("passwordInsecure") # Select the user information and record data from the forgotpassword table # pertaining to `token`, requiring that the link associated with the record # be visited no more than five minutes prior; if the forgotpassword record is # not found or does not meet this requirement, raise an exception query = d.execute(""" SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address FROM login lo INNER JOIN userinfo ui USING (userid) INNER JOIN forgotpassword fp USING (userid) WHERE fp.token = '%s' AND fp.link_time > %i """, [form.token, d.get_time() - 300], options="single") if not query: raise WeasylError("forgotpasswordRecordMissing") USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query # Check `username` and `email` against known correct values and raise an # exception if there is a mismatch if emailer.normalize_address(form.email) != emailer.normalize_address(EMAIL): raise WeasylError("emailIncorrect") elif d.get_sysname(form.username) != USERNAME: raise WeasylError("usernameIncorrect") elif d.get_address() != ADDRESS: raise WeasylError("addressInvalid") # Update the authbcrypt table with a new password hash """ TODO TEMPORARY """ try: d.execute("INSERT INTO authbcrypt VALUES (%i, '')", [USERID]) except: pass d.execute("UPDATE authbcrypt SET hashsum = '%s' WHERE userid = %i", [login.passhash(form.password), USERID]) d.execute("DELETE FROM forgotpassword WHERE token = '%s'", [form.token])
def reset(form): import login # Raise an exception if `password` does not enter `passcheck` (indicating # that the user mistyped one of the fields) or if `password` does not meet # the system's password security requirements if form.password != form.passcheck: raise WeasylError("passwordMismatch") elif not login.password_secure(form.password): raise WeasylError("passwordInsecure") # Select the user information and record data from the forgotpassword table # pertaining to `token`, requiring that the link associated with the record # be visited no more than five minutes prior; if the forgotpassword record is # not found or does not meet this requirement, raise an exception query = d.execute(""" SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address FROM login lo INNER JOIN userinfo ui USING (userid) INNER JOIN forgotpassword fp USING (userid) WHERE fp.token = '%s' AND fp.link_time > %i """, [form.token, d.get_time() - 300], options="single") if not query: raise WeasylError("forgotpasswordRecordMissing") USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query # Check `username` and `email` against known correct values and raise an # exception if there is a mismatch if emailer.normalize_address(form.email) != emailer.normalize_address(EMAIL): raise WeasylError("emailIncorrect") elif d.get_sysname(form.username) != USERNAME: raise WeasylError("usernameIncorrect") elif d.get_address() != ADDRESS: raise WeasylError("addressInvalid") # Update the authbcrypt table with a new password hash """ TODO TEMPORARY """ try: d.execute("INSERT INTO authbcrypt VALUES (%i, '')", [USERID]) except: pass d.execute("UPDATE authbcrypt SET hashsum = '%s' WHERE userid = %i", [login.passhash(form.password), USERID]) d.execute("DELETE FROM forgotpassword WHERE token = '%s'", [form.token])
def POST(self): form = web.input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) profile.edit_email_password(self.user_id, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck) return define.errorpage( self.user_id, "**Success!** Your settings have been updated.", [["Go Back", "/control"], ["Return Home", "/"]])
def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) username = d.get_sysname(form.username) # Determine the user associated with `username`; if the user is not found, # raise an exception user = d.engine.execute( "SELECT userid, email FROM login WHERE login_name = %(username)s", username=username).first() if not user: raise WeasylError("loginRecordMissing") # Check the user's email address against the provided e-mail address, # raising an exception if there is a mismatch if email != emailer.normalize_address(user.email): raise WeasylError("emailInvalid") # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() try: d.engine.execute( "INSERT INTO forgotpassword (userid, token, set_time, address)" " VALUES (%(id)s, %(token)s, %(time)s, %(address)s)", id=user.userid, token=token, time=now, address=address) except IntegrityError: # An IntegrityError will probably indicate that a password reset request # already exists and that the existing row should be updated. If the update # doesn't find anything, though, the original error should be re-raised. result = d.engine.execute(""" UPDATE forgotpassword SET token = %(token)s, set_time = %(time)s, address = %(address)s WHERE userid = %(id)s """, id=user.userid, token=token, time=now, address=address) if result.rowcount != 1: raise # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) username = d.get_sysname(form.username) # Determine the user associated with `username`; if the user is not found, # raise an exception user = d.engine.execute( "SELECT userid, email FROM login WHERE login_name = %(username)s", username=username).first() if not user: raise WeasylError("loginRecordMissing") # Check the user's email address against the provided e-mail address, # raising an exception if there is a mismatch if email != emailer.normalize_address(user.email): raise WeasylError("emailInvalid") # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() try: d.engine.execute( "INSERT INTO forgotpassword (userid, token, set_time, address)" " VALUES (%(id)s, %(token)s, %(time)s, %(address)s)", id=user.userid, token=token, time=now, address=address) except IntegrityError: # An IntegrityError will probably indicate that a password reset request # already exists and that the existing row should be updated. If the update # doesn't find anything, though, the original error should be re-raised. result = d.engine.execute(""" UPDATE forgotpassword SET token = %(token)s, set_time = %(time)s, address = %(address)s WHERE userid = %(id)s """, id=user.userid, token=token, time=now, address=address) if result.rowcount != 1: raise # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def append(db, email, terms): token = security.generate_key(40) email = emailer.normalize_address(email) if not email: raise error.WeasylError("emailInvalid") define.execute(db, "INSERT INTO premiumpurchase VALUES ('%s', '%s', %i)", [token, email, terms]) emailer.append([email], None, "Weasyl Premium Verification", define.render("email/verify_premium.html", [token, terms]))
def request(form): token = security.generate_key(100) email = emailer.normalize_address(form.email) username = d.get_sysname(form.username) # Determine the user associated with `username`; if the user is not found, # raise an exception user = d.engine.execute( "SELECT userid, email FROM login WHERE login_name = %(username)s", username=username).first() if not user: raise WeasylError("loginRecordMissing") # Check the user's email address against the provided e-mail address, # raising an exception if there is a mismatch if email != emailer.normalize_address(user.email): raise WeasylError("emailInvalid") # Insert a record into the forgotpassword table for the user, # or update an existing one now = d.get_time() address = d.get_address() d.engine.execute(""" INSERT INTO forgotpassword (userid, token, set_time, address) VALUES (%(id)s, %(token)s, %(time)s, %(address)s) ON CONFLICT (userid) DO UPDATE SET token = %(token)s, set_time = %(time)s, address = %(address)s """, id=user.userid, token=token, time=now, address=address) # Generate and send an email to the user containing a password reset link emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
def get_account_verification_token(email=None, username=None): email = email and emailer.normalize_address(email) username = username and d.get_sysname(username) logincreate = d.meta.tables['logincreate'] statement = select([logincreate.c.token]) if email: statement = statement.where(logincreate.c.email.ilike(email)) else: statement = statement.where(logincreate.c.login_name == username) return d.engine.scalar(statement)
def get_account_verification_token(email=None, username=None): email = email and emailer.normalize_address(email) username = username and d.get_sysname(username) logincreate = d.meta.tables['logincreate'] statement = select([logincreate.c.token]) if email: statement = statement.where(logincreate.c.email.ilike(email)) else: statement = statement.where(logincreate.c.login_name == username) return d.engine.scalar(statement)
def control_editemailpassword_post_(request): form = request.web_input(newemail="", newemailcheck="", newpassword="", newpasscheck="", password="") newemail = emailer.normalize_address(form.newemail) newemailcheck = emailer.normalize_address(form.newemailcheck) # Check if the email was invalid; Both fields must be valid (not None), and have the form fields set if not newemail and not newemailcheck and form.newemail != "" and form.newemailcheck != "": raise WeasylError("emailInvalid") return_message = profile.edit_email_password( request.userid, form.username, form.password, newemail, newemailcheck, form.newpassword, form.newpasscheck ) if not return_message: # No changes were made message = "No changes were made to your account." else: # Changes were made, so inform the user of this message = "**Success!** " + return_message # Finally return the message about what (if anything) changed to the user return Response(define.errorpage( request.userid, message, [["Go Back", "/control"], ["Return Home", "/"]]) )
def request(email): token = security.generate_key(25, key_characters=string.digits + string.ascii_lowercase) token_sha256 = _hash_token(token) email = emailer.normalize_address(email) if email is None: raise WeasylError("emailInvalid") d.engine.execute( "INSERT INTO forgotpassword (email, token_sha256)" " VALUES (%(email)s, %(token_sha256)s)", email=email, token_sha256=bytearray(token_sha256)) # Generate and send an email to the user containing a password reset link emailer.send(email, "Weasyl Account Recovery", d.render("email/reset_password.html", [token]))
def create(form): # Normalize form data username = d.plaintext(form.username[:_USERNAME]) sysname = d.get_sysname(username) email = emailer.normalize_address(form.email) emailcheck = emailer.normalize_address(form.emailcheck) password = form.password passcheck = form.passcheck if form.day and form.month and form.year: try: birthday = arrow.Arrow(int(form.year), int(form.month), int(form.day)) except ValueError: raise WeasylError("birthdayInvalid") else: birthday = None # Check mismatched form data if password != passcheck: raise WeasylError("passwordMismatch") if email != emailcheck: raise WeasylError("emailMismatch") # Check invalid form data if birthday is None or d.age_in_years(birthday) < 13: raise WeasylError("birthdayInvalid") if not password_secure(password): raise WeasylError("passwordInsecure") if not email: raise WeasylError("emailInvalid") if not sysname or ";" in username: raise WeasylError("usernameInvalid") if sysname in [ "admin", "administrator", "mod", "moderator", "weasyl", "weasyladmin", "weasylmod", "staff", "security" ]: raise WeasylError("usernameInvalid") if email_exists(email): raise WeasylError("emailExists") if username_exists(sysname): raise WeasylError("usernameExists") # Create pending account token = security.generate_key(40) d.engine.execute( d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": email, "birthday": birthday, "unixtime": arrow.now(), }) # Queue verification email emailer.append([email], None, "Weasyl Account Creation", d.render("email/verify_account.html", [token, sysname])) d.metric('increment', 'createdusers')
def create(form): # Normalize form data username = clean_display_name(form.username) sysname = d.get_sysname(username) email = emailer.normalize_address(form.email) emailcheck = emailer.normalize_address(form.emailcheck) password = form.password passcheck = form.passcheck if form.day and form.month and form.year: try: birthday = arrow.Arrow(int(form.year), int(form.month), int(form.day)) except ValueError: raise WeasylError("birthdayInvalid") else: birthday = None # Check mismatched form data if password != passcheck: raise WeasylError("passwordMismatch") if email != emailcheck: raise WeasylError("emailMismatch") # Check invalid form data if birthday is None or d.age_in_years(birthday) < 13: raise WeasylError("birthdayInvalid") if not password_secure(password): raise WeasylError("passwordInsecure") if not email: raise WeasylError("emailInvalid") if is_email_blacklisted(email): raise WeasylError("emailBlacklisted") if username_exists(sysname): raise WeasylError("usernameExists") # Account verification token token = security.generate_key(40) # Only attempt to create the account if the email is unused (as defined by the function) if not email_exists(email): # Create pending account d.engine.execute(d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": email, "birthday": birthday, }) # Send verification email emailer.send(email, "Weasyl Account Creation", d.render( "email/verify_account.html", [token, sysname])) d.metric('increment', 'createdusers') else: # Store a dummy record to support plausible deniability of email addresses # So "reserve" the username, but mark the record invalid, and use the token to satisfy the uniqueness # constraint for the email field (e.g., if there is already a valid, pending row in the table). d.engine.execute(d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": token, "birthday": arrow.now(), "invalid": True, # So we have a way for admins to determine which email address collided in the View Pending Accounts Page "invalid_email_addr": email, }) # The email address in question is already in use in either `login` or `logincreate`; # let the already registered user know this via email (perhaps they forgot their username/password) query_username_login = d.engine.scalar("SELECT login_name FROM login WHERE email = %(email)s", email=email) query_username_logincreate = d.engine.scalar("SELECT login_name FROM logincreate WHERE email = %(email)s", email=email) emailer.send(email, "Weasyl Account Creation - Account Already Exists", d.render( "email/email_in_use_account_creation.html", [query_username_login or query_username_logincreate]))
def create(form): # Normalize form data username = d.plaintext(form.username[:_USERNAME]) sysname = d.get_sysname(username) email = emailer.normalize_address(form.email) emailcheck = emailer.normalize_address(form.emailcheck) password = form.password passcheck = form.passcheck if form.day and form.month and form.year: try: birthday = arrow.Arrow(int(form.year), int(form.month), int(form.day)) except ValueError: raise WeasylError("birthdayInvalid") else: birthday = None # Check mismatched form data if password != passcheck: raise WeasylError("passwordMismatch") if email != emailcheck: raise WeasylError("emailMismatch") # Check invalid form data if birthday is None or d.age_in_years(birthday) < 13: raise WeasylError("birthdayInvalid") if not password_secure(password): raise WeasylError("passwordInsecure") if not email: raise WeasylError("emailInvalid") if is_email_blacklisted(email): raise WeasylError("emailBlacklisted") if not sysname or ";" in username: raise WeasylError("usernameInvalid") if sysname in ["admin", "administrator", "mod", "moderator", "weasyl", "weasyladmin", "weasylmod", "staff", "security"]: raise WeasylError("usernameInvalid") if username_exists(sysname): raise WeasylError("usernameExists") # Account verification token token = security.generate_key(40) # Only attempt to create the account if the email is unused (as defined by the function) if not email_exists(email): # Create pending account d.engine.execute(d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": email, "birthday": birthday, "unixtime": arrow.now(), }) # Queue verification email emailer.append([email], None, "Weasyl Account Creation", d.render( "email/verify_account.html", [token, sysname])) d.metric('increment', 'createdusers') else: # Store a dummy record to support plausible deniability of email addresses # So "reserve" the username, but mark the record invalid, and use the token to satisfy the uniqueness # constraint for the email field (e.g., if there is already a valid, pending row in the table). d.engine.execute(d.meta.tables["logincreate"].insert(), { "token": token, "username": username, "login_name": sysname, "hashpass": passhash(password), "email": token, "birthday": arrow.now(), "unixtime": arrow.now(), "invalid": True, }) # The email address in question is already in use in either `login` or `logincreate`; # let the already registered user know this via email (perhaps they forgot their username/password) query_username_login = d.engine.scalar("SELECT login_name FROM login WHERE email = %(email)s", email=email) query_username_logincreate = d.engine.scalar("SELECT login_name FROM logincreate WHERE email = %(email)s", email=email) emailer.append([email], None, "Weasyl Account Creation - Account Already Exists", d.render( "email/email_in_use_account_creation.html", [query_username_login or query_username_logincreate]))