worikng base version
This commit is contained in:
@ -1,3 +1,5 @@
|
|||||||
|
import base64
|
||||||
|
import json
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
from .models import UserLogin, UserInDB, Session, UserCreate
|
from .models import UserLogin, UserInDB, Session, UserCreate
|
||||||
from .utils import (
|
from .utils import (
|
||||||
@ -61,10 +63,12 @@ class AuthService:
|
|||||||
}
|
}
|
||||||
|
|
||||||
async def validate(self, access_token: str, client_token: str):
|
async def validate(self, access_token: str, client_token: str):
|
||||||
|
print(f"Searching for access_toke and client_token: '{access_token}', '{client_token}")
|
||||||
session = await sessions_collection.find_one({
|
session = await sessions_collection.find_one({
|
||||||
"access_token": access_token,
|
"access_token": access_token,
|
||||||
"client_token": client_token,
|
"client_token": client_token,
|
||||||
})
|
})
|
||||||
|
print("Session from DB:", session)
|
||||||
if not session or datetime.utcnow() > session["expires_at"]:
|
if not session or datetime.utcnow() > session["expires_at"]:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@ -80,3 +84,83 @@ class AuthService:
|
|||||||
{"$set": {"access_token": new_access_token}},
|
{"$set": {"access_token": new_access_token}},
|
||||||
)
|
)
|
||||||
return {"accessToken": new_access_token, "clientToken": client_token}
|
return {"accessToken": new_access_token, "clientToken": client_token}
|
||||||
|
|
||||||
|
async def get_minecraft_profile(self, uuid: str):
|
||||||
|
formatted_uuid = f"{uuid[:8]}-{uuid[8:12]}-{uuid[12:16]}-{uuid[16:20]}-{uuid[20:]}"
|
||||||
|
user = await users_collection.find_one({"uuid": formatted_uuid})
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"User not found (searched for UUID: {formatted_uuid})"
|
||||||
|
)
|
||||||
|
|
||||||
|
textures = {
|
||||||
|
"timestamp": int(datetime.now().timestamp()),
|
||||||
|
"profileId": formatted_uuid,
|
||||||
|
"profileName": user["username"],
|
||||||
|
"textures": {
|
||||||
|
"SKIN": {"url": user.get("skin_url", "")},
|
||||||
|
"CAPE": {"url": user.get("cloak_url", "")}
|
||||||
|
} if user.get("skin_url") or user.get("cloak_url") else {}
|
||||||
|
}
|
||||||
|
|
||||||
|
textures_json = json.dumps(textures).encode()
|
||||||
|
base64_textures = base64.b64encode(textures_json).decode()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"id": formatted_uuid,
|
||||||
|
"name": user["username"],
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "textures",
|
||||||
|
"value": base64_textures
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async def join_server(self, request_data: dict):
|
||||||
|
access_token = request_data.get("accessToken")
|
||||||
|
selected_profile = request_data.get("selectedProfile")
|
||||||
|
server_id = request_data.get("serverId")
|
||||||
|
|
||||||
|
if not all([access_token, selected_profile, server_id]):
|
||||||
|
raise HTTPException(status_code=400, detail="Missing required parameters")
|
||||||
|
|
||||||
|
decoded_token = decode_token(access_token)
|
||||||
|
if not decoded_token:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid access token")
|
||||||
|
|
||||||
|
token_uuid = decoded_token.get("uuid", "").replace("-", "")
|
||||||
|
if token_uuid != selected_profile:
|
||||||
|
raise HTTPException(status_code=403, detail="Token doesn't match selected profile")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def has_joined(self, username: str, server_id: str):
|
||||||
|
user = await users_collection.find_one({"username": username})
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
|
response_uuid = user["uuid"].replace("-", "")
|
||||||
|
|
||||||
|
textures = {}
|
||||||
|
if user.get("skin_url"):
|
||||||
|
textures["SKIN"] = {"url": user["skin_url"]}
|
||||||
|
if user.get("cloak_url"):
|
||||||
|
textures["CAPE"] = {"url": user["cloak_url"]}
|
||||||
|
|
||||||
|
textures_value = base64.b64encode(json.dumps({
|
||||||
|
"timestamp": int(datetime.now().timestamp()),
|
||||||
|
"profileId": response_uuid,
|
||||||
|
"profileName": username,
|
||||||
|
"textures": textures
|
||||||
|
}).encode()).decode()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"id": response_uuid,
|
||||||
|
"name": username,
|
||||||
|
"properties": [{
|
||||||
|
"name": "textures",
|
||||||
|
"value": textures_value
|
||||||
|
}] if textures else []
|
||||||
|
}
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
from fastapi import FastAPI, Depends, HTTPException, Body
|
import base64
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
from fastapi import FastAPI, Depends, HTTPException, Body, Request, Response
|
||||||
from fastapi.security import OAuth2PasswordBearer
|
from fastapi.security import OAuth2PasswordBearer
|
||||||
from .models import UserCreate, UserLogin, ValidateRequest
|
from .models import UserCreate, UserLogin, ValidateRequest
|
||||||
from .auth import AuthService
|
from .auth import AuthService
|
||||||
from .database import users_collection
|
from .database import users_collection
|
||||||
|
from .utils import decode_token
|
||||||
import os
|
import os
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
import logging
|
||||||
|
# logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
auth_service = AuthService()
|
auth_service = AuthService()
|
||||||
@ -51,23 +57,22 @@ async def refresh_token(access_token: str, client_token: str):
|
|||||||
raise HTTPException(status_code=401, detail="Invalid tokens")
|
raise HTTPException(status_code=401, detail="Invalid tokens")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Эндпоинт для проверки скинов (Minecraft использует его)
|
@app.get("/sessionserver/session/minecraft/profile/{uuid}")
|
||||||
@app.get("/session/hasJoined")
|
async def get_minecraft_profile(uuid: str, unsigned: bool = False):
|
||||||
async def has_joined(username: str, serverId: str):
|
return await auth_service.get_minecraft_profile(uuid)
|
||||||
user = await users_collection.find_one({"username": username})
|
|
||||||
if not user:
|
|
||||||
raise HTTPException(status_code=404, detail="User not found")
|
|
||||||
|
|
||||||
return {
|
@app.post("/sessionserver/session/minecraft/join")
|
||||||
"id": user["uuid"],
|
async def join_server(request_data: dict = Body(...)):
|
||||||
"name": username,
|
try:
|
||||||
"properties": [
|
await auth_service.join_server(request_data)
|
||||||
{
|
return Response(status_code=204)
|
||||||
"name": "textures",
|
except Exception as e:
|
||||||
"value": "base64_encoded_skin_data", # Здесь можно добавить скины
|
print("Error in join_server:", str(e))
|
||||||
}
|
raise
|
||||||
],
|
|
||||||
}
|
@app.get("/sessionserver/session/minecraft/hasJoined")
|
||||||
|
async def has_joined(username: str, serverId: str):
|
||||||
|
return await auth_service.has_joined(username, serverId)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
Reference in New Issue
Block a user