diff --git a/src/vpn_manager_globalprotect/backend.py b/src/vpn_manager_globalprotect/backend.py index 9c263b8..6b03a43 100644 --- a/src/vpn_manager_globalprotect/backend.py +++ b/src/vpn_manager_globalprotect/backend.py @@ -26,11 +26,11 @@ import re import psutil -class LoginTarget(IntEnum): +class LoginTarget(StrEnum): """Login target enum.""" - GATEWAY = 0 - PORTAL = 1 + GATEWAY = "gateway" + PORTAL = "portal" class Options(TypedDict, total=False): @@ -52,7 +52,8 @@ class Auth(TypedDict): class GlobalProtectConnection( - ConnectionBase, connection_type="dev.ezri.vpn1.Connection.GlobalProtect" + ConnectionBase, + connection_type="dev.ezri.vpn1.Connection.GlobalProtect", ): """GlobalProtect VPN connection backend.""" @@ -311,3 +312,46 @@ class GlobalProtectConnection( self._disconnecting = True self._proc.terminate() await self._proc_wait_task + + @classmethod + def validate_options(cls, options: dict[str, Variant]): + # options must contain hostname and login target. + if "hostname" not in options: + raise errors.InvalidOptions.missing("hostname") + if "login_target" not in options: + raise errors.InvalidOptions.missing( + "login_target", details="What login endpoint to use." + ) + + # validate types + if sig := options["hostname"].signature != "s": + raise errors.InvalidOptions.invalid_type("hostname", "s", sig) + if sig := options["login_target"].signature != "s": + raise errors.InvalidOptions.invalid_type("login_target", "s", sig) + if ( + sig := options.get("verify_certificate", Variant("b", True)).signature + != "b" + ): + raise errors.InvalidOptions.invalid_type("verify_certifcate", "b", sig) + if ( + sig := options.get("allow_insecure_crypto", Variant("b", True)).signature + != "b" + ): + raise errors.InvalidOptions.invalid_type("verify_certificate", "b", sig) + if sig := options.get("spoof_clientos", Variant("s", "")).signature != "s": + raise errors.InvalidOptions.invalid_type("spoof_clientos", "s", sig) + if ( + sig := options.get("use_default_browser", Variant("b", True)).signature + != "b" + ): + raise errors.InvalidOptions.invalid_type("use_default_browser", "b", sig) + + @classmethod + def restore_options(cls, options: dict) -> dict[str, Variant]: + result = {} + cls.put_value(result, "s", options, "hostname") + cls.put_value(result, "s", options, "login_target") + cls.put_value(result, "s", options, "spoof_clientos") + cls.put_value(result, "b", options, "verify_certificate") + cls.put_value(result, "b", options, "allow_insecure_crypto") + cls.put_value(result, "b", options, "use_default_browser") diff --git a/src/vpn_manager_globalprotect/errors.py b/src/vpn_manager_globalprotect/errors.py index bde3b30..ac4817b 100644 --- a/src/vpn_manager_globalprotect/errors.py +++ b/src/vpn_manager_globalprotect/errors.py @@ -10,26 +10,25 @@ from vpn_manager.common.errors import ( UnknownTarget, AuthenticationTimeout, NoAuthenticationInProgress, + InvalidOptions, +) + +GlobalProtectBaseException = VPNBaseException.derive_for_package( + "GlobalProtectBaseException", "dev.ezri.vpn1.GlobalProtect" ) -class CertificateError( - VPNBaseException, error_type="dev.ezri.vpn1.GlobalProtect.CertificateError" -): +class CertificateError(GlobalProtectBaseException): """Certificate error.""" -class SSLError(VPNBaseException, error_type="dev.ezri.vpn1.GlobalProtect.SSLError"): +class SSLError(GlobalProtectBaseException): """SSL error.""" -class PreloginFailure( - VPNBaseException, error_type="dev.ezri.vpn1.GlobalProtect.PreloginFailure" -): +class PreloginFailure(GlobalProtectBaseException): """Prelogin failure.""" -class InvalidResponse( - VPNBaseException, error_type="dev.ezri.vpn1.GlobalProtect.InvalidResponse" -): +class InvalidResponse(GlobalProtectBaseException): """Invalid response."""