update: updated policy review page
This commit is contained in:
parent
796eb5ae76
commit
19cdcc4a2f
1 changed files with 180 additions and 15 deletions
195
gui/__main__.py
195
gui/__main__.py
|
|
@ -24,7 +24,7 @@ from core.controllers.LocationController import LocationController
|
||||||
from core.controllers.ProfileController import ProfileController
|
from core.controllers.ProfileController import ProfileController
|
||||||
from core.controllers.SubscriptionController import SubscriptionController
|
from core.controllers.SubscriptionController import SubscriptionController
|
||||||
from core.controllers.SubscriptionPlanController import SubscriptionPlanController
|
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.SessionConnection import SessionConnection
|
||||||
from core.models.session.SessionProfile import SessionProfile
|
from core.models.session.SessionProfile import SessionProfile
|
||||||
from core.models.system.SystemConnection import SystemConnection
|
from core.models.system.SystemConnection import SystemConnection
|
||||||
|
|
@ -912,6 +912,8 @@ class CustomWindow(QMainWindow):
|
||||||
InstallSystemPackage(self.page_stack, self),
|
InstallSystemPackage(self.page_stack, self),
|
||||||
WelcomePage(self.page_stack, self),
|
WelcomePage(self.page_stack, self),
|
||||||
SystemwidePromptPage(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),
|
PaymentDetailsPage(self.page_stack, self),
|
||||||
DurationSelectionPage(self.page_stack, self),
|
DurationSelectionPage(self.page_stack, self),
|
||||||
CurrencySelectionPage(self.page_stack, self),
|
CurrencySelectionPage(self.page_stack, self),
|
||||||
|
|
@ -931,6 +933,8 @@ class CustomWindow(QMainWindow):
|
||||||
|
|
||||||
if self.check_first_launch():
|
if self.check_first_launch():
|
||||||
self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(WelcomePage)))
|
self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(WelcomePage)))
|
||||||
|
else:
|
||||||
|
self.check_suggestible_policies()
|
||||||
|
|
||||||
def read_data(self):
|
def read_data(self):
|
||||||
return self._data["Profile_1"]
|
return self._data["Profile_1"]
|
||||||
|
|
@ -974,6 +978,26 @@ class CustomWindow(QMainWindow):
|
||||||
else:
|
else:
|
||||||
return False
|
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):
|
def has_shown_fast_mode_prompt(self):
|
||||||
flag_file = os.path.join(self.gui_config_home, '.fast-mode-prompted')
|
flag_file = os.path.join(self.gui_config_home, '.fast-mode-prompted')
|
||||||
return os.path.exists(flag_file)
|
return os.path.exists(flag_file)
|
||||||
|
|
@ -6966,7 +6990,9 @@ class Settings(Page):
|
||||||
def load_systemwide_settings(self):
|
def load_systemwide_settings(self):
|
||||||
enabled = False
|
enabled = False
|
||||||
try:
|
try:
|
||||||
enabled = PrivilegePolicyController.is_instated()
|
privilege_policy = PolicyController.get('privilege')
|
||||||
|
if privilege_policy is not None:
|
||||||
|
enabled = PolicyController.is_instated(privilege_policy)
|
||||||
except Exception:
|
except Exception:
|
||||||
enabled = False
|
enabled = False
|
||||||
self.systemwide_toggle.setChecked(enabled)
|
self.systemwide_toggle.setChecked(enabled)
|
||||||
|
|
@ -6980,11 +7006,13 @@ class Settings(Page):
|
||||||
def save_systemwide_settings(self):
|
def save_systemwide_settings(self):
|
||||||
enable = self.systemwide_toggle.isChecked()
|
enable = self.systemwide_toggle.isChecked()
|
||||||
try:
|
try:
|
||||||
if enable:
|
privilege_policy = PolicyController.get('privilege')
|
||||||
PrivilegePolicyController.instate()
|
if privilege_policy is not None:
|
||||||
else:
|
if enable:
|
||||||
if PrivilegePolicyController.is_instated():
|
PolicyController.instate(privilege_policy)
|
||||||
PrivilegePolicyController.revoke()
|
else:
|
||||||
|
if PolicyController.is_instated(privilege_policy):
|
||||||
|
PolicyController.revoke(privilege_policy)
|
||||||
self.load_systemwide_settings()
|
self.load_systemwide_settings()
|
||||||
self.update_status.update_status("System-wide policy settings updated")
|
self.update_status.update_status("System-wide policy settings updated")
|
||||||
except CommandNotFoundError as e:
|
except CommandNotFoundError as e:
|
||||||
|
|
@ -7989,18 +8017,23 @@ class SystemwidePromptPage(Page):
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
self.title.setGeometry(20, 50, 760, 40)
|
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 = QLabel(self)
|
||||||
description.setGeometry(80, 100, 640, 80)
|
description.setGeometry(80, 100, 640, 120)
|
||||||
description.setWordWrap(True)
|
description.setWordWrap(True)
|
||||||
description.setStyleSheet("font-size: 14px; color: cyan;")
|
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 = 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_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))
|
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 = QPushButton("Yes, enable system-wide profiles", self)
|
||||||
yes_button.setGeometry(170, 200, 300, 50)
|
yes_button.setGeometry(170, 300, 300, 50)
|
||||||
yes_button.setStyleSheet("""
|
yes_button.setStyleSheet("""
|
||||||
QPushButton {
|
QPushButton {
|
||||||
background: #007AFF;
|
background: #007AFF;
|
||||||
|
|
@ -8016,7 +8049,7 @@ class SystemwidePromptPage(Page):
|
||||||
""")
|
""")
|
||||||
yes_button.clicked.connect(self.enable_systemwide)
|
yes_button.clicked.connect(self.enable_systemwide)
|
||||||
no_button = QPushButton("Not now", self)
|
no_button = QPushButton("Not now", self)
|
||||||
no_button.setGeometry(170, 270, 120, 40)
|
no_button.setGeometry(170, 370, 120, 40)
|
||||||
no_button.setStyleSheet("""
|
no_button.setStyleSheet("""
|
||||||
QPushButton {
|
QPushButton {
|
||||||
background: #007AFF;
|
background: #007AFF;
|
||||||
|
|
@ -8034,7 +8067,8 @@ class SystemwidePromptPage(Page):
|
||||||
self.refresh_status()
|
self.refresh_status()
|
||||||
|
|
||||||
def refresh_status(self):
|
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.setText("Current status: system-wide policy is enabled.")
|
||||||
self.status_label.setStyleSheet("font-size: 14px; color: #2ecc71;")
|
self.status_label.setStyleSheet("font-size: 14px; color: #2ecc71;")
|
||||||
else:
|
else:
|
||||||
|
|
@ -8042,8 +8076,11 @@ class SystemwidePromptPage(Page):
|
||||||
self.status_label.setStyleSheet("font-size: 14px; color: #e67e22;")
|
self.status_label.setStyleSheet("font-size: 14px; color: #e67e22;")
|
||||||
|
|
||||||
def enable_systemwide(self):
|
def enable_systemwide(self):
|
||||||
|
|
||||||
try:
|
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.update_status.mark_systemwide_prompt_shown()
|
||||||
self.refresh_status()
|
self.refresh_status()
|
||||||
self.update_status.update_status("System-wide policy enabled")
|
self.update_status.update_status("System-wide policy enabled")
|
||||||
|
|
@ -8066,6 +8103,134 @@ class SystemwidePromptPage(Page):
|
||||||
install_page = self.page_stack.findChild(InstallSystemPackage)
|
install_page = self.page_stack.findChild(InstallSystemPackage)
|
||||||
if install_page:
|
if install_page:
|
||||||
self.page_stack.setCurrentIndex(self.page_stack.indexOf(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):
|
class DurationSelectionPage(Page):
|
||||||
def __init__(self, page_stack, main_window=None, parent=None):
|
def __init__(self, page_stack, main_window=None, parent=None):
|
||||||
super().__init__("Select Duration", page_stack, main_window, parent)
|
super().__init__("Select Duration", page_stack, main_window, parent)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue