210 lines
7.2 KiB
Python
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")
|