import sqlite3 from .exceptions import UsernameTakenError class Users: """A table of users, including admins. A user must register through the interface provided by JImbrella to be one of the users in this table. Those who borrow umbrellas via jForm are not stored here. Columns: - username | identifier Unicode string. must be unique. - password | salted and hashed password. - role | one of ("admin", "user"). expect additions. - status | one of ("normal", "denied"). expect additions. - language | one of ("en-US", 'zh-CN"). - realname | (optional) legal name of user. - id | (optional) student/faculty ID. - phone | (optional) phone number. - email | (optional) email address. Schema: CREATE TABLE Users( username TEXT PRIMARY KEY, password TEXT, role TEXT, status TEXT, language TEXT, realname TEXT, id TEXT, phone TEXT, email TEXT ); """ def __init__(self, path): self.path = path def register(self, username, password, language): """Create a new user. If username is already taken, raise UsernameTakenError. """ db = sqlite3.connect(self.path) try: db.execute( "INSERT INTO Users (username, password, role, status, language) " + "VALUES (?, ?, ?, ?, ?)", (username, password, "user", "normal", "en-US"), ) except sqlite3.IntegrityError: raise UsernameTakenError(username) db.commit() db.close() def find(self, username) -> dict: """Find a user and return it in its `dict` structure. If user is not found, return None.""" db = sqlite3.connect(self.path) db.row_factory = sqlite3.Row user = db.execute( "SELECT * FROM Users WHERE username = ?", (username,) ).fetchone() return user