Wireguard renegotiation now flows through the new HTTPx modules

This commit is contained in:
SimplifiedPrivacy 2026-08-07 15:05:17 -04:00
parent 320037a2b1
commit 061df01a0d
8 changed files with 91 additions and 78 deletions

20
Untitled Document Normal file
View file

@ -0,0 +1,20 @@
from core.observers.ConnectionObserver import ConnectionObserver
from core.services.networking.systemwide.encrypted_proxy.get_proxy_data import post_operator_proxy
import json
observer = ConnectionObserver()
observer.subscribe("connecting", lambda msg: print(f"[CONNECT] {msg}"))
observer.subscribe("tor_bootstrapping", lambda msg: print(f"[BOOTSTRAP] {msg}"))
observer.subscribe("tor_bootstrap_progressing", lambda msg: print(f"[PROGRESS] {msg}"))
observer.subscribe("tor_bootstrapped", lambda msg: print(f"[SUCCESS] {msg}"))
observer.subscribe("custom_message", lambda msg: print(f"[INFO] {msg}"))
results = post_operator_proxy(
billing_code="2UEN-SXAJ-Z1YO-93EJ",
location_id=4,
protocol="hysteria2",
connection_observer=observer
)
print(results)

View file

@ -81,6 +81,8 @@ class ProfileController:
port_number = establish_connection(profile, ignore=ignore, connection_observer=connection_observer) port_number = establish_connection(profile, ignore=ignore, connection_observer=connection_observer)
except ConnectionError: except ConnectionError:
raise ProfileActivationError('The profile could not be enabled.') raise ProfileActivationError('The profile could not be enabled.')
except ValueError:
raise ProfileActivationError('The profile could not be enabled.')
if profile_observer is not None: if profile_observer is not None:
profile_observer.notify('enabled', profile) profile_observer.notify('enabled', profile)
@ -99,6 +101,8 @@ class ProfileController:
raise raise
except ConnectionError: except ConnectionError:
raise ProfileActivationError('The profile could not be enabled.') raise ProfileActivationError('The profile could not be enabled.')
except ValueError:
raise ProfileActivationError('The profile could not be enabled.')
@staticmethod @staticmethod
@ -163,6 +167,8 @@ class ProfileController:
)) ))
except ConnectionTerminationError: except ConnectionTerminationError:
raise ProfileDeactivationError('The profile could not be disabled.') raise ProfileDeactivationError('The profile could not be disabled.')
except ValueError:
raise ProfileDeactivationError('The profile could not be disabled.')
except FirewallError: except FirewallError:
raise raise

View file

@ -215,14 +215,14 @@ class WebServiceApiService:
return requests.post(Constants.SP_API_BASE_URL + path, headers=headers, json=body, proxies=proxies) return requests.post(Constants.SP_API_BASE_URL + path, headers=headers, json=body, proxies=proxies)
@staticmethod # @staticmethod
def get_cached_sync(proxies: Optional[dict] = None): # def get_cached_sync(proxies: Optional[dict] = None):
from requests.status_codes import codes as status_codes # from requests.status_codes import codes as status_codes
response = WebServiceApiService.__get('/cachedsync', None, proxies) # response = WebServiceApiService.__get('/cachedsync', None, proxies)
if response.status_code == status_codes.OK: # if response.status_code == status_codes.OK:
return response.json() # return response.json()
else: # else:
return None # return None

View file

@ -1,9 +1,13 @@
from core.services.networking.httpx import connect
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
from core.models.session.SessionProfile import SessionProfile from core.models.session.SessionProfile import SessionProfile
from core.models.system.SystemProfile import SystemProfile from core.models.system.SystemProfile import SystemProfile
from core.Errors import MissingSubscriptionError, MissingLocationError, InvalidSubscriptionError from core.Errors import MissingSubscriptionError, MissingLocationError, InvalidSubscriptionError
from core.services.WebServiceApiService import WebServiceApiService from core.services.WebServiceApiService import WebServiceApiService
from core.controllers.ConnectionController import ConnectionController from core.controllers.ConnectionController import ConnectionController
from core.observers.ConnectionObserver import ConnectionObserver from core.observers.ConnectionObserver import ConnectionObserver
from core.Constants import Constants
from typing import Union, Optional from typing import Union, Optional
import base64 import base64
import re import re
@ -21,16 +25,39 @@ def register_wireguard_session(
raise MissingLocationError() raise MissingLocationError()
wireguard_keys = _generate_wireguard_keys() wireguard_keys = _generate_wireguard_keys()
public_key = wireguard_keys.get('public', None)
wireguard_configuration = ConnectionController.with_preferred_connection( if not public_key:
profile.location.country_code, logger.error("No Public Key Generated. Raising ValueError")
profile.location.code, raise ValueError("No Public Key Generated.")
profile.subscription.billing_code,
wireguard_keys.get('public'), country_code = profile.location.country_code
task=WebServiceApiService.post_wireguard_session, location_code = profile.location.code
connection_observer=connection_observer billing_code = profile.subscription.billing_code
url = f'{Constants.SP_API_BASE_URL}/countries/{country_code}/locations/{location_code}/wireguard-sessions'
payload = {
'public_key': public_key
}
api_result = connect.single_endpoint(
method="post",
url=url,
observer=connection_observer,
payload=payload,
billing_code=billing_code
) )
if not api_result.valid:
if api_result.error_type == ErrorType.AUTHENTICATION_ERROR:
logger.error(f"Server is giving an Authentication error for billing ID: {billing_code}")
raise InvalidSubscriptionError(f"Invalid Subscription for {billing_code}")
else:
error_msg = f"Could Not Connect to API: {api_result.error_type}"
logger.error(error_msg)
raise ConnectionError(error_msg)
wireguard_configuration = api_result.data
if wireguard_configuration is None: if wireguard_configuration is None:
raise InvalidSubscriptionError() raise InvalidSubscriptionError()
@ -64,3 +91,16 @@ def _inject_private_key(config: str, private_key: str) -> str:
expression = re.compile(r'^(PrivateKey =)\s?$', re.MULTILINE) expression = re.compile(r'^(PrivateKey =)\s?$', re.MULTILINE)
return re.sub(expression, r'\1 ' + private_key, config) return re.sub(expression, r'\1 ' + private_key, config)
# legacy:
# ConnectionController.with_preferred_connection(
# profile.location.country_code,
# profile.location.code,
# profile.subscription.billing_code,
# wireguard_keys.get('public'),
# task=WebServiceApiService.post_wireguard_session,
# connection_observer=connection_observer
# )

View file

@ -23,8 +23,6 @@ from core.models.BaseProfile import ProfileType
from core.observers.ConnectionObserver import ConnectionObserver from core.observers.ConnectionObserver import ConnectionObserver
from core.controllers.SystemStateController import SystemStateController from core.controllers.SystemStateController import SystemStateController
from core.services.networking.systemwide.encrypted_proxy.ensure_singbox_configured import ensure_singbox_configured
def establish_connection( def establish_connection(
profile: Union[SessionProfile, SystemProfile], profile: Union[SessionProfile, SystemProfile],
ignore: tuple[type[Exception]] = (), ignore: tuple[type[Exception]] = (),

View file

@ -50,7 +50,8 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
method=method, method=method,
url=url, url=url,
observer=observer, observer=observer,
payload=payload payload=payload,
billing_code=billing_code
) )
elif not made_client and connection_type == ConnectionChoice.SYSTEM: elif not made_client and connection_type == ConnectionChoice.SYSTEM:
return ApiResponse(valid=False, error_type=ErrorType.DEVELOPER_ERROR, message="Can't make a local non-Tor HTTPx client. This error should not go off.") return ApiResponse(valid=False, error_type=ErrorType.DEVELOPER_ERROR, message="Can't make a local non-Tor HTTPx client. This error should not go off.")
@ -92,7 +93,8 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
method=method, method=method,
url=url, url=url,
observer=observer, observer=observer,
payload=payload payload=payload,
billing_code=billing_code
) )
######################################################## ########################################################
@ -143,7 +145,7 @@ def _make_client(connection_type: str, observer) -> httpx.Client | ApiResponse:
return False return False
def bootstrap_and_try_again(method: str, url: str, observer: ConnectionObserver, payload: dict = None): def bootstrap_and_try_again(method: str, url: str, observer: ConnectionObserver, payload: dict = None, billing_code: str = None):
""" """
Rank: Rank:
Coordinator Coordinator

View file

@ -25,7 +25,8 @@ def make_request(
method=method, method=method,
url=url, url=url,
client=client, client=client,
payload=payload payload=payload,
billing_code=billing_code
) )
if initial_result.valid: if initial_result.valid:
@ -59,7 +60,8 @@ def make_request(
method=method, method=method,
url=url, url=url,
client=client, client=client,
payload=payload payload=payload,
billing_code=billing_code
) )
return second_result return second_result

View file

@ -277,58 +277,3 @@ def establish_system_connection(
terminate_tor_connection() terminate_tor_connection()
time.sleep(1.0) time.sleep(1.0)
# legacy version:
# try:
# connection_result = __establish_system_connection(
# profile=profile,
# firewall_setting=firewall_setting,
# dns_setting=dns_setting,
# connection_observer=connection_observer
# )
# evaluate_connection_result(connection_result)
# except ConnectionError:
# # ================= RETRY ON FAILURE =================
# try:
# terminate_system_connection(firewall_setting, dns_setting)
# except ConnectionTerminationError:
# pass
# raise ConnectionError('The connection could not be established.')
# except CalledProcessError:
# try:
# terminate_system_connection(firewall_setting, dns_setting)
# except ConnectionTerminationError:
# pass
# # trying again..
# try:
# connection_result = __establish_system_connection(
# profile=profile,
# firewall_setting=firewall_setting,
# dns_setting=dns_setting,
# connection_observer=connection_observer
# )
# evaluate_connection_result(connection_result)
# except (ConnectionError, CalledProcessError):
# try:
# terminate_system_connection(firewall_setting, dns_setting)
# except ConnectionTerminationError:
# pass
# raise ConnectionError('The connection could not be established.')
# def evaluate_connection_result(connection_result: Result):
# if not connection_result.valid:
# logger.error(f"[SYSTEMWIDE WG] Critical issue, could not establish a connection: {connection_result.message}")
# try:
# terminate_system_connection(firewall_setting, True)
# except ConnectionTerminationError:
# pass