sp-hydra-veil-core/core/controllers/ProfileController.py

157 lines
6.3 KiB
Python

from core.services.profiles.ProfileRepository import ProfileRepository
# from core.services.subscriptions import subscriptions
from core.models.Result import Result, ResultError
from core.errors.logger import logger
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError
from core.models.BaseProfile import BaseProfile as Profile
from core.models.Subscription import Subscription
from core.models.session.SessionProfile import SessionProfile
from core.models.system.SystemProfile import SystemProfile
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
from core.observers.ConnectionObserver import ConnectionObserver
from core.observers.ProfileObserver import ProfileObserver
from core.services.WebServiceApiService import WebServiceApiService
from typing import Union, Optional
import base64
import re
import time
class ProfileController:
# Initialize the singleton repository
_repo = ProfileRepository()
@staticmethod
def get(id: int) -> Union[SessionProfile, SystemProfile, None]:
# Controller no longer talks to the Model; it talks to the Repo
return ProfileController._repo.get(id)
@staticmethod
def get_all():
return ProfileController._repo.get_all()
@staticmethod
def create(profile: Union[SessionProfile, SystemProfile], profile_observer: ProfileObserver = None):
# Call the helper with the 'created' event
ProfileController._save_and_sync(profile, 'created', profile_observer)
@staticmethod
def update(profile: Union[SessionProfile, SystemProfile], profile_observer: ProfileObserver = None):
# Call the helper with the 'updated' event
ProfileController._save_and_sync(profile, 'updated', profile_observer)
@staticmethod
def _save_and_sync(profile, event_type: str, observer: ProfileObserver = None):
"""Private helper to handle the actual persistence and cache synchronization."""
# 1. Persist to disk
profile.save()
# 2. update cache to prevent drift
ProfileController._repo.update_cache(profile)
# 3. Notify observer
if observer is not None:
observer.notify(event_type, profile)
@staticmethod
def delete(profile: Union[SessionProfile, SystemProfile], profile_observer: ProfileObserver = None):
"""Remove the profile from both disk and cache"""
# 1. Save to temp variable:
profile_id = profile.id
# 2. Permanently delete from disk
profile.delete()
# 3. update cache with the temp variable to prevent drift
ProfileController._repo.invalidate(profile_id=profile_id)
# @staticmethod
# def attach_subscription(profile: Union[SessionProfile, SystemProfile], subscription: Subscription):
# profile.subscription = subscription
# profile.save()
# @staticmethod
# def activate_subscription(profile: Union[SessionProfile, SystemProfile], connection_observer: Optional[ConnectionObserver] = None):
# from core.controllers.ConnectionController import ConnectionController
# if profile.has_subscription():
# subscription = subscriptions.get_subscription(
# billing_code=profile.subscription.billing_code,
# connection_observer=connection_observer
# )
# if subscription is not None:
# profile.subscription = subscription
# profile.save()
# else:
# raise InvalidSubscriptionError()
# else:
# raise MissingSubscriptionError()
# @staticmethod
# def get_invoice(profile: Union[SessionProfile, SystemProfile]):
# if profile.has_subscription():
# # return subscriptions.get_invoice(billing_code=profile.subscription.billing_code)
# return WebServiceApiService.get_invoice(profile.subscription.billing_code)
# else:
# return None
@staticmethod
def attach_proxy_configuration(profile: Union[SessionProfile, SystemProfile]):
if profile.is_session_profile() and profile.has_subscription():
proxy_configuration = WebServiceApiService.get_proxy_configuration(profile.subscription.billing_code)
if proxy_configuration is not None:
profile.attach_proxy_configuration(proxy_configuration)
@staticmethod
def get_proxy_configuration(profile: Union[SessionProfile, SystemProfile]):
if profile.is_session_profile():
return profile.get_proxy_configuration()
else:
return None
@staticmethod
def has_proxy_configuration(profile: Union[SessionProfile, SystemProfile]):
profile.has_proxy_configuration()
@staticmethod
def get_wireguard_configuration_path(profile: Union[SessionProfile, SystemProfile]):
return profile.get_wireguard_configuration_path()
@staticmethod
def has_wireguard_configuration(profile: Union[SessionProfile, SystemProfile]):
return profile.has_wireguard_configuration()
# from core.observers.TicketObserver import TicketObserver
# from core.services.assassin.ticket_respawn import respawn_profile
# from core.services.assassin import assassin_tools
# from core.errors.exceptions import FirewallError
# from core.services.networking.systemwide.systemwide_wireguard import terminate_system_connection
# from core.services.networking.general_connection_tools.testing_evaluating import system_uses_wireguard_interface
# from core.services.networking.general_connection_tools.connection_enable import establish_connection
# from core.services.networking.systemwide.systemwide_utils import get_firewall_setting, get_dns_setting
# from core.services.networking.systemwide.encrypted_proxy.singbox_runner import end_singbox
# from core.services.networking.systemwide import killswitch
#, ConnectionTerminationError, ProfileActivationError, ProfileDeactivationError, MissingLocationError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
# from core.controllers.ApplicationController import ApplicationController
# from core.controllers.ApplicationVersionController import ApplicationVersionController
# from core.controllers.SessionStateController import SessionStateController
# from core.controllers.SystemStateController import SystemStateController