This commit is contained in:
itqop 2024-04-15 14:18:31 +03:00
parent 0c886205fe
commit 2c02ce1048
8 changed files with 141 additions and 10 deletions

View File

@ -19,7 +19,7 @@ async def get_uuid(request: RequestSchema):
@app.post("/check_subscription/") @app.post("/check_subscription/")
async def check_subscription(request: RequestSchema): async def check_subscription(request: RequestSchema):
profile = await get_profile(schema=request) profile = await get_profile(schema=request)
subscription_status = await database.check_subscription_by_uuid(user=profile) subscription_status = await database.check_subscription_by_nickname(user=profile)
return {"has_subscription": subscription_status} return {"has_subscription": subscription_status}
@app.post("/check_ban_status/") @app.post("/check_ban_status/")
@ -53,15 +53,28 @@ async def grant_tab(request: RequestSchema):
await database.grant_tab_by_username(user=profile, tab=request.tab) await database.grant_tab_by_username(user=profile, tab=request.tab)
return {"message": "Tab granted successfully"} return {"message": "Tab granted successfully"}
@app.post("/grant_subscribe/")
async def grant_tab(request: RequestSchema):
profile = await get_profile(schema=request)
await database.update_subscription(user=profile)
async def get_profile(schema: RequestSchema) -> UserSchema: async def get_profile(schema: RequestSchema) -> UserSchema:
await database.delete_expired_tab_users() await database.delete_expired_tab_users()
uuid = await database.get_uuid_by_username(schema) uuid = await database.get_uuid_by_username(schema)
if not uuid: if not uuid:
raise HTTPException(status_code=404, detail="User not found") raise HTTPException(status_code=404, detail="User not found")
discord_id = await database.get_discord(schema)
if not discord_id:
raise HTTPException(status_code=404, detail="User not found in whitelist")
has_sub = await database.check_subscription_by_nickname(schema)
profile = UserSchema.model_construct( profile = UserSchema.model_construct(
username=schema.username, username=schema.username,
uuid=uuid, uuid=uuid,
expiry=schema.validated_expiry discord_id=discord_id,
expiry=schema.validated_expiry,
has_sub=has_sub,
tab=schema.tab
) )
print(profile)
return profile return profile

View File

@ -1,6 +1,7 @@
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import PositiveInt, computed_field, MySQLDsn from pydantic import PositiveInt, computed_field, MySQLDsn
from pydantic_core import Url from pydantic_core import Url
import httpx
class Configs(BaseSettings): class Configs(BaseSettings):
@ -9,6 +10,9 @@ class Configs(BaseSettings):
DATABASE: str DATABASE: str
USERNAME: str USERNAME: str
PASSWORD: str PASSWORD: str
HOST_DS: str
PORT_DS: PositiveInt
TOKEN_DS: str
@computed_field @computed_field
def DB_URI(self) -> MySQLDsn: def DB_URI(self) -> MySQLDsn:
@ -16,6 +20,13 @@ class Configs(BaseSettings):
f"mysql+aiomysql://{self.USERNAME}:{self.PASSWORD}@{self.HOST}:{self.PORT}/{self.DATABASE}?charset=utf8mb4" f"mysql+aiomysql://{self.USERNAME}:{self.PASSWORD}@{self.HOST}:{self.PORT}/{self.DATABASE}?charset=utf8mb4"
) )
@computed_field
def DS_URL(self) -> httpx.URL:
return httpx.URL(
f"http://{self.HOST_DS}:{self.PORT_DS}/force-assign-role"
)
model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8') model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')
configs = Configs() configs = Configs()

View File

@ -1,3 +1,3 @@
from db.sql_schemas import TabUser, LuckpermsUserPermission, LitebansBan, LuckpermsPlayer from db.sql_schemas import TabUser, LuckpermsUserPermission, LitebansBan, LuckpermsPlayer, Subscribe, Whitelist
from db.database import Database from db.database import Database
from db.schemas import UUIDSchema, MySQLConfig, UserSchema, RequestSchema, TabSchema from db.schemas import UUIDSchema, MySQLConfig, UserSchema, RequestSchema, TabSchema

View File

@ -1,12 +1,15 @@
from sqlalchemy import select, delete from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import create_async_engine from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from db import LuckpermsPlayer, LitebansBan, LuckpermsUserPermission, TabUser from db import LuckpermsPlayer, LitebansBan, LuckpermsUserPermission, TabUser, Subscribe, Whitelist
from db.schemas import MySQLConfig, UserSchema, RequestSchema, TabSchema from db.schemas import MySQLConfig, UserSchema, RequestSchema, TabSchema
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from aiocache import cached, SimpleMemoryCache from aiocache import cached, SimpleMemoryCache
from aiocache.serializers import PickleSerializer from aiocache.serializers import PickleSerializer
import datetime import datetime
import httpx
from config import configs
class Database: class Database:
def __init__(self, uri: MySQLConfig): def __init__(self, uri: MySQLConfig):
@ -55,18 +58,18 @@ class Database:
session.add(permission) session.add(permission)
await session.commit() await session.commit()
async def grant_tab_by_username(self, user: UserSchema, tab: TabSchema): async def grant_tab_by_username(self, user: UserSchema):
async with self.AsyncSessionLocal() as session: async with self.AsyncSessionLocal() as session:
prefix = TabUser( prefix = TabUser(
user=user.username, user=user.username,
property=tab.property, property=user.tab.property,
value=tab.value, value=user.tab.value,
expiry=user.expiry expiry=user.expiry
) )
session.add(prefix) session.add(prefix)
await session.commit() await session.commit()
async def check_subscription_by_uuid(self, user: UserSchema) -> bool: async def check_subscription_by_uuid_old(self, user: UserSchema) -> bool:
async with self.AsyncSessionLocal() as session: async with self.AsyncSessionLocal() as session:
subscription = await session.execute( subscription = await session.execute(
select(LuckpermsUserPermission).filter( select(LuckpermsUserPermission).filter(
@ -79,6 +82,19 @@ class Database:
else: else:
return False return False
async def check_subscription_by_nickname(self, user: UserSchema) -> bool:
async with self.AsyncSessionLocal() as session:
subscription = await session.execute(
select(Subscribe).filter(
Subscribe.nickname == user.username,
Subscribe.expiry > datetime.datetime.now()
)
)
if subscription.scalar():
return True
else:
return False
@cached(ttl=2, cache=SimpleMemoryCache, serializer=PickleSerializer()) @cached(ttl=2, cache=SimpleMemoryCache, serializer=PickleSerializer())
async def check_ban_status_by_uuid(self, user: UserSchema) -> bool: async def check_ban_status_by_uuid(self, user: UserSchema) -> bool:
async with self.AsyncSessionLocal() as session: async with self.AsyncSessionLocal() as session:
@ -103,3 +119,66 @@ class Database:
.where(TabUser.expiry != 0) .where(TabUser.expiry != 0)
) )
await session.commit() await session.commit()
async def get_discord(self, user: UserSchema):
discord = None
async with self.AsyncSessionLocal() as session:
try:
result = await session.execute(select(Whitelist).where(Whitelist.player == user.username))
record = result.fetchone()
if record:
discord = record[0].discord
else:
discord = None
except Exception as e:
print("Ошибка при выполнении запроса:", e)
if isinstance(discord, str) and len(discord) > 8:
return discord
else:
return None
async def update_subscription(self, user: UserSchema):
async with self.AsyncSessionLocal() as session:
try:
expiry_datetime = datetime.datetime.fromtimestamp(user.expiry, datetime.timezone.utc)
if user.has_sub:
subscription = await session.execute(select(Subscribe).where(Subscribe.discord == user.discord_id and Subscribe.nickname == user.username))
subscription = subscription.fetchone()[0]
if subscription:
updated_expiry = subscription.expiry + (expiry_datetime - datetime.datetime.now(datetime.timezone.utc))
subscription.expiry = updated_expiry
else:
new_subscription = Subscribe(discord=user.discord_id, nickname=user.username, expiry=expiry_datetime)
session.add(new_subscription)
else:
new_subscription = Subscribe(discord=user.discord_id, nickname=user.username, expiry=expiry_datetime)
session.add(new_subscription)
await session.commit()
await self.grant_tab_by_username(user=user)
await self.grant_permissions_by_uuid(user=user)
await discord_role(user.discord_id)
except Exception as e:
print("Ошибка при выполнении запроса:", e)
await session.rollback()
async def delete_expired_subscriptions(self):
async with self.AsyncSessionLocal() as session:
try:
await session.execute(delete(Subscribe).where(Subscribe.expiry < datetime.now(datetime.timezone.utc)))
await session.commit()
except Exception as e:
print("Ошибка при удалении устаревших подписок:", e)
await session.rollback()
async def discord_role(discord_id: int):
params = {"user_id": discord_id, "token": configs.TOKEN_DS}
async with httpx.AsyncClient() as client:
try:
response = await client.get(configs.DS_URL, params=params)
data = response.json()
return data
except httpx.HTTPError as e:
print(f"Ошибка при отправке запроса: {e}")
return {"error": "Произошла ошибка при выполнении запроса"}

View File

@ -4,4 +4,6 @@ from .UUIDSchema import UUIDSchema
class UserSchema(UUIDSchema): class UserSchema(UUIDSchema):
username: str username: str
discord_id: str
has_sub: bool
expiry: PositiveInt = 1 expiry: PositiveInt = 1

View File

@ -0,0 +1,11 @@
from sqlalchemy import Column, Integer, String, TIMESTAMP
from .Base import Base
class Subscribe(Base):
__tablename__ = 'subscribe'
id = Column(Integer, primary_key=True, autoincrement=True)
discord = Column(String(36))
nickname = Column(String(20))
expiry = Column(TIMESTAMP)

View File

@ -0,0 +1,13 @@
from .Base import Base
from sqlalchemy import Column, Integer, String, TIMESTAMP
from sqlalchemy.sql import func
class Whitelist(Base):
__tablename__ = 'whitelist'
id = Column(Integer, primary_key=True, autoincrement=True)
player = Column(String(16), nullable=False)
discord = Column(String(36), nullable=True, default=None)
added_on = Column(TIMESTAMP, server_default=func.now())

View File

@ -2,3 +2,5 @@ from .LitebansBan import LitebansBan
from .LuckpermsPlayer import LuckpermsPlayer from .LuckpermsPlayer import LuckpermsPlayer
from .LuckpermsUserPermission import LuckpermsUserPermission from .LuckpermsUserPermission import LuckpermsUserPermission
from .TabUser import TabUser from .TabUser import TabUser
from .Subscribe import Subscribe
from .Whitelist import Whitelist