diff --git a/common_tools.py b/common_tools.py index 7650fae..a800047 100755 --- a/common_tools.py +++ b/common_tools.py @@ -1,6 +1,6 @@ """ Classes Method and Functions for lx Apps """ -import os +import getpass import shutil import signal import base64 @@ -222,27 +222,6 @@ class LxTools: y = (screen_height - height) // 2 window.geometry(f"{width}x{height}+{x}+{y}") - @staticmethod - def get_username() -> str: - """ - Returns the username of the logged-in user, - even if the script is running with root privileges. - """ - try: - result = run( - ["logname"], - stdout=PIPE, - text=True, - check=True, - ) - if result.returncode != 0: - pass - - return result.stdout.strip() - - except subprocess.CalledProcessError: - pass - @staticmethod def clean_files(TEMP_DIR: Path = None, file: Path = None) -> None: """ @@ -520,82 +499,50 @@ class Tunnel: return data @staticmethod - def active() -> str: + def get_active() -> str: """ Shows the Active Tunnel """ - active = ( - os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"') - .read() - .split() - ) - if not active: - active = "" - else: - active = active[0] + active = None + try: + process: CompletedProcess[str] = run( + ["nmcli", "-t", "-f", "NAME,TYPE", "connection", "show", "--active"], + capture_output=True, + text=True, + check=False, + ) - return active + active = next( + line.split(":")[0].strip() + for line in process.stdout.splitlines() + if line.endswith("wireguard") + ) + + if process.stderr and "error" in process.stderr.lower(): + logging.error(f"Error output on nmcli: {process.stderr}") + + except StopIteration: + active = None + except Exception as e: + logging.error(f"Error on nmcli: {e}") + active = None + + return active if active is not None else "" @staticmethod - def list() -> List[str]: - """ - Returns a list of Wireguard tunnel names - """ - AppConfig.TEMP_DIR: Path = Path("/tmp/tlecdcwg/") - wg_s: List[str] = os.listdir(AppConfig.TEMP_DIR) - - return wg_s - - @staticmethod - def export( - image_path: Path = None, - image_path2: Path = None, - image_path3: Path = None, - image_path4: Path = None, - title: Dict = None, - window_msg: Dict = None, - ) -> None: + def export() -> bool: """ This will export the tunnels. A zipfile with the current date and time is created in the user's home directory with the correct right - Args: - AppConfig.IMAGE_PATHS["icon_info"]: Image for TK window which is displayed to the left of the text - AppConfig.IMAGE_PATHS["icon_vpn"]: Image for Task Icon - AppConfig.IMAGE_PATHS["icon_error"]: Image for TK window which is displayed to the left of the text - AppConfig.IMAGE_PATHS["icon_msg"]: Image for Task Icon """ now_time: datetime = datetime.now() now_datetime: str = now_time.strftime("wg-exp-%m-%d-%Y-%H:%M") - tl: List[str] = Tunnel.list() try: - if len(tl) != 0: - wg_tar: str = f"{Path.home()}/{now_datetime}" - shutil.copytree("/tmp/tlecdcwg/", "/tmp/wire_py", dirs_exist_ok=True) - source: Path = Path("/tmp/wire_py") - shutil.make_archive(wg_tar, "zip", source) - shutil.rmtree(source) - with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf: - if len(zf.namelist()) != 0: - - LxTools.msg_window( - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - Msg.STR["exp_succ"], - Msg.STR["exp_in_home"], - ) - - else: - - LxTools.msg_window( - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"], - Msg.STR["exp_err"], - Msg.STR["exp_try"], - ) - - else: + AppConfig.ensure_directories() + CryptoUtil.decrypt(getpass.getuser()) + if len([file.name for file in AppConfig.TEMP_DIR.glob("*.conf")]) == 0: LxTools.msg_window( AppConfig.IMAGE_PATHS["icon_info"], @@ -603,10 +550,58 @@ class Tunnel: Msg.STR["sel_tl"], Msg.STR["tl_first"], ) + return False + else: + wg_tar: str = f"{AppConfig.BASE_DIR}/{now_datetime}" + try: + shutil.make_archive(wg_tar, "zip", AppConfig.TEMP_DIR) + with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf: + if len(zf.namelist()) != 0: + + LxTools.msg_window( + AppConfig.IMAGE_PATHS["icon_info"], + AppConfig.IMAGE_PATHS["icon_vpn"], + Msg.STR["exp_succ"], + Msg.STR["exp_in_home"], + ) + else: + logging.error( + f"There was a mistake at creating the Zip file. File is empty." + ) + LxTools.msg_window( + AppConfig.IMAGE_PATHS["icon_error"], + AppConfig.IMAGE_PATHS["icon_msg"], + Msg.STR["exp_err"], + Msg.STR["exp_zip"], + ) + return False + return True + except PermissionError: + logging.error( + f"Permission denied when creating archive in {wg_tar}" + ) + return False + + except Exception as e: + logging.error(f"Export failed: {str(e)}") + LxTools.msg_window( + AppConfig.IMAGE_PATHS["icon_error"], + AppConfig.IMAGE_PATHS["icon_msg"], + Msg.STR["exp_err"], + Msg.STR["exp_try"], + ) + return False + except zipfile.BadZipFile as e: + logging.error(f"Invalid ZIP file: {e}") + return False except TypeError: pass + finally: + LxTools.clean_files(AppConfig.TEMP_DIR) + AppConfig.ensure_directories() + # ConfigManager with caching class ConfigManager: diff --git a/ssl_encrypt.py b/ssl_encrypt.py index 191e0a2..f3068ba 100755 --- a/ssl_encrypt.py +++ b/ssl_encrypt.py @@ -2,7 +2,6 @@ """ This Script encrypt Wireguardfiles for Wirepy users for more Security """ import argparse -import logging from pathlib import Path import pwd import shutil diff --git a/wirepy.py b/wirepy.py index bbacf24..970272d 100755 --- a/wirepy.py +++ b/wirepy.py @@ -177,7 +177,7 @@ class FrameWidgets(ttk.Frame): self.about_btn.grid(column=2, columnspan=2, row=0) self.readme = tk.Menu(self) - self.a = Tunnel.active() + self.a = Tunnel.get_active() # Label Frame 1 self.lb_frame_btn_lbox = ttk.Frame(self) @@ -292,14 +292,7 @@ class FrameWidgets(ttk.Frame): self.btn_exp = ttk.Button( self.lb_frame_btn_lbox, image=self.exp_pic, - command=lambda: Tunnel.export( - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"], - Msg.STR["sel_tl"], - Msg.STR["tl_first"], - ), + command=lambda: Tunnel.export(), padding=0, ) @@ -713,7 +706,7 @@ class FrameWidgets(ttk.Frame): LxTools.clean_files(AppConfig.TEMP_DIR, file=None) AppConfig.ensure_directories() self.str_var.set("") - self.a = Tunnel.active() + self.a = Tunnel.get_active() self.l_box.insert(0, self.a) self.wg_autostart.configure(state="normal") self.l_box.selection_clear(0, tk.END) @@ -1147,7 +1140,7 @@ class FrameWidgets(ttk.Frame): """ Updated the display after connection changes """ - self.a = Tunnel.active() + self.a = Tunnel.get_active() if not hasattr(self, "str_var"): self.str_var = tk.StringVar() self.str_var.set(self.a) diff --git a/wp_app_config.py b/wp_app_config.py index 9f88244..8b3f355 100644 --- a/wp_app_config.py +++ b/wp_app_config.py @@ -195,6 +195,11 @@ class Msg: "imp_err": _("Import Error"), "exp_err": _("Export Error"), "exp_try": _("Export failed! Please try again"), + "exp_zip": _( + "The error occurs because the zipfile module encountered an issue.\n" + "Please verify that you have the latest version of WirePy installed.\n" + "You can also contact the WirePy developer team to resolve this issue quickly.\n" + ), "tl_first": _("Please first import tunnel"), "sel_list": _("Please select a tunnel from the list"), "sign_len": _("The new name may contain only 12 characters"),