From 703fe57c12d8913f3e6b40e7ce71583bf9d20325 Mon Sep 17 00:00:00 2001 From: SimplifiedPrivacy Date: Sat, 18 Jul 2026 16:44:54 -0400 Subject: [PATCH] Introduce Base profile types on load, which gradually will switch over on save/edits. Transition Connections to using Enum instead of raw strings. --- core/controllers/ConnectionController.py | 5 ++++- core/models/BaseConnection.py | 6 ++++-- core/models/BaseProfile.py | 26 ++++++++++++++++-------- core/models/session/SessionConnection.py | 26 +++++++++++++++++------- core/models/system/SystemConnection.py | 26 +++++++++++++++++------- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/core/controllers/ConnectionController.py b/core/controllers/ConnectionController.py index 5be14db..df63ced 100644 --- a/core/controllers/ConnectionController.py +++ b/core/controllers/ConnectionController.py @@ -8,6 +8,7 @@ from core.controllers.ConfigurationController import ConfigurationController from core.controllers.ProfileController import ProfileController from core.controllers.SessionStateController import SessionStateController from core.controllers.SystemStateController import SystemStateController +from core.models.BaseProfile import ProfileType from core.models.session.SessionProfile import SessionProfile from core.models.system.SystemProfile import SystemProfile from core.models.system.SystemState import SystemState @@ -26,6 +27,7 @@ import subprocess import sys import tempfile import time +from enum import Enum class ConnectionController: @@ -58,6 +60,7 @@ class ConnectionController: # needs_proxy_configuration comes from the child connection models # for the system it returns false blindly. for the session is checks if the connection type is masked. + # if connection.masked and not profile.has_proxy_configuration(): if connection.needs_proxy_configuration() and not profile.has_proxy_configuration(): if profile.has_subscription(): @@ -514,4 +517,4 @@ class ConnectionController: if profile.subscription.has_been_activated(): return True - return False + return False \ No newline at end of file diff --git a/core/models/BaseConnection.py b/core/models/BaseConnection.py index edc7021..36df078 100644 --- a/core/models/BaseConnection.py +++ b/core/models/BaseConnection.py @@ -1,19 +1,21 @@ from dataclasses import dataclass from dataclasses_json import dataclass_json - @dataclass_json @dataclass class BaseConnection: code: str - # called by: connection controller for basic type checks on wireguard code + # Called by: ConnectionController + # it uses it for basic type checks on wireguard code def needs_wireguard_configuration(self): return self.code == 'wireguard' + # Called By SubscriptionPlan def is_session_connection(self): return type(self).__name__ == 'SessionConnection' + # Not called. Dead code def is_system_connection(self): return type(self).__name__ == 'SystemConnection' diff --git a/core/models/BaseProfile.py b/core/models/BaseProfile.py index 5dddec0..e38e13b 100644 --- a/core/models/BaseProfile.py +++ b/core/models/BaseProfile.py @@ -28,6 +28,7 @@ import re import shutil import tempfile from sqlalchemy.orm import Session +from enum import Enum @safe_db_operation def execute_location_sql(country_code: str, city_code: str, session: Session) -> DatabaseOperation: @@ -51,6 +52,9 @@ def get_profile_location_data(country_code: str, city_code: str) -> Location: return None +class ProfileType(str, Enum): + SESSION = "session" + SYSTEM = "system" @dataclass_json @dataclass @@ -61,6 +65,7 @@ class BaseProfile(ABC): name: str subscription: Optional[Subscription] location: Optional[Location] = field(metadata=config(exclude=Exclude.ALWAYS)) # SQLAlchemy object + type: ProfileType # legacy version included it to be serialized, but now it's an SQLAlchemy object. # location: Optional[Location] @@ -237,16 +242,9 @@ class BaseProfile(ABC): # this needs error handling if there's no location or malconformed config. - # legacy phased out since SQLAlchemy handles the time_zone. - - # if location is not None: - - # if profile['location'].get('time_zone') is not None: - # location.time_zone = profile['location']['time_zone'] - - # profile['location'] = location - + # =========== SESSION =========== if 'application_version' in profile: + profile['type'] = ProfileType.SESSION if profile['application_version'] is not None: application_version = ApplicationVersion.find(profile['application_version']['application_code'] or None, profile['application_version']['version_number'] or None) @@ -258,7 +256,10 @@ class BaseProfile(ABC): # noinspection PyUnresolvedReferences profile = SessionProfile.from_dict(profile) + + # =========== SYSTEM =========== else: + profile['type'] = ProfileType.SYSTEM from core.models.system.SystemProfile import SystemProfile # noinspection PyUnresolvedReferences @@ -299,3 +300,10 @@ class BaseProfile(ABC): @staticmethod def __get_data_path(id: int): return f'{Constants.HV_PROFILE_DATA_HOME}/{str(id)}' + + +# legacy phased out since SQLAlchemy handles the time_zone. +# if location is not None: +# if profile['location'].get('time_zone') is not None: +# location.time_zone = profile['location']['time_zone'] +# profile['location'] = location diff --git a/core/models/session/SessionConnection.py b/core/models/session/SessionConnection.py index d1f7df7..c9626e3 100644 --- a/core/models/session/SessionConnection.py +++ b/core/models/session/SessionConnection.py @@ -1,20 +1,32 @@ from core.models.BaseConnection import BaseConnection from dataclasses import dataclass +from enum import Enum +class SessionConnectionTypes(str, Enum): + WIREGUARD = "wireguard" + TOR = "tor" @dataclass class SessionConnection(BaseConnection): - masked: bool = False + code: SessionConnectionTypes + masked: bool - def __post_init__(self): - - if self.code not in ('system', 'tor', 'wireguard'): - raise ValueError('Invalid connection code.') - - # called by connection controller + # Called by: ConnectionController # doesn't even make sense, it's checking if the Session is code system. this will always be false. def is_unprotected(self): return self.code == 'system' and self.masked is False + # Called by: SessionProfile.determine_timezone def needs_proxy_configuration(self): return self.masked is True + + +# legacy: +# @dataclass +# class SessionConnection(BaseConnection): +# masked: bool = False + +# def __post_init__(self): + +# if self.code not in ('system', 'tor', 'wireguard'): +# raise ValueError('Invalid connection code.') diff --git a/core/models/system/SystemConnection.py b/core/models/system/SystemConnection.py index 732441a..cc9371e 100644 --- a/core/models/system/SystemConnection.py +++ b/core/models/system/SystemConnection.py @@ -1,16 +1,28 @@ from core.models.BaseConnection import BaseConnection from dataclasses import dataclass +from enum import Enum +from typing import Literal +class SystemConnectionTypes(str, Enum): + WIREGUARD = "wireguard" + HYSTERIA2 = "hysteria2" + VLESS = "vless" @dataclass -class SystemConnection (BaseConnection): - - - def __post_init__(self): - - if self.code not in ('vless', 'hysteria2', 'wireguard'): - raise ValueError('Invalid connection code.') +class SystemConnection(BaseConnection): + code: SystemConnectionTypes + masked: Literal[False] = False @staticmethod def needs_proxy_configuration(): return False + +# legacy: +# @dataclass +# class SystemConnection (BaseConnection): + + +# def __post_init__(self): + +# if self.code not in ('vless', 'hysteria2', 'wireguard'): +# raise ValueError('Invalid connection code.')