artemis/core/data/schema/user.py

123 lines
4.0 KiB
Python
Raw Normal View History

from typing import Optional, List
from sqlalchemy import Table, Column
from sqlalchemy.types import Integer, String, TIMESTAMP
from sqlalchemy.sql import func
2023-02-19 20:40:25 +00:00
from sqlalchemy.dialects.mysql import insert
from sqlalchemy.sql import func, select
2023-02-19 20:40:25 +00:00
from sqlalchemy.engine import Row
import bcrypt
from core.data.schema.base import BaseData, metadata
aime_user = Table(
"aime_user",
metadata,
Column("id", Integer, nullable=False, primary_key=True, autoincrement=True),
Column("username", String(25), unique=True),
Column("email", String(255), unique=True),
Column("password", String(255)),
2023-03-09 16:38:58 +00:00
Column("permissions", Integer),
Column("created_date", TIMESTAMP, server_default=func.now()),
Column("last_login_date", TIMESTAMP, onupdate=func.now()),
Column("suspend_expire_time", TIMESTAMP),
2023-03-09 16:38:58 +00:00
mysql_charset="utf8mb4",
)
class UserData(BaseData):
2024-01-09 19:42:17 +00:00
async def create_user(
2023-03-09 16:38:58 +00:00
self,
id: int = None,
username: str = None,
email: str = None,
password: str = None,
permission: int = 1,
) -> Optional[int]:
2023-02-19 20:40:25 +00:00
if id is None:
sql = insert(aime_user).values(
2023-03-09 16:38:58 +00:00
username=username,
email=email,
password=password,
permissions=permission,
2023-02-19 20:40:25 +00:00
)
else:
2023-02-19 20:40:25 +00:00
sql = insert(aime_user).values(
2023-03-09 16:38:58 +00:00
id=id,
username=username,
email=email,
password=password,
permissions=permission,
2023-02-19 20:40:25 +00:00
)
2023-02-19 20:40:25 +00:00
conflict = sql.on_duplicate_key_update(
2023-03-09 16:38:58 +00:00
username=username, email=email, password=password, permissions=permission
2023-02-19 20:40:25 +00:00
)
2023-03-09 16:38:58 +00:00
2024-01-09 19:42:17 +00:00
result = await self.execute(conflict)
2023-03-09 16:38:58 +00:00
if result is None:
return None
return result.lastrowid
2023-03-09 16:38:58 +00:00
2024-01-09 19:42:17 +00:00
async def get_user(self, user_id: int) -> Optional[Row]:
sql = select(aime_user).where(aime_user.c.id == user_id)
2024-01-09 19:42:17 +00:00
result = await self.execute(sql)
2023-03-09 16:38:58 +00:00
if result is None:
return False
2023-02-19 20:40:25 +00:00
return result.fetchone()
2023-03-09 16:38:58 +00:00
async def check_password(self, user_id: int, passwd: bytes = None) -> bool:
usr = await self.get_user(user_id)
2023-03-09 16:38:58 +00:00
if usr is None:
return False
2023-02-19 20:40:25 +00:00
2023-03-09 16:38:58 +00:00
if usr["password"] is None:
return False
if passwd is None or not passwd:
return False
2023-02-19 20:40:25 +00:00
2023-03-09 16:38:58 +00:00
return bcrypt.checkpw(passwd, usr["password"].encode())
2023-02-19 20:40:25 +00:00
2024-01-09 19:42:17 +00:00
async def delete_user(self, user_id: int) -> None:
sql = aime_user.delete(aime_user.c.id == user_id)
2024-01-09 19:42:17 +00:00
result = await self.execute(sql)
2023-03-09 16:38:58 +00:00
if result is None:
self.logger.error(f"Failed to delete user with id {user_id}")
2024-01-09 19:42:17 +00:00
async def get_unregistered_users(self) -> List[Row]:
"""
Returns a list of users who have not registered with the webui. They may or may not have cards.
"""
sql = select(aime_user).where(aime_user.c.password == None)
2024-01-09 19:42:17 +00:00
result = await self.execute(sql)
2023-03-09 16:38:58 +00:00
if result is None:
return None
2023-03-09 16:38:58 +00:00
return result.fetchall()
2024-01-09 19:42:17 +00:00
async def find_user_by_email(self, email: str) -> Row:
sql = select(aime_user).where(aime_user.c.email == email)
2024-01-09 19:42:17 +00:00
result = await self.execute(sql)
if result is None:
return False
return result.fetchone()
2024-01-09 19:42:17 +00:00
async def find_user_by_username(self, username: str) -> List[Row]:
sql = aime_user.select(aime_user.c.username.like(f"%{username}%"))
2024-01-09 19:42:17 +00:00
result = await self.execute(sql)
if result is None:
return False
return result.fetchall()
async def change_password(self, user_id: int, new_passwd: str) -> bool:
sql = aime_user.update(aime_user.c.id == user_id).values(password = new_passwd)
result = await self.execute(sql)
return result is not None
async def change_username(self, user_id: int, new_name: str) -> bool:
sql = aime_user.update(aime_user.c.id == user_id).values(username = new_name)
result = await self.execute(sql)
return result is not None