Centralisation des constantes modifiable vers le même fichier.

This commit is contained in:
2026-03-27 12:08:22 +01:00
parent 3863cd4140
commit eda3a9cd3b
9 changed files with 53 additions and 49 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <excludeFolder url="file://$MODULE_DIR$/.venv" />
</content> </content>
<orderEntry type="jdk" jdkName="uv (PyQt6_LaTaniere)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.13 (Lataniere_ui_1)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>
+1 -1
View File
@@ -3,5 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="uv (PyQt6_LaTaniere)" /> <option name="sdkName" value="uv (PyQt6_LaTaniere)" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="uv (PyQt6_LaTaniere)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (Lataniere_ui_1)" project-jdk-type="Python SDK" />
</project> </project>
+20 -12
View File
@@ -6,10 +6,6 @@ from PySide6.QtGui import QColor
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Constants # Constants
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
FIVEMURL = "fivem://connect/prod.la-taniere.fun"
REDIRECT_URI = "http://localhost:5000/callback"
SCOPES = ["identify"]
CLIENT_ID = "1240007913175781508"
AUTENTICATION_SUCCESS_MESSAGE = """ AUTENTICATION_SUCCESS_MESSAGE = """
<html> <html>
<head> <head>
@@ -30,16 +26,28 @@ class Resources(Enum):
FONT = ':/assets/Avocado-Cake-Demo.otf' FONT = ':/assets/Avocado-Cake-Demo.otf'
class Urls(Enum): class Urls(Enum):
DISCORD = 'https://discord.gg/A7eanmSkp2' DISCORD = 'https://discord.gg/A7eanmSkp2' # <- La Tanière invitation Discord
INTRANET = 'https://la-taniere.fun/connexion/' INTRANET = 'https://la-taniere.fun/connexion/' # <- La Tanière site web
API_URL = 'https://prod.la-taniere.fun:30121/' API_URL = 'https://prod.la-taniere.fun:30121' # <- La Tanière Api url
FIVEMURL = 'fivem://connect/prod.la-taniere.fun' # <- La Tanière FiveM addresse
LOCAL_CALLBACK_PORT = 5000
LOCAL_CALLBACK_HOST = 'localhost'
LOCAL_CALLBACK_URL = f'http://{LOCAL_CALLBACK_HOST}:{LOCAL_CALLBACK_PORT}/callback' # <- Url de Callback OAuth DiscordA
class ApiEndPoints(Enum): class ApiEndPoints(Enum):
QUEUE_STATUS = '/queue/status/' API_VERSION = 'api_v2'
QUEUE_LEAVE = '/queue/leave' QUEUE_STATUS = 'queue/status/'
QUEUE_JOIN = '/queue/join' QUEUE_LEAVE = 'queue/leave'
QUEUE_REFRESH = '/queue/refresh' QUEUE_JOIN = 'queue/join'
REGISTER_USER = '/api_v2/connection/register' QUEUE_REFRESH = 'queue/refresh'
WHITELIST_URL_ENDPOINT = "iswhitelist"
REGISTER_USER = f'{API_VERSION}/connection/register'
TOKEN_AUTH = f'{API_VERSION}/tkn_auth'
AUTHENTICATION = f'{API_VERSION}/auth'
class DiscordApplicationReferences(Enum):
SCOPES = ["identify"]
CLIENT_ID = "1240007913175781508"
class Glow(Enum): class Glow(Enum):
COLOR = QColor(255, 140, 0, 255) COLOR = QColor(255, 140, 0, 255)
+9 -12
View File
@@ -3,7 +3,7 @@ import webbrowser
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs, urlencode, urlparse from urllib.parse import parse_qs, urlencode, urlparse
from config.constants import AUTENTICATION_SUCCESS_MESSAGE, CLIENT_ID, REDIRECT_URI, SCOPES from config.constants import AUTENTICATION_SUCCESS_MESSAGE, DiscordApplicationReferences, Urls
from fivemserver.get_server_token import GetServerTokenForDiscord from fivemserver.get_server_token import GetServerTokenForDiscord
from tools.http_client import ApiError, http_get, http_post from tools.http_client import ApiError, http_get, http_post
@@ -13,8 +13,6 @@ os.environ['PYTHONWARNINGS'] = 'ignore'
OAUTH_AUTHORIZE_URL = "https://discord.com/api/oauth2/authorize" OAUTH_AUTHORIZE_URL = "https://discord.com/api/oauth2/authorize"
OAUTH_TOKEN_URL = "https://discord.com/api/oauth2/token" OAUTH_TOKEN_URL = "https://discord.com/api/oauth2/token"
DISCORD_ME_URL = "https://discord.com/api/users/@me" DISCORD_ME_URL = "https://discord.com/api/users/@me"
LOCAL_CALLBACK_HOST = "localhost"
LOCAL_CALLBACK_PORT = 5000
class OAuthCallbackHandler(BaseHTTPRequestHandler): class OAuthCallbackHandler(BaseHTTPRequestHandler):
code: str | None = None code: str | None = None
@@ -45,7 +43,7 @@ def get_discord_client_id() -> str:
""" """
return discord application id return discord application id
""" """
return CLIENT_ID return DiscordApplicationReferences.CLIENT_ID.value
# return discord user id # return discord user id
def get_discord_user_id() -> tuple[str, str]: def get_discord_user_id() -> tuple[str, str]:
@@ -57,17 +55,16 @@ def get_discord_user_id() -> tuple[str, str]:
session_id = GetServerTokenForDiscord.authenticate() session_id = GetServerTokenForDiscord.authenticate()
client_secret = GetServerTokenForDiscord.get_token(session_id) client_secret = GetServerTokenForDiscord.get_token(session_id)
auth_url = "https://discord.com/api/oauth2/authorize"
params = { params = {
"client_id": CLIENT_ID, "client_id": DiscordApplicationReferences.CLIENT_ID.value,
"redirect_uri": REDIRECT_URI, "redirect_uri": Urls.LOCAL_CALLBACK_URL.value,
"response_type": "code", "response_type": "code",
"scope": " ".join(SCOPES), "scope": " ".join(DiscordApplicationReferences.SCOPES.value),
} }
webbrowser.open(f"{auth_url}?{urlencode(params)}") webbrowser.open(f"{OAUTH_AUTHORIZE_URL}?{urlencode(params)}")
server = HTTPServer((LOCAL_CALLBACK_HOST, LOCAL_CALLBACK_PORT), OAuthCallbackHandler) server = HTTPServer((Urls.LOCAL_CALLBACK_HOST.value, Urls.LOCAL_CALLBACK_PORT.value), OAuthCallbackHandler)
try: try:
server.handle_request() server.handle_request()
@@ -81,11 +78,11 @@ def get_discord_user_id() -> tuple[str, str]:
token = http_post( token = http_post(
OAUTH_TOKEN_URL, OAUTH_TOKEN_URL,
data={ data={
"client_id": CLIENT_ID, "client_id": DiscordApplicationReferences.CLIENT_ID.value,
"client_secret": client_secret, "client_secret": client_secret,
"grant_type": "authorization_code", "grant_type": "authorization_code",
"code": OAuthCallbackHandler.code, "code": OAuthCallbackHandler.code,
"redirect_uri": REDIRECT_URI, "redirect_uri": Urls.LOCAL_CALLBACK_URL.value,
}, },
headers={"Content-Type": "application/x-www-form-urlencoded"}, headers={"Content-Type": "application/x-www-form-urlencoded"},
).json() ).json()
+2 -3
View File
@@ -1,8 +1,7 @@
import psutil import psutil
from pypresence import Presence from pypresence import Presence
from config.constants import Urls from config.constants import Urls, DiscordApplicationReferences
from discord.discord_oauth import CLIENT_ID
from fivemserver.get_server_token import GetServerTokenForDiscord from fivemserver.get_server_token import GetServerTokenForDiscord
@@ -40,7 +39,7 @@ class CheckDiscord:
Vérifie si l'utilisateur Discord est connecté. Vérifie si l'utilisateur Discord est connecté.
⚠️ne vérifie pas le user id discord. ⚠️ne vérifie pas le user id discord.
""" """
rpc = Presence(CLIENT_ID) rpc = Presence(DiscordApplicationReferences.CLIENT_ID.value)
try: try:
rpc.connect() rpc.connect()
return True return True
+4 -2
View File
@@ -1,6 +1,8 @@
import os import os
import subprocess import subprocess
from config.constants import Urls
class FiveMLauncher: class FiveMLauncher:
def __init__(self, fivem_path: str): def __init__(self, fivem_path: str):
@@ -15,5 +17,5 @@ class FiveMLauncher:
subprocess.Popen(self.fivem_path, shell=True) subprocess.Popen(self.fivem_path, shell=True)
""" """
#subprocess.Popen(f"explorer {FIVEMURL}") subprocess.Popen(f"explorer {Urls.FIVEMURL.value}")
subprocess.Popen(r'explorer fivem://connect/prod.la-taniere.fun') #subprocess.Popen(r'explorer fivem://connect/prod.la-taniere.fun')
+9 -9
View File
@@ -5,7 +5,7 @@ from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from config.constants import Urls from config.constants import Urls, ApiEndPoints
from tools.http_client import http_post, ApiError from tools.http_client import http_post, ApiError
@@ -33,18 +33,18 @@ class GetServerTokenForDiscord:
# ========================== # ==========================
try: try:
auth = http_post( auth = http_post(
f"{server}/api_v2/auth", f"{server}/{ApiEndPoints.AUTHENTICATION.value}",
json={"client_pub": base64.b64encode(client_pub_pem).decode()}, json={"client_pub": base64.b64encode(client_pub_pem).decode()},
).json() ).json()
except ApiError: except ApiError:
raise raise
except ValueError as exc: except ValueError as exc:
raise ApiError("Réponse JSON invalide lors de l'authentification.", url=f"{server}/api_v2/auth") from exc raise ApiError("Réponse JSON invalide lors de l'authentification.", url=f"{server}/{ApiEndPoints.AUTHENTICATION.value}") from exc
server_pub_b64 = auth.get("server_pub") server_pub_b64 = auth.get("server_pub")
session_id = auth.get("session_id") session_id = auth.get("session_id")
if not server_pub_b64 or not session_id: if not server_pub_b64 or not session_id:
raise ApiError("Réponse d'authentification invalide : données manquantes.", url=f"{server}/api_v2/auth") raise ApiError("Réponse d'authentification invalide : données manquantes.", url=f"{server}/{ApiEndPoints.AUTHENTICATION.value}")
server_pub = serialization.load_pem_public_key(base64.b64decode(server_pub_b64)) server_pub = serialization.load_pem_public_key(base64.b64decode(server_pub_b64))
shared_key = client_private.exchange(ec.ECDH(), server_pub) shared_key = client_private.exchange(ec.ECDH(), server_pub)
@@ -71,19 +71,19 @@ class GetServerTokenForDiscord:
try: try:
download = http_post( download = http_post(
f"{server}/api_v2/tkn_auth", f"{server}/{ApiEndPoints.TOKEN_AUTH.value}",
headers={"x-session-id": session_id}, headers={"x-session-id": session_id},
).json() ).json()
except ApiError: except ApiError:
raise raise
except ValueError as exc: except ValueError as exc:
raise ApiError("Réponse JSON invalide lors de la récupération du token.", raise ApiError("Réponse JSON invalide lors de la récupération du token.",
url=f"{server}/api_v2/tkn_auth") from exc url=f"{server}/{ApiEndPoints.TOKEN_AUTH.value}") from exc
nonce_b64 = download.get("nonce") nonce_b64 = download.get("nonce")
encrypted_data_b64 = download.get("data") encrypted_data_b64 = download.get("data")
if not nonce_b64 or not encrypted_data_b64: if not nonce_b64 or not encrypted_data_b64:
raise ApiError("Réponse de token invalide : nonce ou data manquant.", url=f"{server}/api_v2/tkn_auth") raise ApiError("Réponse de token invalide : nonce ou data manquant.", url=f"{server}/{ApiEndPoints.TOKEN_AUTH.value}")
nonce = base64.b64decode(nonce_b64) nonce = base64.b64decode(nonce_b64)
encrypted_data = base64.b64decode(encrypted_data_b64) encrypted_data = base64.b64decode(encrypted_data_b64)
@@ -99,7 +99,7 @@ class GetServerTokenForDiscord:
try: try:
registration_data = http_post( registration_data = http_post(
f"{server}/api_v2/connection/register", f"{server}/{ApiEndPoints.REGISTER_USER.value}",
headers={"x-session-id": session_id}, headers={"x-session-id": session_id},
json={"discord_id": discord_user_id}, json={"discord_id": discord_user_id},
).json() ).json()
@@ -108,7 +108,7 @@ class GetServerTokenForDiscord:
except ValueError as exc: except ValueError as exc:
raise ApiError( raise ApiError(
"Réponse JSON invalide lors de l'enregistrement Discord.", "Réponse JSON invalide lors de l'enregistrement Discord.",
url=f"{server}/api_v2/connection/register", url=f"{server}/{ApiEndPoints.REGISTER_USER.value}",
) from exc ) from exc
return bool(registration_data.get("success", False)) return bool(registration_data.get("success", False))
+4 -4
View File
@@ -20,7 +20,7 @@ class QueueManager:
def join_queue(self) -> dict: def join_queue(self) -> dict:
res = requests.post( res = requests.post(
f"{Urls.API_URL.value}{ApiEndPoints.QUEUE_JOIN.value}", f"{Urls.API_URL.value}/{ApiEndPoints.QUEUE_JOIN.value}",
json={"uuid": self.user_id}, json={"uuid": self.user_id},
verify=False verify=False
) )
@@ -28,13 +28,13 @@ class QueueManager:
def check_status(self) -> dict: def check_status(self) -> dict:
res = requests.get( res = requests.get(
f"{Urls.API_URL.value}{ApiEndPoints.QUEUE_STATUS.value}/{self.user_id}" f"{Urls.API_URL.value}/{ApiEndPoints.QUEUE_STATUS.value}/{self.user_id}"
) )
return res.json() return res.json()
def leave_queue(self): def leave_queue(self):
requests.post( requests.post(
f"{Urls.API_URL.value}{ApiEndPoints.QUEUE_LEAVE.value}", f"{Urls.API_URL.value}/{ApiEndPoints.QUEUE_LEAVE.value}",
json={"uuid": self.user_id}, json={"uuid": self.user_id},
verify=False verify=False
) )
@@ -46,7 +46,7 @@ class QueueManager:
return return
try: try:
requests.post( requests.post(
f"{Urls.API_URL.value}{ApiEndPoints.QUEUE_REFRESH.value}", f"{Urls.API_URL.value}/{ApiEndPoints.QUEUE_REFRESH.value}",
json={ json={
"uuid": self.user_id, "uuid": self.user_id,
"session_id": session_id, "session_id": session_id,
+3 -5
View File
@@ -1,20 +1,18 @@
from config.constants import PlayerServerInfo from config.constants import PlayerServerInfo
from tools.http_client import ApiError, http_get from tools.http_client import ApiError, http_get
from config.constants import ApiEndPoints
WHITELIST_URL_ENDPOINT = "iswhitelist/"
class WhiteList: class WhiteList:
@staticmethod @staticmethod
def check_whitelist(url: str, discord_user_id: str) -> None: def check_whitelist(url: str, discord_user_id: str) -> None:
try: try:
api_data = http_get(f"{url}{WHITELIST_URL_ENDPOINT}{discord_user_id}").json() api_data = http_get(f"{url}/{ApiEndPoints.WHITELIST_URL_ENDPOINT.value}/{discord_user_id}").json()
except ApiError: except ApiError:
raise raise
except ValueError as exc: except ValueError as exc:
raise ApiError( raise ApiError(
"Réponse JSON invalide lors de la vérification whitelist.", "Réponse JSON invalide lors de la vérification whitelist.",
url=f"{url}{WHITELIST_URL_ENDPOINT}{discord_user_id}", url=f"{url}/{ApiEndPoints.WHITELIST_URL_ENDPOINT.value}/{discord_user_id}",
) from exc ) from exc
PlayerServerInfo.is_whitelist = api_data.get("whitelisted", False) PlayerServerInfo.is_whitelist = api_data.get("whitelisted", False)