mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-30 07:51:27 +00:00
246 lines
7.8 KiB
Python
246 lines
7.8 KiB
Python
|
from abc import ABC, abstractmethod
|
||
|
import re
|
||
|
from typing import Optional
|
||
|
|
||
|
from selfprivacy_api.utils import (
|
||
|
ReadUserData,
|
||
|
WriteUserData,
|
||
|
check_if_subdomain_is_taken,
|
||
|
)
|
||
|
|
||
|
|
||
|
class ServiceConfigItem(ABC):
|
||
|
id: str
|
||
|
description: str
|
||
|
widget: str
|
||
|
type: str
|
||
|
|
||
|
@abstractmethod
|
||
|
def get_value(self, service_id):
|
||
|
pass
|
||
|
|
||
|
@abstractmethod
|
||
|
def set_value(self, value, service_id):
|
||
|
pass
|
||
|
|
||
|
@abstractmethod
|
||
|
def validate_value(self, value):
|
||
|
return True
|
||
|
|
||
|
def as_dict(self, service_options):
|
||
|
return {
|
||
|
"id": self.id,
|
||
|
"type": self.type,
|
||
|
"description": self.description,
|
||
|
"widget": self.widget,
|
||
|
"value": self.get_value(service_options),
|
||
|
}
|
||
|
|
||
|
|
||
|
class StringServiceConfigItem(ServiceConfigItem):
|
||
|
def __init__(
|
||
|
self,
|
||
|
id: str,
|
||
|
default_value: str,
|
||
|
description: str,
|
||
|
regex: Optional[str] = None,
|
||
|
widget: Optional[str] = None,
|
||
|
allow_empty: bool = False,
|
||
|
):
|
||
|
if widget == "subdomain" and not regex:
|
||
|
raise ValueError("Subdomain widget requires regex")
|
||
|
self.id = id
|
||
|
self.type = "string"
|
||
|
self.default_value = default_value
|
||
|
self.description = description
|
||
|
self.regex = re.compile(regex) if regex else None
|
||
|
self.widget = widget if widget else "text"
|
||
|
self.allow_empty = allow_empty
|
||
|
|
||
|
def get_value(self, service_id):
|
||
|
with ReadUserData() as user_data:
|
||
|
if "modules" in user_data and service_id in user_data["modules"]:
|
||
|
return user_data["modules"][service_id].get(self.id, self.default_value)
|
||
|
return self.default_value
|
||
|
|
||
|
def set_value(self, value, service_id):
|
||
|
if not self.validate_value(value):
|
||
|
raise ValueError(f"Value {value} is not valid")
|
||
|
with WriteUserData() as user_data:
|
||
|
if "modules" not in user_data:
|
||
|
user_data["modules"] = {}
|
||
|
if service_id not in user_data["modules"]:
|
||
|
user_data["modules"][service_id] = {}
|
||
|
user_data["modules"][service_id][self.id] = value
|
||
|
|
||
|
def as_dict(self, service_options):
|
||
|
return {
|
||
|
"id": self.id,
|
||
|
"type": self.type,
|
||
|
"description": self.description,
|
||
|
"widget": self.widget,
|
||
|
"value": self.get_value(service_options),
|
||
|
"default_value": self.default_value,
|
||
|
"regex": self.regex.pattern if self.regex else None,
|
||
|
}
|
||
|
|
||
|
def validate_value(self, value):
|
||
|
if not isinstance(value, str):
|
||
|
return False
|
||
|
if not self.allow_empty and not value:
|
||
|
return False
|
||
|
if self.regex and not self.regex.match(value):
|
||
|
return False
|
||
|
if self.widget == "subdomain":
|
||
|
if check_if_subdomain_is_taken(value):
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
|
||
|
class BoolServiceConfigItem(ServiceConfigItem):
|
||
|
def __init__(
|
||
|
self,
|
||
|
id: str,
|
||
|
default_value: bool,
|
||
|
description: str,
|
||
|
widget: Optional[str] = None,
|
||
|
):
|
||
|
self.id = id
|
||
|
self.type = "bool"
|
||
|
self.default_value = default_value
|
||
|
self.description = description
|
||
|
self.widget = widget if widget else "switch"
|
||
|
|
||
|
def get_value(self, service_id):
|
||
|
with ReadUserData() as user_data:
|
||
|
if "modules" in user_data and service_id in user_data["modules"]:
|
||
|
return user_data["modules"][service_id].get(self.id, self.default_value)
|
||
|
return self.default_value
|
||
|
|
||
|
def set_value(self, value, service_id):
|
||
|
if not self.validate_value(value):
|
||
|
raise ValueError(f"Value {value} is not a boolean")
|
||
|
with WriteUserData() as user_data:
|
||
|
if "modules" not in user_data:
|
||
|
user_data["modules"] = {}
|
||
|
if service_id not in user_data["modules"]:
|
||
|
user_data["modules"][service_id] = {}
|
||
|
user_data["modules"][service_id][self.id] = value
|
||
|
|
||
|
def as_dict(self, service_options):
|
||
|
return {
|
||
|
"id": self.id,
|
||
|
"type": self.type,
|
||
|
"description": self.description,
|
||
|
"widget": self.widget,
|
||
|
"value": self.get_value(service_options),
|
||
|
"default_value": self.default_value,
|
||
|
}
|
||
|
|
||
|
def validate_value(self, value):
|
||
|
return isinstance(value, bool)
|
||
|
|
||
|
|
||
|
class EnumServiceConfigItem(ServiceConfigItem):
|
||
|
def __init__(
|
||
|
self,
|
||
|
id: str,
|
||
|
default_value: str,
|
||
|
description: str,
|
||
|
options: list[str],
|
||
|
widget: Optional[str] = None,
|
||
|
):
|
||
|
self.id = id
|
||
|
self.type = "enum"
|
||
|
self.default_value = default_value
|
||
|
self.description = description
|
||
|
self.options = options
|
||
|
self.widget = widget if widget else "select"
|
||
|
|
||
|
def get_value(self, service_id):
|
||
|
with ReadUserData() as user_data:
|
||
|
if "modules" in user_data and service_id in user_data["modules"]:
|
||
|
return user_data["modules"][service_id].get(self.id, self.default_value)
|
||
|
return self.default_value
|
||
|
|
||
|
def set_value(self, value, service_id):
|
||
|
if not self.validate_value(value):
|
||
|
raise ValueError(f"Value {value} is not in options")
|
||
|
with WriteUserData() as user_data:
|
||
|
if "modules" not in user_data:
|
||
|
user_data["modules"] = {}
|
||
|
if service_id not in user_data["modules"]:
|
||
|
user_data["modules"][service_id] = {}
|
||
|
user_data["modules"][service_id][self.id] = value
|
||
|
|
||
|
def as_dict(self, service_options):
|
||
|
return {
|
||
|
"id": self.id,
|
||
|
"type": self.type,
|
||
|
"description": self.description,
|
||
|
"widget": self.widget,
|
||
|
"value": self.get_value(service_options),
|
||
|
"default_value": self.default_value,
|
||
|
"options": self.options,
|
||
|
}
|
||
|
|
||
|
def validate_value(self, value):
|
||
|
if not isinstance(value, str):
|
||
|
return False
|
||
|
return value in self.options
|
||
|
|
||
|
|
||
|
# TODO: unused for now
|
||
|
class IntServiceConfigItem(ServiceConfigItem):
|
||
|
def __init__(
|
||
|
self,
|
||
|
id: str,
|
||
|
default_value: int,
|
||
|
description: str,
|
||
|
widget: Optional[str] = None,
|
||
|
min_value: Optional[int] = None,
|
||
|
max_value: Optional[int] = None,
|
||
|
) -> None:
|
||
|
self.id = id
|
||
|
self.type = "int"
|
||
|
self.default_value = default_value
|
||
|
self.description = description
|
||
|
self.widget = widget if widget else "number"
|
||
|
self.min_value = min_value
|
||
|
self.max_value = max_value
|
||
|
|
||
|
def get_value(self, service_id):
|
||
|
with ReadUserData() as user_data:
|
||
|
if "modules" in user_data and service_id in user_data["modules"]:
|
||
|
return user_data["modules"][service_id].get(self.id, self.default_value)
|
||
|
return self.default_value
|
||
|
|
||
|
def set_value(self, value, service_id):
|
||
|
if not self.validate_value(value):
|
||
|
raise ValueError(f"Value {value} is not valid")
|
||
|
with WriteUserData() as user_data:
|
||
|
if "modules" not in user_data:
|
||
|
user_data["modules"] = {}
|
||
|
if service_id not in user_data["modules"]:
|
||
|
user_data["modules"][service_id] = {}
|
||
|
user_data["modules"][service_id][self.id] = value
|
||
|
|
||
|
def as_dict(self, service_options):
|
||
|
return {
|
||
|
"id": self.id,
|
||
|
"type": self.type,
|
||
|
"description": self.description,
|
||
|
"widget": self.widget,
|
||
|
"value": self.get_value(service_options),
|
||
|
"default_value": self.default_value,
|
||
|
"min_value": self.min_value,
|
||
|
"max_value": self.max_value,
|
||
|
}
|
||
|
|
||
|
def validate_value(self, value):
|
||
|
if not isinstance(value, int):
|
||
|
return False
|
||
|
return (self.min_value is None or value >= self.min_value) and (
|
||
|
self.max_value is None or value <= self.max_value
|
||
|
)
|