diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/wifi/adapters/wireless.py b/demos/python/sdk_wireless_camera_control/open_gopro/wifi/adapters/wireless.py index 974c8419..71cb3c1c 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/wifi/adapters/wireless.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/wifi/adapters/wireless.py @@ -117,15 +117,16 @@ def _detect_driver(self) -> WifiController: if which("networksetup"): return NetworksetupWireless() - # Try Linux options. Need password for sudo - if not self._password: - self._password = getpass("Need to run as sudo. Enter password: ") - # Validate password - if "VALID PASSWORD" not in cmd(f'echo "{self._password}" | sudo -S echo "VALID PASSWORD"'): - raise RuntimeError("Invalid password") - + # Try Linux options. # try nmcli (Ubuntu 14.04). Allow for use in Snap Package if which("nmcli") or which("nmcli", path="/snap/bin/"): + + ctrl_wifi = cmd("nmcli general permissions |grep enable-disable-wifi") + scan_wifi = cmd("nmcli general permissions |grep scan") + + if not "yes" in ctrl_wifi or not "yes" in scan_wifi: + self._sudo_from_stdin() + version = cmd("nmcli --version").split()[-1] # On RHEL based systems, the version is in the form of 1.44.2-1.fc39 # wich raises an error when trying to compare it with the Version class @@ -138,10 +139,34 @@ def _detect_driver(self) -> WifiController: ) # try nmcli (Ubuntu w/o network-manager) if which("wpa_supplicant"): + self._sudo_from_stdin() return WpasupplicantWireless(password=self._password) raise RuntimeError("Unable to find compatible wireless driver.") + def _sudo_from_stdin(self) -> str: + """Ask for sudo password input from stdin + + This method prompts the user to enter the sudo password from the command line. + It validates the password by running a command with sudo and checking if the password is valid. + + Returns: + str: The entered sudo password. + + Raises: + RuntimeError: If the password is empty or invalid. + """ + # Need password for sudo + if not self._password: + self._password = getpass("Need to run as sudo. Enter password: ") + if not self._password: + raise RuntimeError("Can't use sudo with empty password.") + # Validate password + if "VALID PASSWORD" not in cmd(f'echo "{self._password}" | sudo -S echo "VALID PASSWORD"'): + raise RuntimeError("Invalid password") + + return self._password + @pass_through_to_driver def connect(self, ssid: str, password: str, timeout: float = 15) -> bool: # type: ignore """Connect to a network. @@ -234,7 +259,7 @@ def is_on(self) -> bool: class NmcliWireless(WifiController): """Linux nmcli Driver < 0.9.9.0.""" - def __init__(self, password: str, interface: Optional[str] = None) -> None: + def __init__(self, password: str | None, interface: Optional[str] = None) -> None: WifiController.__init__(self, interface=interface, password=password) def _clean(self, partial: str) -> None: @@ -395,7 +420,7 @@ def power(self, power: bool) -> bool: class Nmcli0990Wireless(WifiController): """Linux nmcli Driver >= 0.9.9.0.""" - def __init__(self, password: str, interface: Optional[str] = None) -> None: + def __init__(self, password: str | None, interface: Optional[str] = None) -> None: WifiController.__init__(self, interface=interface, password=password) def _clean(self, partial: str) -> None: @@ -554,7 +579,7 @@ class WpasupplicantWireless(WifiController): _file = "/tmp/wpa_supplicant.conf" - def __init__(self, password: str, interface: Optional[str] = None) -> None: + def __init__(self, password: str | None, interface: Optional[str] = None) -> None: WifiController.__init__(self, interface=interface, password=password) def connect(self, ssid: str, password: str, timeout: float = 15) -> bool: diff --git a/demos/python/sdk_wireless_camera_control/open_gopro/wifi/controller.py b/demos/python/sdk_wireless_camera_control/open_gopro/wifi/controller.py index 49884329..fd1ca6bb 100644 --- a/demos/python/sdk_wireless_camera_control/open_gopro/wifi/controller.py +++ b/demos/python/sdk_wireless_camera_control/open_gopro/wifi/controller.py @@ -143,12 +143,9 @@ def is_on(self) -> bool: def sudo(self) -> str: """Return the sudo encapsulated password - Raises: - RuntimeError: No password has been supplied - Returns: str: echo "**********" | sudo -S """ if not self._password: - raise RuntimeError("Can't use sudo with empty password.") + return "" return f'echo "{self._password}" | sudo -S'