Add a login page (nonfunctional)

This commit is contained in:
Juhani Krekelä 2018-06-09 17:25:04 +03:00
parent c3556b0c71
commit 0187775332
3 changed files with 99 additions and 2 deletions

View File

@ -3,10 +3,14 @@ import random
import unicodedata
import sqlite3
from collections import namedtuple
from passlib.hash import argon2
import config
UserInfo = namedtuple('UserInfo', ('id', 'parent', 'status', 'username', 'email', 'comment'))
# ------------------------------------------------------------------
# General
# ------------------------------------------------------------------
@ -29,6 +33,7 @@ def connect():
# ------------------------------------------------------------------
def add_user(db, *, username, password, email, parent, status):
# TODO: Ensure users are unique
"""Add a user to the database
Will not commit the changes itself, so run .commit() on the database object yourself"""
global csprgn
@ -57,6 +62,65 @@ def add_user(db, *, username, password, email, parent, status):
cursor.execute('PRAGMA foreign_keys = ON;') # Fail if we insert a user with bogus parent field
cursor.execute('INSERT INTO users VALUES (?, ?, ?, ?, ?, ?, ?);', (userid, parent, status, password, username, email, ''))
def get_userid(db, username):
"""Returns the user ID associated with given username
If no user was found, returns None"""
# Unicode normalize the username
username = unicodedata.normalize('NFKC', username)
# Get the user ID
cursor = db.cursor()
cursor.execute('SELECT id FROM users WHERE username = ?', (username,))
results = cursor.fetchall()
# If no user was found, return None
if len(results) != 1:
return None
return results[0][0]
def check_password(db, userid, password):
"""Checks the password for given userid
Will return True if the password matches and False otherwise"""
# Unicode normalize the password
password = unicodedata.normalize('NFKC', password)
# Get the password and status
cursor = db.cursor()
cursor.execute('SELECT password, status FROM users WHERE id = ?', (userid,))
results = cursor.fetchall()
# If no user of that name, fail
if len(results) != 1:
return False
hashed, status = results[0]
# If user has been deleted, fail
if status == userstatus.deleted:
return False
# Check the password
return argon2.verify(password, hashed)
def get_user_info(db, userid):
"""Returns a UserInfo object representing the data associated with a user
If no user was found, returns None"""
cursor = db.cursor()
cursor.execute('SELECT id, parent, status, username, email, comment FROM users WHERE id = ?', (userid,))
results = cursor.fetchall()
# If no user was found, return None
if len(results) != 1:
return None
userid, parent, status, username, email, comment = results[0]
# Translate status into enum
status = userstatus(status)
return UserInfo(userid, parent, status, username, email, comment)
def initialize_users(db, admin_user, admin_password):
"""Creates a bare-bones user table with only admin user
This should never be run outside of the initialization script"""

View File

@ -90,6 +90,31 @@ def index():
soup = new_soup()
return page_skeleton(page_title = config.site_name, contents = [], soup = soup)
def login_forward(raw_path):
"""Returns html
Creates a page telling the user to log in"""
# TODO: Take the user back to where they were
soup = new_soup()
# TODO: Don't hardcode
contents = bs4.BeautifulSoup('''
<p>Login to access</p>
<form action="''' + config.url_prefix + '''/login" method="post">
<div>
<input type="text" name="username"/>
</div>
<div>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Login"/>
</div>
</form>
''')
# TODO: Internationalization
return page_skeleton(page_title = 'Login to ' + config.site_name, contents = contents, soup = soup)
def error_404(path):
"""Returns html"""
soup = new_soup()

View File

@ -7,7 +7,9 @@ import generate_html
class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
server_version = 'Buranun/0.0'
protocol_version = 'HTTP/1.1'
# TODO: Look into keepalive problems in links2
#protocol_version = 'HTTP/1.1'
protocol_version = 'HTTP/1.0'
def __send_html(self, html, *, status_code = 200):
encoded = html.encode('utf-8')
@ -54,7 +56,13 @@ class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
print(received_cookies['buranun_session'].value)
else:
print('no cookies')
# Display page that tells user to login
# TODO: Have it forward the user back to the page where they were at
html = generate_html.login_forward(self.path)
self.__send_html(html)
# Don't run rest of the function
return
path = urllib.parse.unquote(self.path)