Sudo config management. Properly delete the config for protocol changes, and install it using the generic commands module
This commit is contained in:
parent
5923cc8a7f
commit
bdfb933548
5 changed files with 52 additions and 18 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
# Major Change Log:
|
# Major Change Log:
|
||||||
|
|
||||||
|
# Vless Introduced
|
||||||
|
### Aug 20, 2026
|
||||||
|
Vless is now working. Config Parsing and setup is stable, and increased the wait time for connection testing. But this is a temporary solution. The real answer is not a static time check, but a dynamic result reading for when to test. Which then has it's own timeout time
|
||||||
|
<br/>
|
||||||
|
|
||||||
# Assassin Introduced
|
# Assassin Introduced
|
||||||
### Aug 18, 2026
|
### Aug 18, 2026
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
# utils
|
# utils
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
from core.models.Result import Result, ResultError
|
from core.models.Result import Result, ResultError
|
||||||
|
from core.services.networking.systemwide.general_tools.manage_sudo_configs import remove_sudo_config
|
||||||
|
|
||||||
# JSON Models
|
# JSON Models
|
||||||
from core.models.BaseProfile import BaseProfile as Profile
|
from core.models.BaseProfile import BaseProfile as Profile
|
||||||
|
|
@ -88,9 +89,21 @@ def update_profile(
|
||||||
# profile.application_version.version_number = browser_version
|
# profile.application_version.version_number = browser_version
|
||||||
|
|
||||||
elif key == 'protocol':
|
elif key == 'protocol':
|
||||||
|
# ============= SAME VALUE =============
|
||||||
|
if profile.connection.code == new_value:
|
||||||
|
error_msg = f"This is NOT changing the protocol, it already was {new_value}"
|
||||||
|
return Result(valid=False, message=error_msg, error_type=ResultError.INVALID_INPUT)
|
||||||
|
|
||||||
# ============= SYSTEMWIDE =============
|
# ============= SYSTEMWIDE =============
|
||||||
if profile.connection == 'system-wide':
|
if profile.connection == 'system-wide':
|
||||||
if new_value in SYSTEMWIDE_CHOICES:
|
if new_value in SYSTEMWIDE_CHOICES:
|
||||||
|
# REMOVE PAST CONFIG:
|
||||||
|
removed = remove_sudo_config(profile)
|
||||||
|
if not removed.valid:
|
||||||
|
error_msg = "You must give permission to delete the previous protocol's config file."
|
||||||
|
return Result(valid=False, message=error_msg, error_type=ResultError.PERMISSION)
|
||||||
|
|
||||||
|
# UPDATE PROFILE
|
||||||
profile.connection.code = new_value
|
profile.connection.code = new_value
|
||||||
final_data = "edit_session"
|
final_data = "edit_session"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ from core.services.networking.httpx import connect
|
||||||
|
|
||||||
from core.services.networking.systemwide.encrypted_proxy.hysteria_config import build_hysteria_config
|
from core.services.networking.systemwide.encrypted_proxy.hysteria_config import build_hysteria_config
|
||||||
from core.services.networking.systemwide.encrypted_proxy.vless_config import build_vless_config, parse_vless_link
|
from core.services.networking.systemwide.encrypted_proxy.vless_config import build_vless_config, parse_vless_link
|
||||||
|
from core.utils.basic_operations.write_or_read_from_json import write_json_to_file
|
||||||
|
from core.utils.run_commands import run_generic_command
|
||||||
|
|
||||||
# Models
|
# Models
|
||||||
from core.models.pydantic_models.HysteriaData import HysteriaData
|
from core.models.pydantic_models.HysteriaData import HysteriaData
|
||||||
|
|
@ -177,28 +179,25 @@ def attach_config_to_sudo_folder(
|
||||||
logger.info("About to save to backup config path")
|
logger.info("About to save to backup config path")
|
||||||
backup_path = f'{backup_folder}/backup.conf.bak'
|
backup_path = f'{backup_folder}/backup.conf.bak'
|
||||||
|
|
||||||
try:
|
saved_backup = write_json_to_file(data=config_data, filepath=backup_path)
|
||||||
with open(backup_path, "w") as configuration_file:
|
if not saved_backup:
|
||||||
json.dump(config_data, configuration_file, indent=4)
|
logger.error("Backup Save was not successfull")
|
||||||
logger.info("Saved to backup config path!")
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
configuration_is_attached = False
|
configuration_is_attached = False
|
||||||
failed_attempt_count = 0
|
failed_attempt_count = 0
|
||||||
|
|
||||||
while not configuration_is_attached and failed_attempt_count < 3:
|
while not configuration_is_attached and failed_attempt_count < 3:
|
||||||
logger.info(f"Trying attempt {failed_attempt_count} to write to the sudo folder..")
|
human_readable_goal = f"Attempt {failed_attempt_count} to write to the sudo folder"
|
||||||
try:
|
logger.info(human_readable_goal)
|
||||||
process = subprocess.Popen(('pkexec', 'install', '-D', backup_path, sudo_filepath, '-o', 'root', '-m', '744'))
|
command = ['pkexec', 'install', '-D', backup_path, sudo_filepath, '-o', 'root', '-m', '744']
|
||||||
configuration_is_attached = not bool(os.waitpid(process.pid, 0)[1] >> 8)
|
result_object = run_generic_command(command, human_readable_goal, timeout=5)
|
||||||
except Exception as e:
|
if result_object.valid:
|
||||||
logger.error(e)
|
configuration_is_attached = True
|
||||||
|
else:
|
||||||
if not configuration_is_attached:
|
|
||||||
failed_attempt_count += 1
|
failed_attempt_count += 1
|
||||||
|
|
||||||
|
|
||||||
if not configuration_is_attached:
|
if not configuration_is_attached:
|
||||||
raise ProfileModificationError('The configuration could not be attached.')
|
raise ProfileModificationError('The configuration could not be attached.')
|
||||||
return False # redundant
|
return False # redundant
|
||||||
|
|
@ -230,9 +229,6 @@ def post_operator_proxy(billing_code: str, protocol: str, connection_observer: C
|
||||||
# convert the error message here
|
# convert the error message here
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# no longer needed:
|
|
||||||
# 'location_id': location_id,
|
|
||||||
# 'subscription_plan_id': subscription_plan_id,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
from core.utils.run_commands import run_generic_command
|
||||||
|
from core.models.Result import Result
|
||||||
|
from core.models.system.SystemProfile import SystemProfile
|
||||||
|
|
||||||
|
def get_target_filename(profile: SystemProfile) -> str:
|
||||||
|
if profile.connection.code == "wireguard":
|
||||||
|
return "wg.conf"
|
||||||
|
else:
|
||||||
|
return "proxy.json"
|
||||||
|
|
||||||
|
def remove_sudo_config(profile: SystemProfile) -> Result:
|
||||||
|
# FILE PATH:
|
||||||
|
base_folder = profile.get_system_config_path()
|
||||||
|
file_name = get_target_filename(profile)
|
||||||
|
sudo_filepath = f"{base_folder}/{file_name}"
|
||||||
|
|
||||||
|
# REMOVE:
|
||||||
|
command = ['pkexec', 'rm', '-f', sudo_filepath]
|
||||||
|
human_readable_goal = "Removing file from sudo folder"
|
||||||
|
return run_generic_command(command, human_readable_goal, timeout=35)
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ def activate_subscription(
|
||||||
|
|
||||||
# Already activated—nothing to do
|
# Already activated—nothing to do
|
||||||
if profile.subscription.has_been_activated():
|
if profile.subscription.has_been_activated():
|
||||||
logger.info("sub has already been activated, returnining true")
|
logger.info("Sub has already been activated")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue