Centralisation des constantes modifiable vers le même fichier.
This commit is contained in:
Generated
+1
-1
@@ -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>
|
||||||
Generated
+1
-1
@@ -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
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user