From a5c512c7d4d05a693f9c8b2d297a1bbeecb26f4c Mon Sep 17 00:00:00 2001 From: Beesquit Date: Tue, 5 Aug 2025 12:10:56 +0300 Subject: [PATCH] idk WIP2 --- src/api/accounts.py | 57 +++++++++++++++++++++++++++++++++++++-------- src/api/models.py | 2 ++ src/api/utils.py | 11 ++++----- src/db/accounts.py | 3 +-- tables.sql | 1 + 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/api/accounts.py b/src/api/accounts.py index c44191f..a2b8dc8 100644 --- a/src/api/accounts.py +++ b/src/api/accounts.py @@ -5,29 +5,66 @@ from psycopg2._psycopg import connection import db.accounts as db import settings.settings as settings -from api.utils import get_password_hash +from api.utils import encrypt_str, get_current_user +from api.models import User, Account from db.internal import get_db_connection accounts_router = APIRouter(prefix="/api/accounts", tags=["anon"]) -@accounts_router.post("/add/user") +@accounts_router.post("/account") +async def get_account( + account_id: int, + conn: Annotated[connection, Depends(get_db_connection)], + current_user: Annotated[User, Depends(get_current_user)] +): + if current_user.role not in settings.settings.admin_roles: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not allowed", + ) + account_data = db.get_account(conn, account_id) + if account_data is None: + return HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="No such account", + ) + account = Account() + account.fill(account_data) + return account + + +@accounts_router.post("/add") async def add_account( platform: str, login: str, password: str, metadata: dict, - conn: Annotated[connection, Depends(get_db_connection)] + conn: Annotated[connection, Depends(get_db_connection)], + current_user: Annotated[User, Depends(get_current_user)] ): - if not settings.settings.allow_create_users: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="Not allowed", - ) if db.check_account_existence(conn, platform, login, password): raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Account already exists", ) - hashed_password = get_password_hash(password) - return db.create_user(conn, username, hashed_password, "user") + hashed_password = encrypt_str(password) + return db.create_account(conn, login, hashed_password, metadata) + +# TODO: add author to check editing rights? +@accounts_router.post("/update") +async def update_account( + account_id: int, + platform: str, + login: str, + password: str, + metadata: dict, + conn: Annotated[connection, Depends(get_db_connection)], + current_user: Annotated[User, Depends(get_current_user)] +): + if current_user.role not in settings.settings.admin_roles: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not allowed", + ) + return db.update_account(conn, account_id, platform, login, password, metadata) diff --git a/src/api/models.py b/src/api/models.py index b4f54f6..46bea00 100644 --- a/src/api/models.py +++ b/src/api/models.py @@ -1,6 +1,7 @@ from datetime import datetime from pydantic import BaseModel +from api.utils import decrypt_str class Token(BaseModel): @@ -103,6 +104,7 @@ class Account(BaseModel): self.id = params["id"] self.platform = params["platform"] self.login = params["login"] + self.password = decrypt_str(params["password"]) self.metadata = params["metadata"] self.created_at = params["created_at"] id: int = -1 diff --git a/src/api/utils.py b/src/api/utils.py index 549055a..2d5ade6 100644 --- a/src/api/utils.py +++ b/src/api/utils.py @@ -4,7 +4,6 @@ from typing import Annotated import bcrypt import jwt from Crypto.Cipher import AES -from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer @@ -20,14 +19,14 @@ from db.internal import get_db_connection oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") -def encrypt_str(string, key_hex): - key = bytes.fromhex(key_hex) - cipher = AES.new(key, AES.MODE_ECB) # Простейший режим (небезопасно для больших данных!) +def encrypt_str(string): + key = bytes.fromhex(startup_settings.secret_key) + cipher = AES.new(key, AES.MODE_ECB) encrypted_string = cipher.encrypt(pad(string.encode(), AES.block_size)) return encrypted_string -def decrypt_str(encrypted_string, key_hex): - key = bytes.fromhex(key_hex) +def decrypt_str(encrypted_string): + key = bytes.fromhex(startup_settings.secret_key) cipher = AES.new(key, AES.MODE_ECB) string = unpad(cipher.decrypt(encrypted_string), AES.block_size) return string.decode() diff --git a/src/db/accounts.py b/src/db/accounts.py index fa0ec7f..4d32df1 100644 --- a/src/db/accounts.py +++ b/src/db/accounts.py @@ -23,8 +23,7 @@ def create_account( """, (platform, login, password, json.dumps(metadata)), ) - conn.commit() - return cur.rowcount > 0 + return conn.commit() def delete_account( diff --git a/tables.sql b/tables.sql index 92e1d7c..79e61aa 100644 --- a/tables.sql +++ b/tables.sql @@ -68,6 +68,7 @@ create table picrinth.swipes ( constraint swipes_unique unique (username, feed_id, picture_id) ); +-- TODO: add author? create table picrinth.accounts ( id serial not null, platform text not null,