117 lines
3.9 KiB
Python
117 lines
3.9 KiB
Python
import requests
|
|
import time
|
|
import base64
|
|
import json
|
|
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
|
|
from app.models.gameservers import GameServer
|
|
|
|
from config import Config
|
|
|
|
config = Config()
|
|
|
|
def sign_content( content : bytes ) -> str:
|
|
"""
|
|
Signs the given content using the gameserver private key
|
|
|
|
:param content: The content to sign
|
|
|
|
:returns: str
|
|
"""
|
|
assert isinstance( content, bytes ), "content must be a bytes object"
|
|
|
|
with open( config.GAMESERVER_COMM_PRIVATE_KEY_LOCATION, "rb" ) as f:
|
|
private_key = serialization.load_pem_private_key(
|
|
f.read(),
|
|
password=None,
|
|
backend=default_backend()
|
|
)
|
|
|
|
signature = private_key.sign(
|
|
content,
|
|
padding.PKCS1v15(),
|
|
hashes.SHA256()
|
|
)
|
|
|
|
return base64.b64encode( signature ).decode( "utf-8" )
|
|
|
|
def perform_get(
|
|
TargetGameserver : GameServer,
|
|
Endpoint : str,
|
|
AdditionalHeaders : dict = {},
|
|
|
|
RequestTimeout : int = 10
|
|
) -> requests.Response:
|
|
"""
|
|
Performs a GET request to the given gameserver
|
|
|
|
:param TargetGameserver: The gameserver to send the request to
|
|
:param Endpoint: The endpoint to send the request to
|
|
:param AdditionalHeaders: Additional headers to send with the request
|
|
:param RequestTimeout: The amount of time before the request times out
|
|
|
|
:returns: requests.Response
|
|
"""
|
|
assert isinstance( TargetGameserver, GameServer ), "TargetGameserver must be an instance of GameServer"
|
|
assert isinstance( Endpoint, str ), "Endpoint must be a string"
|
|
assert isinstance( AdditionalHeaders, dict ), "AdditionalHeaders must be a dictionary"
|
|
|
|
RequestTimestamp = time.time()
|
|
signed_content = sign_content( f'{RequestTimestamp}\nGET'.encode( 'utf-8' ) )
|
|
ReqSignature = f"{str(RequestTimestamp)}|{ signed_content }"
|
|
|
|
headers = {
|
|
"User-Agent": "SYNTAX-Gameserver-Communication/1.0",
|
|
"X-Syntax-Request-Signature": ReqSignature
|
|
}
|
|
|
|
return requests.get(
|
|
url = f"http://{TargetGameserver.serverIP}:{TargetGameserver.serverPort}/{Endpoint}",
|
|
headers = headers,
|
|
timeout = RequestTimeout
|
|
)
|
|
|
|
def perform_post(
|
|
TargetGameserver : GameServer,
|
|
Endpoint : str,
|
|
JSONData : dict | list = {},
|
|
AdditionalHeaders : dict = {},
|
|
|
|
RequestTimeout : int = 10
|
|
) -> requests.Response:
|
|
"""
|
|
Performs a POST request to the given gameserver
|
|
|
|
:param TargetGameserver: The gameserver to send the request to
|
|
:param Endpoint: The endpoint to send the request to
|
|
:param JSONData: The JSON data to send with the request
|
|
:param AdditionalHeaders: Additional headers to send with the request
|
|
:param RequestTimeout: The amount of time before the request times out
|
|
|
|
:returns: requests.Response
|
|
"""
|
|
assert isinstance( TargetGameserver, GameServer ), "TargetGameserver must be an instance of GameServer"
|
|
assert isinstance( Endpoint, str ), "Endpoint must be a string"
|
|
assert isinstance( JSONData, ( dict, list ) ), "JSONData must be a dictionary or list"
|
|
assert isinstance( AdditionalHeaders, dict ), "AdditionalHeaders must be a dictionary"
|
|
|
|
RequestTimestamp = time.time()
|
|
signed_content = sign_content( f"{RequestTimestamp}\nPOST\n{json.dumps(JSONData)}".encode( "utf-8" ))
|
|
ReqSignature = f"{str(RequestTimestamp)}|{signed_content}"
|
|
|
|
headers = {
|
|
"User-Agent": "SYNTAX-Gameserver-Communication/1.0",
|
|
"X-Syntax-Request-Signature": ReqSignature,
|
|
"Content-Type": "application/json"
|
|
}
|
|
headers.update( AdditionalHeaders )
|
|
|
|
return requests.post(
|
|
url = f"http://{TargetGameserver.serverIP}:{TargetGameserver.serverPort}/{Endpoint}",
|
|
headers = headers,
|
|
data = json.dumps( JSONData ),
|
|
timeout = RequestTimeout
|
|
) |