update: updated policy review page

This commit is contained in:
Your Name 2025-11-30 12:14:02 +01:00
parent 796eb5ae76
commit 19cdcc4a2f

View file

@ -24,7 +24,7 @@ from core.controllers.LocationController import LocationController
from core.controllers.ProfileController import ProfileController
from core.controllers.SubscriptionController import SubscriptionController
from core.controllers.SubscriptionPlanController import SubscriptionPlanController
from core.controllers.PrivilegePolicyController import PrivilegePolicyController
from core.controllers.PolicyController import PolicyController
from core.models.session.SessionConnection import SessionConnection
from core.models.session.SessionProfile import SessionProfile
from core.models.system.SystemConnection import SystemConnection
@ -912,6 +912,8 @@ class CustomWindow(QMainWindow):
InstallSystemPackage(self.page_stack, self),
WelcomePage(self.page_stack, self),
SystemwidePromptPage(self.page_stack, self),
PolicySuggestionPage(self.page_stack, self, None, 'capability'),
PolicySuggestionPage(self.page_stack, self, None, 'privilege'),
PaymentDetailsPage(self.page_stack, self),
DurationSelectionPage(self.page_stack, self),
CurrencySelectionPage(self.page_stack, self),
@ -931,6 +933,8 @@ class CustomWindow(QMainWindow):
if self.check_first_launch():
self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(WelcomePage)))
else:
self.check_suggestible_policies()
def read_data(self):
return self._data["Profile_1"]
@ -974,6 +978,26 @@ class CustomWindow(QMainWindow):
else:
return False
def check_suggestible_policies(self):
try:
capability_policy = PolicyController.get('capability')
if capability_policy is not None:
if PolicyController.is_suggestible(capability_policy) and not PolicyController.is_instated(capability_policy):
capability_page = None
for i in range(self.page_stack.count()):
page = self.page_stack.widget(i)
if isinstance(page, PolicySuggestionPage) and page.policy_type == 'capability':
capability_page = page
break
if capability_page:
self.page_stack.setCurrentIndex(self.page_stack.indexOf(capability_page))
return
except Exception as e:
print(f"Error checking suggestible policies: {e}")
def has_shown_fast_mode_prompt(self):
flag_file = os.path.join(self.gui_config_home, '.fast-mode-prompted')
return os.path.exists(flag_file)
@ -6966,7 +6990,9 @@ class Settings(Page):
def load_systemwide_settings(self):
enabled = False
try:
enabled = PrivilegePolicyController.is_instated()
privilege_policy = PolicyController.get('privilege')
if privilege_policy is not None:
enabled = PolicyController.is_instated(privilege_policy)
except Exception:
enabled = False
self.systemwide_toggle.setChecked(enabled)
@ -6980,11 +7006,13 @@ class Settings(Page):
def save_systemwide_settings(self):
enable = self.systemwide_toggle.isChecked()
try:
if enable:
PrivilegePolicyController.instate()
else:
if PrivilegePolicyController.is_instated():
PrivilegePolicyController.revoke()
privilege_policy = PolicyController.get('privilege')
if privilege_policy is not None:
if enable:
PolicyController.instate(privilege_policy)
else:
if PolicyController.is_instated(privilege_policy):
PolicyController.revoke(privilege_policy)
self.load_systemwide_settings()
self.update_status.update_status("System-wide policy settings updated")
except CommandNotFoundError as e:
@ -7989,18 +8017,23 @@ class SystemwidePromptPage(Page):
def setup_ui(self):
self.title.setGeometry(20, 50, 760, 40)
self.title.setText("Enable system-wide WireGuard profiles")
self.title.setText("Enable \"no sudo\" systemwide")
description = QLabel(self)
description.setGeometry(80, 100, 640, 80)
description.setGeometry(80, 100, 640, 120)
description.setWordWrap(True)
description.setStyleSheet("font-size: 14px; color: cyan;")
description.setText("You can enable system-wide WireGuard profiles so they can be started without entering your sudo password each time. This uses a secure sudo policy tailored to your user.")
description.setText("If you're using Systemwide profiles, you may wish to enable them without having to enter the sudo password each time for convenience. This requires the sudo password to setup profiles and disable them (for security), but not to turn it on each time. You can choose to set this up now or later in the options menu.")
disclaimer = QLabel(self)
disclaimer.setGeometry(80, 230, 640, 60)
disclaimer.setWordWrap(True)
disclaimer.setStyleSheet("font-size: 12px; color: #808080;")
disclaimer.setText("As we outline in our documentation, HydraVeil uses a much more secure method than other VPNs, because it does NOT require a dameon to run 24/7 with elevated privileges. However, keep in mind that ANY reduction in password authentication from ANY VPN is loosening security for convenience.")
icon_label = QLabel(self)
icon_label.setGeometry(80, 200, 64, 64)
icon_label.setGeometry(80, 300, 64, 64)
icon_pix = QPixmap(os.path.join(self.btn_path, "wireguard_system_wide.png"))
icon_label.setPixmap(icon_pix.scaled(64, 64, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
yes_button = QPushButton("Yes, enable system-wide profiles", self)
yes_button.setGeometry(170, 200, 300, 50)
yes_button.setGeometry(170, 300, 300, 50)
yes_button.setStyleSheet("""
QPushButton {
background: #007AFF;
@ -8016,7 +8049,7 @@ class SystemwidePromptPage(Page):
""")
yes_button.clicked.connect(self.enable_systemwide)
no_button = QPushButton("Not now", self)
no_button.setGeometry(170, 270, 120, 40)
no_button.setGeometry(170, 370, 120, 40)
no_button.setStyleSheet("""
QPushButton {
background: #007AFF;
@ -8034,7 +8067,8 @@ class SystemwidePromptPage(Page):
self.refresh_status()
def refresh_status(self):
if PrivilegePolicyController.is_instated():
privilege_policy = PolicyController.get('privilege')
if privilege_policy is not None and PolicyController.is_instated(privilege_policy):
self.status_label.setText("Current status: system-wide policy is enabled.")
self.status_label.setStyleSheet("font-size: 14px; color: #2ecc71;")
else:
@ -8042,8 +8076,11 @@ class SystemwidePromptPage(Page):
self.status_label.setStyleSheet("font-size: 14px; color: #e67e22;")
def enable_systemwide(self):
try:
PrivilegePolicyController.instate()
privilege_policy = PolicyController.get('privilege')
if privilege_policy is not None:
PolicyController.instate(privilege_policy)
self.update_status.mark_systemwide_prompt_shown()
self.refresh_status()
self.update_status.update_status("System-wide policy enabled")
@ -8066,6 +8103,134 @@ class SystemwidePromptPage(Page):
install_page = self.page_stack.findChild(InstallSystemPackage)
if install_page:
self.page_stack.setCurrentIndex(self.page_stack.indexOf(install_page))
class PolicySuggestionPage(Page):
def __init__(self, page_stack, main_window=None, parent=None, policy_type='capability'):
super().__init__("PolicySuggestion", page_stack, main_window, parent)
self.btn_path = main_window.btn_path
self.update_status = main_window
self.policy_type = policy_type
self.policy = PolicyController.get(policy_type)
self.button_back.setVisible(False)
self.button_next.setVisible(False)
self.button_go.setVisible(False)
self.status_label = QLabel(self)
self.status_label.setGeometry(80, 430, 640, 40)
self.status_label.setStyleSheet("font-size: 14px; color: cyan;")
self.setup_ui()
def setup_ui(self):
policy_name = "Capability" if self.policy_type == 'capability' else "Privilege"
self.title.setGeometry(20, 50, 760, 40)
self.title.setText(f"Policy Suggestion: {policy_name} Policy")
description = QLabel(self)
description.setGeometry(80, 100, 640, 60)
description.setWordWrap(True)
description.setStyleSheet("font-size: 14px; color: cyan;")
description.setText(f"A {policy_name.lower()} policy is available and can be instated to improve functionality. Review the policy details below before proceeding.")
preview_label = QLabel(self)
preview_label.setGeometry(80, 170, 640, 30)
preview_label.setStyleSheet("font-size: 13px; color: white; font-weight: bold;")
preview_label.setText("Policy Preview:")
preview_text = QTextEdit(self)
preview_text.setGeometry(80, 200, 640, 150)
preview_text.setReadOnly(True)
preview_text.setStyleSheet("""
QTextEdit {
background-color: #1a1a1a;
color: #00ffff;
border: 1px solid #333;
border-radius: 4px;
font-family: monospace;
font-size: 11px;
padding: 5px;
}
""")
try:
preview_content = PolicyController.preview(self.policy)
preview_text.setText(preview_content)
except Exception as e:
preview_text.setText(f"Error loading preview: {str(e)}")
yes_button = QPushButton(f"Instate {policy_name} Policy", self)
yes_button.setGeometry(170, 370, 250, 50)
yes_button.setStyleSheet("""
QPushButton {
background: #007AFF;
color: white;
border: none;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
}
QPushButton:hover {
background: #0056CC;
}
""")
yes_button.clicked.connect(self.instate_policy)
no_button = QPushButton("Skip", self)
no_button.setGeometry(440, 370, 120, 50)
no_button.setStyleSheet("""
QPushButton {
background: #666;
color: white;
border: none;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
}
QPushButton:hover {
background: #555;
}
""")
no_button.clicked.connect(self.skip_policy)
self.refresh_status()
def refresh_status(self):
try:
if PolicyController.is_instated(self.policy):
self.status_label.setText(f"Current status: {self.policy_type} policy is instated.")
self.status_label.setStyleSheet("font-size: 14px; color: #2ecc71;")
else:
self.status_label.setText(f"Current status: {self.policy_type} policy is not instated.")
self.status_label.setStyleSheet("font-size: 14px; color: #e67e22;")
except Exception:
self.status_label.setText("Unable to determine policy status.")
self.status_label.setStyleSheet("font-size: 14px; color: #e67e22;")
def instate_policy(self):
try:
PolicyController.instate(self.policy)
self.refresh_status()
policy_name = "Capability" if self.policy_type == 'capability' else "Privilege"
self.update_status.update_status(f"{policy_name} policy instated")
menu_page = self.page_stack.findChild(MenuPage)
if menu_page:
self.page_stack.setCurrentIndex(self.page_stack.indexOf(menu_page))
else:
self.page_stack.setCurrentIndex(0)
except CommandNotFoundError as e:
self.status_label.setText(str(e))
self.status_label.setStyleSheet("font-size: 14px; color: red;")
except (PolicyAssignmentError, PolicyInstatementError) as e:
self.status_label.setText(str(e))
self.status_label.setStyleSheet("font-size: 14px; color: red;")
except Exception as e:
self.status_label.setText(f"Failed to instate policy: {str(e)}")
self.status_label.setStyleSheet("font-size: 14px; color: red;")
def skip_policy(self):
menu_page = self.page_stack.findChild(MenuPage)
if menu_page:
self.page_stack.setCurrentIndex(self.page_stack.indexOf(menu_page))
else:
self.page_stack.setCurrentIndex(0)
class DurationSelectionPage(Page):
def __init__(self, page_stack, main_window=None, parent=None):
super().__init__("Select Duration", page_stack, main_window, parent)