Преглед изворни кода

Implement email registration

Fixes #1
pull/40/head
Sindre Stephansen пре 5 година
родитељ
комит
46394af70f
7 измењених фајлова са 170 додато и 10 уклоњено
  1. +2
    -0
      mysql/sql/init.sql
  2. +11
    -4
      src/app/models/register.py
  3. +80
    -0
      src/app/models/user.py
  4. +19
    -0
      src/app/templates/verify.html
  5. +2
    -1
      src/app/views/app.py
  6. +3
    -0
      src/app/views/login.py
  7. +53
    -5
      src/app/views/register.py

+ 2
- 0
mysql/sql/init.sql Прегледај датотеку

@@ -13,6 +13,8 @@ CREATE TABLE users (
country VARCHAR(50),
login_attempts INT UNSIGNED,
last_login_attempt INT UNSIGNED,
verified BOOLEAN,
token VARCHAR(50),
PRIMARY KEY (userid)
);



+ 11
- 4
src/app/models/register.py Прегледај датотеку

@@ -6,7 +6,7 @@ logger = logging.getLogger(__name__)


def set_user(username, password, full_name, company, email,
street_address, city, state, postal_code, country):
street_address, city, state, postal_code, country, token):
"""
Register a new user in the database
:param username: The users unique user name
@@ -19,6 +19,7 @@ def set_user(username, password, full_name, company, email,
:param state: The state where the user lives
:param postal_code: The corresponding postal code
:param country: The users country
:param token: The account verification token
:type username: str
:type password: str
:type full_name: str
@@ -29,13 +30,19 @@ def set_user(username, password, full_name, company, email,
:type state: str
:type postal_code: str
:type country: str
:type token: str
"""
db.connect()
cursor = db.cursor()
query = ("INSERT INTO users VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0)")
query = ("""
INSERT INTO users (userid, username, password, full_name, company,
email, street_address, city, state, postal_code,
country, login_attempts, last_login_attempt, verified, token)
VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0, 0, %s)
""")
try:
cursor.execute(query, (username, password, full_name, company, email, street_address,
city, state, postal_code, country))
cursor.execute(query, (username, password, full_name, company, email,
street_address, city, state, postal_code, country, token))
db.commit()
except mysql.connector.Error as err:
logger.error("Failed executing query: %s", err)


+ 80
- 0
src/app/models/user.py Прегледај датотеку

@@ -122,3 +122,83 @@ def get_user_name_by_id(userid):
cursor.close()
db.close()
return username


def set_token(userid, token):
"""Set the given token for the given user."""
db.connect()
cursor = db.cursor()
query = ("UPDATE users SET token=%s WHERE userid=%s")
try:
cursor.execute(query, (token, userid))
db.commit()
except mysql.connector.Error as err:
print("Failed executing query: {}".format(err))
cursor.fetchall()
exit(1)
finally:
cursor.close()
db.close()


def get_userid_from_token(token):
"""Get the user with the given verify token."""
db.connect()
cursor = db.cursor()
query = ("SELECT userid FROM users WHERE token=%s")
try:
cursor.execute(query, (token,))
tokens = cursor.fetchall()
if tokens:
return tokens[0][0]
except mysql.connector.Error as err:
print("Failed executing query: {}".format(err))
cursor.fetchall()
exit(1)
finally:
cursor.close()
db.close()

return None


def verify_user(userid):
"""
Mark the user as verified.
"""
db.connect()
cursor = db.cursor()
query = ("UPDATE users SET verified=1 WHERE userid=%s AND verified=0")
try:
cursor.execute(query, (userid,))
db.commit()
except mysql.connector.Error as err:
print("Failed executing query: {}".format(err))
cursor.fetchall()
exit(1)
finally:
cursor.close()
db.close()


def is_verified(userid):
"""
Check whether the user has verified
"""
db.connect()
cursor = db.cursor()
query = ("SELECT userid FROM users WHERE verified=1 AND userid=%s")
try:
cursor.execute(query, (userid,))
users = cursor.fetchall()
if users:
return True
except mysql.connector.Error as err:
print("Failed executing query: {}".format(err))
cursor.fetchall()
exit(1)
finally:
cursor.close()
db.close()

return False

+ 19
- 0
src/app/templates/verify.html Прегледај датотеку

@@ -0,0 +1,19 @@
$def with (nav, message)

<head>
<title>Beelance2</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="static/stylesheet.css">
<link rel="shortcut icon" type="image/png" href="static/honeybee.png"/>

</head>

<body>

$:nav

<h2>$message</h2>

</body>

<footer></footer>

+ 2
- 1
src/app/views/app.py Прегледај датотеку

@@ -2,7 +2,7 @@ import os
import web
from views.login import Login
from views.logout import Logout
from views.register import Register
from views.register import Register, Verify
from views.new_project import New_project
from views.open_projects import Open_projects
from views.project import Project
@@ -17,6 +17,7 @@ urls = (
'/', 'Index',
'/login', 'Login',
'/logout', 'Logout',
'/verify', 'Verify',
'/register', 'Register',
'/new_project', 'New_project',
'/open_projects', 'Open_projects',


+ 3
- 0
src/app/views/login.py Прегледај датотеку

@@ -64,6 +64,9 @@ class Login():
if login_attempts > login_attempts_threshold:
logger.info("User %s logged in succesfully after %s attempts", username, login_attempts)

if not models.user.is_verified(userid):
return render.login(nav, login_form, "- User not authenticated yet. Please check you email.")

models.user.set_login_attempts(userid, 0, time.time())
self.login(username, userid, data.remember)
raise web.seeother("/")


+ 53
- 5
src/app/views/register.py Прегледај датотеку

@@ -1,6 +1,7 @@
import web
from views.forms import register_form
from views.utils import get_nav_bar, csrf_protected, password_weakness, get_render
from views.utils import get_nav_bar, csrf_protected, password_weakness, get_render, sendmail
from uuid import uuid4
import models.register
import models.user
import logging
@@ -49,9 +50,56 @@ class Register:

password_hash = bcrypt.hashpw(data.password.encode('UTF-8'), bcrypt.gensalt())

models.register.set_user(data.username, password_hash, data.full_name, data.company,
data.email, data.street_address, data.city, data.state,
data.postal_code, data.country)
# Create a verify token
while True:
token = uuid4().hex
if models.user.get_userid_from_token(token) is None:
break

models.register.set_user(
data.username,
password_hash,
data.full_name,
data.company,
data.email,
data.street_address,
data.city,
data.state,
data.postal_code,
data.country,
token,
)

verify_url = "https://{}/verify?token={}".format(web.ctx.host, token)

sendmail(
'Verify your Beelance account',
"""
Welcome to Beelance!

To verify your account, please go to this link: {url}
""".format(url=verify_url),
data.full_name,
data.email,
)

logger.info("User %s registered", data.username)
return render.register(nav, register_form, "User registered!")
return render.register(nav, register_form, "User registered! We have sent you an email to verify your account.")


class Verify:
def GET(self):
"""
Verify the user email
"""
session = web.ctx.session
nav = get_nav_bar(session)
render = get_render()

token = web.input(token='').token
userid = models.user.get_userid_from_token(token)
if token and userid is not None:
models.user.verify_user(userid)
return render.verify(nav, "Your email has been verified. You can log in now.")
else:
return render.verify(nav, "Invalid token. Please try again.")

Loading…
Откажи
Сачувај