This commit is contained in:
ciomek committed 2026-09-04 17:31:30 +02:00
1 parent 5732e26380
commit dbed39ee3a
11 files changed
+122 -61

No files matched your search

+4 -1
View File
@@ -8,6 +8,7 @@ from starlette.authentication import (
)
from starlette.requests import HTTPConnection
from starlette.responses import JSONResponse, Response
from sqlalchemy.orm import selectinload
from sqlmodel import Session, select
from loon.web.db import engine
@@ -62,7 +63,9 @@ class JWTAuthBackend(AuthenticationBackend):
raise AuthenticationError("Invalid or expired token")
with Session(engine) as session:
user = session.exec(select(User).where(User.id == user_id)).first()
user = session.exec(
select(User).where(User.id == user_id).options(selectinload(User.minecraft_user))
).first()
if user is None:
raise AuthenticationError("User not found")
+16 -2
View File
@@ -1,9 +1,23 @@
from sqlmodel import SQLModel, Field
from sqlmodel import SQLModel, Field, Relationship
class MinecraftUser(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
uuid: str = Field(unique=True)
username: str
user: "User" = Relationship(back_populates="minecraft_user")
class User(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
uuid: str = Field(unique=True)
minecraft_user_id: int = Field(foreign_key="minecraftuser.id", nullable=False, unique=True)
minecraft_user: MinecraftUser = Relationship(back_populates="user")
internal_username: str = Field(unique=True)
password: str
admin: bool = Field(default=False)
@property
def uuid(self) -> str:
return self.minecraft_user.uuid
+5 -1
View File
@@ -11,7 +11,11 @@ router = APIRouter(prefix="/users", tags=["users"])
@router.get("/me")
@authenticated
async def me(request: Request):
return request.user.user.model_dump(exclude={"password", "id"})
user = request.user.user
return {
**user.model_dump(exclude={"password", "id", "minecraft_user_id"}),
"minecraft_user": user.minecraft_user.model_dump(exclude={"id"}),
}
@router.post("/inventory/request")
@authenticated
+43
View File
@@ -0,0 +1,43 @@
import asyncio
from sqlmodel import Session, select
from loon.web.db import engine
from loon.web.users.models import MinecraftUser
def _sync_minecraft_users(players: list[dict]) -> list[MinecraftUser]:
players_by_uuid = {player["uuid"]: player["username"] for player in players}
with Session(engine) as session:
existing = session.exec(
select(MinecraftUser).where(MinecraftUser.uuid.in_(players_by_uuid))
).all()
existing_by_uuid = {minecraft_user.uuid: minecraft_user for minecraft_user in existing}
new_users = []
for uuid, username in players_by_uuid.items():
minecraft_user = existing_by_uuid.get(uuid)
if minecraft_user is None:
minecraft_user = MinecraftUser(uuid=uuid, username=username)
new_users.append(minecraft_user)
session.add(minecraft_user)
elif minecraft_user.username != username:
minecraft_user.username = username
session.add(minecraft_user)
session.commit()
minecraft_users = [*existing, *new_users]
for minecraft_user in minecraft_users:
session.refresh(minecraft_user)
return minecraft_users
async def sync_minecraft_users(players: list[dict]) -> list[MinecraftUser]:
if not players:
return []
return await asyncio.to_thread(_sync_minecraft_users, players)