77 lines
2.3 KiB
Python
77 lines
2.3 KiB
Python
async def create(conn):
|
|
# Users core table
|
|
await conn.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS User (
|
|
id INTEGER PRIMARY KEY,
|
|
email TEXT NOT NULL UNIQUE,
|
|
display_name TEXT NOT NULL,
|
|
profile_photo_url TEXT
|
|
);
|
|
"""
|
|
)
|
|
|
|
# Local credential storage for password auth
|
|
await conn.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS LocalCredentials (
|
|
user_id INTEGER PRIMARY KEY,
|
|
hashed_password TEXT NOT NULL,
|
|
FOREIGN KEY(user_id) REFERENCES User(id) ON DELETE CASCADE
|
|
);
|
|
"""
|
|
)
|
|
|
|
# OAuth provider links (e.g., Google)
|
|
await conn.execute(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS OAuthCredentials (
|
|
user_id INTEGER NOT NULL,
|
|
provider TEXT NOT NULL,
|
|
provider_user_id TEXT NOT NULL,
|
|
PRIMARY KEY (provider, provider_user_id),
|
|
FOREIGN KEY(user_id) REFERENCES User(id) ON DELETE CASCADE
|
|
);
|
|
"""
|
|
)
|
|
|
|
# Helpful indices
|
|
await conn.execute("CREATE INDEX IF NOT EXISTS idx_user_email ON User(email);")
|
|
|
|
|
|
async def get_by_email(conn, email: str):
|
|
async with conn.execute(
|
|
"SELECT id, email, display_name, profile_photo_url FROM User WHERE email = ? LIMIT 1",
|
|
(email,),
|
|
) as c:
|
|
row = await c.fetchone()
|
|
if not row:
|
|
return None
|
|
from users.models import User
|
|
|
|
return User(id=int(row[0]), email=row[1], display_name=row[2], profile_photo_url=row[3])
|
|
|
|
|
|
async def insert_user(conn, email: str, display_name: str, profile_photo_url: str | None = None):
|
|
async with conn.execute(
|
|
"INSERT INTO User (email, display_name, profile_photo_url) VALUES (?, ?, ?)",
|
|
(email, display_name, profile_photo_url),
|
|
) as cur:
|
|
user_id = cur.lastrowid
|
|
return user_id
|
|
|
|
|
|
async def set_local_credentials(conn, user_id: int, hashed_password: str):
|
|
await conn.execute(
|
|
"INSERT OR REPLACE INTO LocalCredentials (user_id, hashed_password) VALUES (?, ?)",
|
|
(user_id, hashed_password),
|
|
)
|
|
|
|
|
|
async def get_local_password_hash(conn, user_id: int) -> str | None:
|
|
async with conn.execute(
|
|
"SELECT hashed_password FROM LocalCredentials WHERE user_id = ?",
|
|
(user_id,),
|
|
) as c:
|
|
row = await c.fetchone()
|
|
return row[0] if row else None
|