瀏覽代碼

Merge branch 'minor' of sindre/Beelance into master

pull/38/head
Sindre Stephansen 5 年之前
父節點
當前提交
454633f113
共有 4 個檔案被更改,包括 44 行新增6 行删除
  1. +3
    -1
      mysql/sql/init.sql
  2. +1
    -1
      src/app/models/register.py
  3. +20
    -1
      src/app/models/user.py
  4. +20
    -3
      src/app/views/login.py

+ 3
- 1
mysql/sql/init.sql 查看文件

@@ -11,6 +11,8 @@ CREATE TABLE users (
state VARCHAR(50), state VARCHAR(50),
postal_code VARCHAR(50), postal_code VARCHAR(50),
country VARCHAR(50), country VARCHAR(50),
login_attempts INT UNSIGNED,
last_login_attempt INT UNSIGNED,
PRIMARY KEY (userid) PRIMARY KEY (userid)
); );


@@ -84,7 +86,7 @@ CREATE TABLE task_files (
* Initial data * Initial data
*/ */


insert into users values (NULL, "admin", "$2b$12$iKbYZ0MFwWWxoYUXKRhFiOPo7itaQO2DIRnLgXbECsj8XKVzkNCSi", "Admin Modsen", "ntnu", 'mail@ntnu.no', "street", "trondheim", "trondheim", "1234", "norway");
insert into users values (NULL, "admin", "$2b$12$iKbYZ0MFwWWxoYUXKRhFiOPo7itaQO2DIRnLgXbECsj8XKVzkNCSi", "Admin Modsen", "ntnu", 'mail@ntnu.no', "street", "trondheim", "trondheim", "1234", "norway", 0, 0);


insert into project_category values (NULL, "Gardening"); insert into project_category values (NULL, "Gardening");
insert into project_category values (NULL, "Programming"); insert into project_category values (NULL, "Programming");


+ 1
- 1
src/app/models/register.py 查看文件

@@ -28,7 +28,7 @@ def set_user(username, password, full_name, company, email,
""" """
db.connect() db.connect()
cursor = db.cursor() cursor = db.cursor()
query = ("INSERT INTO users VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)")
query = ("INSERT INTO users VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0)")
try: try:
cursor.execute(query, (username, password, full_name, company, email, street_address, cursor.execute(query, (username, password, full_name, company, email, street_address,
city, state, postal_code, country)) city, state, postal_code, country))


+ 20
- 1
src/app/models/user.py 查看文件

@@ -12,7 +12,7 @@ def get_user(username):
""" """
db.connect() db.connect()
cursor = db.cursor() cursor = db.cursor()
query = ("SELECT userid, username, password from users where username = %s")
query = ("SELECT userid, username, password, login_attempts, last_login_attempt from users where username = %s")
user = None user = None
try: try:
cursor.execute(query, (username,)) cursor.execute(query, (username,))
@@ -51,6 +51,25 @@ def get_users():
return users return users




def set_login_attempts(userid, num, timestamp):
"""
Set the number and timestamp of the failed login attempts for the given user.
"""
db.connect()
cursor = db.cursor()
query = ("UPDATE users SET login_attempts = %s, last_login_attempt = %s WHERE userid = %s")
try:
cursor.execute(query, (num, timestamp, 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_user_id_by_name(username): def get_user_id_by_name(username):
""" """
Get the id of the unique username Get the id of the unique username


+ 20
- 3
src/app/views/login.py 查看文件

@@ -14,6 +14,10 @@ render = web.template.render('templates/')
# The remember cookie should be valid for a week # The remember cookie should be valid for a week
remember_timeout = 3600*24*7 remember_timeout = 3600*24*7


# The timeout between login attempts, after the 3rd incorrect one
login_timeout = 60
login_attempts_threshold = 2



class Login(): class Login():


@@ -47,11 +51,24 @@ class Login():
# Validate login credential with database query # Validate login credential with database query
user = models.user.get_user(data.username) user = models.user.get_user(data.username)


if bcrypt.checkpw(data.password.encode('UTF-8'), user[2].encode('UTF-8')):
self.login(user[1], user[0], data.remember)
if user is None:
return render.login(nav, login_form, "- User authentication failed")

userid, username, password_hash, login_attempts, last_login_attempt = user

if login_attempts > login_attempts_threshold and last_login_attempt + login_timeout > time.time():
return render.login(nav, login_form, "- There have been too many incorrect login attempts for your account. You have to wait a minute before you can log in.")

if bcrypt.checkpw(data.password.encode('UTF-8'), password_hash.encode('UTF-8')):
models.user.set_login_attempts(userid, 0, time.time())
self.login(username, userid, data.remember)
raise web.seeother("/") raise web.seeother("/")
else: else:
return render.login(nav, login_form, "- User authentication failed")
models.user.set_login_attempts(userid, login_attempts+1, time.time())
if login_attempts == login_attempts_threshold:
return render.login(nav, login_form, "- Too many incorrect login attempts. You have to wait a minute before trying again.")
else:
return render.login(nav, login_form, "- User authentication failed")


def login(self, username, userid, remember): def login(self, username, userid, remember):
""" """


Loading…
取消
儲存