Files
elmprodvpn/selective-vpn-gui/main_window/runtime_auth_mixin.py

210 lines
7.2 KiB
Python

from __future__ import annotations
import subprocess
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QApplication, QMessageBox
class RuntimeAuthMixin:
def on_auth_button(self) -> None:
def work():
view = self.ctrl.get_login_view()
if view.logged_in:
self.on_logout()
else:
# при логине всегда переходим на вкладку AdGuardVPN и
# показываем страницу логина
self.tabs.setCurrentWidget(self.tab_vpn)
self._show_vpn_page("login")
self.on_start_login()
self._safe(work, title="Auth error")
def on_login_banner_clicked(self) -> None:
def work():
txt = self.ctrl.login_banner_cli_text()
QMessageBox.information(self, "AdGuard VPN", txt)
self._safe(work, title="Login banner error")
# ---------------- LOGIN FLOW ACTIONS ----------------
def on_start_login(self) -> None:
def work():
self.ctrl.log_gui("Top Login clicked")
self._show_vpn_page("login")
self._login_flow_reset_ui()
start = self.ctrl.login_flow_start()
self._login_cursor = int(start.cursor)
self.lbl_login_flow_status.setText(
f"Status: {start.status_text or ''}"
)
self.lbl_login_flow_email.setText(
f"User: {start.email}" if start.email else ""
)
self.edit_login_url.setText(start.url or "")
self._login_flow_set_buttons(
can_open=start.can_open,
can_check=start.can_check,
can_cancel=start.can_cancel,
)
if start.lines:
cleaned = self._clean_ui_lines(start.lines)
if cleaned:
self._append_text(self.txt_login_flow, cleaned + "\n")
if not start.alive:
self._login_flow_autopoll_stop()
self._login_flow_set_buttons(
can_open=False, can_check=False, can_cancel=False
)
self.btn_login_stop.setEnabled(False)
QTimer.singleShot(250, self.refresh_login_banner)
return
self._login_flow_autopoll_start()
self._safe(work, title="Login start error")
def _login_flow_reset_ui(self) -> None:
self._login_cursor = 0
self._login_url_opened = False
self.edit_login_url.setText("")
self.lbl_login_flow_status.setText("Status: —")
self.lbl_login_flow_email.setText("")
self._set_text(self.txt_login_flow, "")
def _login_flow_set_buttons(
self,
*,
can_open: bool,
can_check: bool,
can_cancel: bool,
) -> None:
self.btn_login_open.setEnabled(bool(can_open))
self.btn_login_copy.setEnabled(bool(self.edit_login_url.text().strip()))
self.btn_login_check.setEnabled(bool(can_check))
self.btn_login_close.setEnabled(bool(can_cancel))
self.btn_login_stop.setEnabled(True)
def _login_flow_autopoll_start(self) -> None:
self._login_flow_active = True
if not self.login_poll_timer.isActive():
self.login_poll_timer.start()
def _login_flow_autopoll_stop(self) -> None:
self._login_flow_active = False
if self.login_poll_timer.isActive():
self.login_poll_timer.stop()
def _login_poll_tick(self) -> None:
if not self._login_flow_active:
return
def work():
view = self.ctrl.login_flow_poll(self._login_cursor)
self._login_cursor = int(view.cursor)
self.lbl_login_flow_status.setText(
f"Status: {view.status_text or ''}"
)
self.lbl_login_flow_email.setText(
f"User: {view.email}" if view.email else ""
)
if view.url:
self.edit_login_url.setText(view.url)
self._login_flow_set_buttons(
can_open=view.can_open,
can_check=view.can_check,
can_cancel=view.can_cancel,
)
cleaned = self._clean_ui_lines(view.lines)
if cleaned:
self._append_text(self.txt_login_flow, cleaned + "\n")
if (not self._login_url_opened) and view.url:
self._login_url_opened = True
try:
subprocess.Popen(["xdg-open", view.url])
except Exception:
pass
phase = (view.phase or "").strip().lower()
if (not view.alive) or phase in (
"success",
"failed",
"cancelled",
"already_logged",
):
self._login_flow_autopoll_stop()
self._login_flow_set_buttons(
can_open=False, can_check=False, can_cancel=False
)
self.btn_login_stop.setEnabled(False)
QTimer.singleShot(250, self.refresh_login_banner)
self._safe(work, title="Login flow error")
def on_login_copy(self) -> None:
def work():
u = self.edit_login_url.text().strip()
if u:
QApplication.clipboard().setText(u)
self.ctrl.log_gui("Login flow: copy-url")
self._safe(work, title="Login copy error")
def on_login_open(self) -> None:
def work():
u = self.edit_login_url.text().strip()
if u:
try:
subprocess.Popen(["xdg-open", u])
except Exception:
pass
self.ctrl.log_gui("Login flow: open")
self._safe(work, title="Login open error")
def on_login_check(self) -> None:
def work():
# если ещё ничего не запущено — считаем это стартом логина
if (
not self._login_flow_active
and self._login_cursor == 0
and not self.edit_login_url.text().strip()
and not self.txt_login_flow.toPlainText().strip()
):
self.on_start_login()
return
self.ctrl.login_flow_action("check")
self.ctrl.log_gui("Login flow: check")
self._safe(work, title="Login check error")
def on_login_cancel(self) -> None:
def work():
self.ctrl.login_flow_action("cancel")
self.ctrl.log_gui("Login flow: cancel")
self._safe(work, title="Login cancel error")
def on_login_stop(self) -> None:
def work():
self.ctrl.login_flow_stop()
self.ctrl.log_gui("Login flow: stop")
self._login_flow_autopoll_stop()
QTimer.singleShot(250, self.refresh_login_banner)
self._safe(work, title="Login stop error")
def on_logout(self) -> None:
def work():
self.ctrl.log_gui("Top Logout clicked")
res = self.ctrl.vpn_logout()
self._set_text(self.txt_vpn, res.pretty_text or str(res))
QTimer.singleShot(250, self.refresh_login_banner)
self._safe(work, title="Logout error")