diff options
Diffstat (limited to 'kvmd/validators')
-rw-r--r-- | kvmd/validators/__init__.py | 83 | ||||
-rw-r--r-- | kvmd/validators/auth.py | 43 | ||||
-rw-r--r-- | kvmd/validators/basic.py | 73 | ||||
-rw-r--r-- | kvmd/validators/fs.py | 52 | ||||
-rw-r--r-- | kvmd/validators/hw.py | 42 | ||||
-rw-r--r-- | kvmd/validators/kvm.py | 48 | ||||
-rw-r--r-- | kvmd/validators/net.py | 67 |
7 files changed, 408 insertions, 0 deletions
diff --git a/kvmd/validators/__init__.py b/kvmd/validators/__init__.py new file mode 100644 index 00000000..f4b0f1fa --- /dev/null +++ b/kvmd/validators/__init__.py @@ -0,0 +1,83 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +import re + +from typing import List +from typing import Callable +from typing import NoReturn +from typing import Any + + +# ===== +class ValidatorError(ValueError): + pass + + +# ===== +def raise_error(arg: Any, name: str, hide: bool=False) -> NoReturn: + arg_str = " " + if not hide: + arg_str = (" %r " if isinstance(arg, (str, bytes)) else " '%s' ") % (arg) + raise ValidatorError("The argument" + arg_str + "is not a valid " + name) + + +def check_not_none(arg: Any, name: str) -> Any: + if arg is None: + raise ValidatorError("Empty argument is not a valid %s" % (name)) + return arg + + +def check_not_none_string(arg: Any, name: str, strip: bool=True) -> str: + arg = str(check_not_none(arg, name)) + if strip: + arg = arg.strip() + return arg + + +def check_in_list(arg: Any, name: str, variants: List) -> Any: + if arg not in variants: + raise_error(arg, name) + return arg + + +def check_string_in_list(arg: Any, name: str, variants: List[str], lower: bool=True) -> Any: + arg = check_not_none_string(arg, name) + if lower: + arg = arg.lower() + return check_in_list(arg, name, variants) + + +def check_re_match(arg: Any, name: str, pattern: str, strip: bool=True, hide: bool=False) -> str: + arg = check_not_none_string(arg, name, strip=strip) + if re.match(pattern, arg, flags=re.MULTILINE) is None: + raise_error(arg, name, hide=hide) + return arg + + +def check_any(arg: Any, name: str, validators: List[Callable[[Any], Any]]) -> Any: + for validator in validators: + try: + return validator(arg) + except Exception: + pass + raise_error(arg, name) diff --git a/kvmd/validators/auth.py b/kvmd/validators/auth.py new file mode 100644 index 00000000..5f6188e1 --- /dev/null +++ b/kvmd/validators/auth.py @@ -0,0 +1,43 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +from typing import Any + +from . import check_string_in_list +from . import check_re_match + + +# ===== +def valid_user(arg: Any) -> str: + return check_re_match(arg, "username characters", r"^[a-z_][a-z0-9_-]*$") + + +def valid_passwd(arg: Any) -> str: + return check_re_match(arg, "passwd characters", r"^[\x20-\x7e]*\Z$", strip=False, hide=True) + + +def valid_auth_token(arg: Any) -> str: + return check_re_match(arg, "auth token", r"^[0-9a-f]{64}$", hide=True) + + +def valid_auth_type(arg: Any) -> str: + return check_string_in_list(arg, "auth type", ["basic"]) diff --git a/kvmd/validators/basic.py b/kvmd/validators/basic.py new file mode 100644 index 00000000..e4a2336e --- /dev/null +++ b/kvmd/validators/basic.py @@ -0,0 +1,73 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +from typing import Type +from typing import Union +from typing import Any + +from . import ValidatorError +from . import raise_error +from . import check_not_none_string +from . import check_in_list + + +# ===== +def valid_bool(arg: Any) -> bool: + true_args = ["1", "true", "yes"] + false_args = ["0", "false", "no"] + + name = "bool (%r or %r)" % (true_args, false_args) + + arg = check_not_none_string(arg, name).lower() + arg = check_in_list(arg, name, true_args + false_args) + return (arg in true_args) + + +def valid_number( + arg: Any, + min: Union[int, float, None]=None, # pylint: disable=redefined-builtin + max: Union[int, float, None]=None, # pylint: disable=redefined-builtin + type: Union[Type[int], Type[float]]=int, # pylint: disable=redefined-builtin + name: str="", +) -> Union[int, float]: + + name = (name or type.__name__) + + arg = check_not_none_string(arg, name) + try: + arg = type(arg) + except Exception: + raise_error(arg, name) + + if min is not None and arg < min: + raise ValidatorError("The argument '%s' must be %s and greater or equial than %s" % (arg, name, min)) + if max is not None and arg > max: + raise ValidatorError("The argument '%s' must be %s and lesser or equal then %s" % (arg, name, max)) + return arg + + +def valid_int_f1(arg: Any) -> int: + return int(valid_number(arg, min=1)) + + +def valid_float_f01(arg: Any) -> float: + return float(valid_number(arg, min=0.1, type=float)) diff --git a/kvmd/validators/fs.py b/kvmd/validators/fs.py new file mode 100644 index 00000000..ed895818 --- /dev/null +++ b/kvmd/validators/fs.py @@ -0,0 +1,52 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +import os + +from typing import Any + +from . import raise_error +from . import check_not_none_string + +from .basic import valid_number + + +# ===== +def valid_abs_path(arg: Any, exists: bool=False) -> str: + name = ("existent absolute path" if exists else "absolute path") + + if len(str(arg).strip()) == 0: + arg = None + arg = check_not_none_string(arg, name) + + arg = os.path.abspath(arg) + if exists and not os.access(arg, os.F_OK): + raise_error(arg, name) + return arg + + +def valid_abs_path_exists(arg: Any) -> str: + return valid_abs_path(arg, exists=True) + + +def valid_unix_mode(arg: Any) -> int: + return int(valid_number(arg, min=0, name="UNIX mode")) diff --git a/kvmd/validators/hw.py b/kvmd/validators/hw.py new file mode 100644 index 00000000..a68743ad --- /dev/null +++ b/kvmd/validators/hw.py @@ -0,0 +1,42 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +from typing import Any + +from . import check_in_list + +from .basic import valid_number + + +# ===== +def valid_tty_speed(arg: Any) -> int: + name = "TTY speed" + arg = int(valid_number(arg, name=name)) + return check_in_list(arg, name, [1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]) + + +def valid_gpio_pin(arg: Any) -> int: + return int(valid_number(arg, min=0, name="GPIO pin")) + + +def valid_gpio_pin_optional(arg: Any) -> int: + return int(valid_number(arg, min=-1, name="optional GPIO pin")) diff --git a/kvmd/validators/kvm.py b/kvmd/validators/kvm.py new file mode 100644 index 00000000..034587ef --- /dev/null +++ b/kvmd/validators/kvm.py @@ -0,0 +1,48 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +from typing import Any + +from . import check_string_in_list + +from .basic import valid_number + + +# ===== +def valid_atx_button(arg: Any) -> str: + return check_string_in_list(arg, "ATX button", ["power", "power_long", "reset"]) + + +def valid_kvm_target(arg: Any) -> str: + return check_string_in_list(arg, "KVM target", ["kvm", "server"]) + + +def valid_log_seek(arg: Any) -> int: + return int(valid_number(arg, min=0, name="log seek")) + + +def valid_stream_quality(arg: Any) -> int: + return int(valid_number(arg, min=1, max=100, name="stream quality")) + + +def valid_stream_fps(arg: Any) -> int: + return int(valid_number(arg, min=0, max=30, name="stream FPS")) diff --git a/kvmd/validators/net.py b/kvmd/validators/net.py new file mode 100644 index 00000000..cad87f07 --- /dev/null +++ b/kvmd/validators/net.py @@ -0,0 +1,67 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev <[email protected]> # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <https://www.gnu.org/licenses/>. # +# # +# ========================================================================== # + + +import socket + +from typing import Any + +from . import check_not_none_string +from . import check_re_match +from . import check_any + +from .basic import valid_number + + +# ===== +def valid_ip_or_host(arg: Any) -> str: + name = "IP address or RFC-1123 hostname" + return check_any( + arg=check_not_none_string(arg, name), + name=name, + validators=[ + valid_ip, + valid_rfc_host, + ], + ) + + +def valid_ip(arg: Any) -> str: + name = "IP address" + return check_any( + arg=check_not_none_string(arg, name), + name=name, + validators=[ + lambda arg: (arg, socket.inet_pton(socket.AF_INET, arg))[0], + lambda arg: (arg, socket.inet_pton(socket.AF_INET6, arg))[0], + ], + ) + + +def valid_rfc_host(arg: Any) -> str: + # http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address + pattern = r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*" \ + r"([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$" + return check_re_match(arg, "RFC-1123 hostname", pattern) + + +def valid_port(arg: Any) -> int: + return int(valid_number(arg, min=0, max=65535, name="TCP/UDP port")) |