Add a login page (nonfunctional)
This commit is contained in:
parent
c3556b0c71
commit
0187775332
3 changed files with 99 additions and 2 deletions
64
database.py
64
database.py
|
@ -3,10 +3,14 @@ import random
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
from passlib.hash import argon2
|
from passlib.hash import argon2
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
UserInfo = namedtuple('UserInfo', ('id', 'parent', 'status', 'username', 'email', 'comment'))
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# General
|
# General
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
@ -29,6 +33,7 @@ def connect():
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def add_user(db, *, username, password, email, parent, status):
|
def add_user(db, *, username, password, email, parent, status):
|
||||||
|
# TODO: Ensure users are unique
|
||||||
"""Add a user to the database
|
"""Add a user to the database
|
||||||
Will not commit the changes itself, so run .commit() on the database object yourself"""
|
Will not commit the changes itself, so run .commit() on the database object yourself"""
|
||||||
global csprgn
|
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('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, ''))
|
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):
|
def initialize_users(db, admin_user, admin_password):
|
||||||
"""Creates a bare-bones user table with only admin user
|
"""Creates a bare-bones user table with only admin user
|
||||||
This should never be run outside of the initialization script"""
|
This should never be run outside of the initialization script"""
|
||||||
|
|
|
@ -90,6 +90,31 @@ def index():
|
||||||
soup = new_soup()
|
soup = new_soup()
|
||||||
return page_skeleton(page_title = config.site_name, contents = [], soup = 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):
|
def error_404(path):
|
||||||
"""Returns html"""
|
"""Returns html"""
|
||||||
soup = new_soup()
|
soup = new_soup()
|
||||||
|
|
12
server.py
12
server.py
|
@ -7,7 +7,9 @@ import generate_html
|
||||||
|
|
||||||
class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
server_version = 'Buranun/0.0'
|
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):
|
def __send_html(self, html, *, status_code = 200):
|
||||||
encoded = html.encode('utf-8')
|
encoded = html.encode('utf-8')
|
||||||
|
@ -54,7 +56,13 @@ class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
print(received_cookies['buranun_session'].value)
|
print(received_cookies['buranun_session'].value)
|
||||||
|
|
||||||
else:
|
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)
|
path = urllib.parse.unquote(self.path)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue