idk WIP2
This commit is contained in:
@ -5,29 +5,66 @@ from psycopg2._psycopg import connection
|
|||||||
|
|
||||||
import db.accounts as db
|
import db.accounts as db
|
||||||
import settings.settings as settings
|
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
|
from db.internal import get_db_connection
|
||||||
|
|
||||||
accounts_router = APIRouter(prefix="/api/accounts", tags=["anon"])
|
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(
|
async def add_account(
|
||||||
platform: str,
|
platform: str,
|
||||||
login: str,
|
login: str,
|
||||||
password: str,
|
password: str,
|
||||||
metadata: dict,
|
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):
|
if db.check_account_existence(conn, platform, login, password):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT,
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
detail="Account already exists",
|
detail="Account already exists",
|
||||||
)
|
)
|
||||||
hashed_password = get_password_hash(password)
|
hashed_password = encrypt_str(password)
|
||||||
return db.create_user(conn, username, hashed_password, "user")
|
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)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from api.utils import decrypt_str
|
||||||
|
|
||||||
|
|
||||||
class Token(BaseModel):
|
class Token(BaseModel):
|
||||||
@ -103,6 +104,7 @@ class Account(BaseModel):
|
|||||||
self.id = params["id"]
|
self.id = params["id"]
|
||||||
self.platform = params["platform"]
|
self.platform = params["platform"]
|
||||||
self.login = params["login"]
|
self.login = params["login"]
|
||||||
|
self.password = decrypt_str(params["password"])
|
||||||
self.metadata = params["metadata"]
|
self.metadata = params["metadata"]
|
||||||
self.created_at = params["created_at"]
|
self.created_at = params["created_at"]
|
||||||
id: int = -1
|
id: int = -1
|
||||||
|
|||||||
@ -4,7 +4,6 @@ from typing import Annotated
|
|||||||
import bcrypt
|
import bcrypt
|
||||||
import jwt
|
import jwt
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.Random import get_random_bytes
|
|
||||||
from Crypto.Util.Padding import pad, unpad
|
from Crypto.Util.Padding import pad, unpad
|
||||||
from fastapi import Depends, HTTPException, status
|
from fastapi import Depends, HTTPException, status
|
||||||
from fastapi.security import OAuth2PasswordBearer
|
from fastapi.security import OAuth2PasswordBearer
|
||||||
@ -20,14 +19,14 @@ from db.internal import get_db_connection
|
|||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
||||||
|
|
||||||
|
|
||||||
def encrypt_str(string, key_hex):
|
def encrypt_str(string):
|
||||||
key = bytes.fromhex(key_hex)
|
key = bytes.fromhex(startup_settings.secret_key)
|
||||||
cipher = AES.new(key, AES.MODE_ECB) # Простейший режим (небезопасно для больших данных!)
|
cipher = AES.new(key, AES.MODE_ECB)
|
||||||
encrypted_string = cipher.encrypt(pad(string.encode(), AES.block_size))
|
encrypted_string = cipher.encrypt(pad(string.encode(), AES.block_size))
|
||||||
return encrypted_string
|
return encrypted_string
|
||||||
|
|
||||||
def decrypt_str(encrypted_string, key_hex):
|
def decrypt_str(encrypted_string):
|
||||||
key = bytes.fromhex(key_hex)
|
key = bytes.fromhex(startup_settings.secret_key)
|
||||||
cipher = AES.new(key, AES.MODE_ECB)
|
cipher = AES.new(key, AES.MODE_ECB)
|
||||||
string = unpad(cipher.decrypt(encrypted_string), AES.block_size)
|
string = unpad(cipher.decrypt(encrypted_string), AES.block_size)
|
||||||
return string.decode()
|
return string.decode()
|
||||||
|
|||||||
@ -23,8 +23,7 @@ def create_account(
|
|||||||
""",
|
""",
|
||||||
(platform, login, password, json.dumps(metadata)),
|
(platform, login, password, json.dumps(metadata)),
|
||||||
)
|
)
|
||||||
conn.commit()
|
return conn.commit()
|
||||||
return cur.rowcount > 0
|
|
||||||
|
|
||||||
|
|
||||||
def delete_account(
|
def delete_account(
|
||||||
|
|||||||
@ -68,6 +68,7 @@ create table picrinth.swipes (
|
|||||||
constraint swipes_unique unique (username, feed_id, picture_id)
|
constraint swipes_unique unique (username, feed_id, picture_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- TODO: add author?
|
||||||
create table picrinth.accounts (
|
create table picrinth.accounts (
|
||||||
id serial not null,
|
id serial not null,
|
||||||
platform text not null,
|
platform text not null,
|
||||||
|
|||||||
Reference in New Issue
Block a user