64 lines
1.6 KiB
Python
64 lines
1.6 KiB
Python
|
import enum
|
||
|
import random
|
||
|
import unicodedata
|
||
|
import sqlite3
|
||
|
|
||
|
from passlib.hash import argon2
|
||
|
|
||
|
class userstatus(enum.Enum):
|
||
|
# These will be stored in the database, be mindful of not changing the numbers
|
||
|
deleted = 0
|
||
|
normal = 1
|
||
|
admin = 2
|
||
|
|
||
|
csprng = random.SystemRandom()
|
||
|
|
||
|
def add_user(userdb, *, username, password, email, parent, status):
|
||
|
"""Add a user to the database"""
|
||
|
global csprgn
|
||
|
|
||
|
assert type(username) == str
|
||
|
assert type(password) == str
|
||
|
assert type(email) == str
|
||
|
assert type(parent) == int or parent is None
|
||
|
assert status in userstatus
|
||
|
|
||
|
# Generate a user ID. SQLite uses 64 bit signed ints, so generate at max 2⁶³-1
|
||
|
userid = csprng.randrange(2**63)
|
||
|
|
||
|
# First unicode normalize the password, then hash it with argon2
|
||
|
password = unicodedata.normalize('NFKC', password)
|
||
|
password = argon2.hash(password)
|
||
|
|
||
|
# Convert status into an int for storage
|
||
|
status = status.value
|
||
|
|
||
|
# Add the user into the database
|
||
|
cursor = userdb.cursor()
|
||
|
cursor.execute('INSERT INTO users VALUES (?, ?, ?, ?, ?, ?, ?);', (userid, parent, status, password, username, email, ''))
|
||
|
userdb.commit()
|
||
|
|
||
|
def initialize_userdb(userdb, admin_user, admin_password):
|
||
|
"""Creates a bare-bones user database with only admin
|
||
|
This should never be run outside of the initialization script"""
|
||
|
|
||
|
cursor = userdb.cursor()
|
||
|
|
||
|
cursor.execute('''CREATE TABLE users (
|
||
|
id integer NOT NULL PRIMARY KEY,
|
||
|
|
||
|
parent integer,
|
||
|
status integer NOT NULL,
|
||
|
|
||
|
password text NOT NULL,
|
||
|
|
||
|
username text NOT NULL,
|
||
|
email text NOT NULL,
|
||
|
|
||
|
comment text NOT NULL
|
||
|
);''')
|
||
|
|
||
|
userdb.commit()
|
||
|
|
||
|
add_user(userdb, username = admin_user, password = admin_password, email = '', parent = None, status = userstatus.admin)
|