diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index addf928..53c7649 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -6,11 +6,42 @@ from typing import List from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.services.bitwarden.icon import BITWARDEN_ICON +from selfprivacy_api.services.config_item import ( + StringServiceConfigItem, + BoolServiceConfigItem, + ServiceConfigItem, +) +from selfprivacy_api.utils.regex_strings import SUBDOMAIN_REGEX class Bitwarden(Service): """Class representing Bitwarden service.""" + config_items: dict[str, ServiceConfigItem] = { + "subdomain": StringServiceConfigItem( + id="subdomain", + default_value="password", + description="Subdomain", + regex=SUBDOMAIN_REGEX, + widget="subdomain", + ), + "signupsAllowed": BoolServiceConfigItem( + id="signupsAllowed", + default_value=True, + description="Allow new user signups", + ), + "sendsAllowed": BoolServiceConfigItem( + id="sendsAllowed", + default_value=True, + description="Allow users to use Bitwarden Send", + ), + "emergencyAccessAllowed": BoolServiceConfigItem( + id="emergencyAccessAllowed", + default_value=True, + description="Allow users to enable Emergency Access", + ), + } + @staticmethod def get_id() -> str: """Return service id.""" diff --git a/selfprivacy_api/services/forgejo/__init__.py b/selfprivacy_api/services/forgejo/__init__.py index d882771..a5b07b0 100644 --- a/selfprivacy_api/services/forgejo/__init__.py +++ b/selfprivacy_api/services/forgejo/__init__.py @@ -127,33 +127,6 @@ class Forgejo(Service): def restart(): subprocess.run(["systemctl", "restart", "forgejo.service"]) - @classmethod - def get_configuration(cls): - with ReadUserData() as user_data: - return { - key: cls.config_items[key].as_dict( - user_data.get("modules", {}).get(cls.get_id(), {}) - ) - for key in cls.config_items - } - - @classmethod - def set_configuration(cls, config_items): - # First, validate the configuration - for key, value in config_items.items(): - if cls.config_items[key].validate_value(value) is False: - raise ValueError(f"Value {value} is not valid for {key}") - with WriteUserData() as user_data: - if "modules" not in user_data: - user_data["modules"] = {} - if cls.get_id() not in user_data["modules"]: - user_data["modules"][cls.get_id()] = {} - for key, value in config_items.items(): - cls.config_items[key].set_value( - value, - user_data["modules"][cls.get_id()], - ) - @staticmethod def get_logs(): return "" diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 08462e0..81fd5ac 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -10,11 +10,31 @@ from selfprivacy_api.utils.systemd import ( from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.jitsimeet.icon import JITSI_ICON +from selfprivacy_api.services.config_item import ( + StringServiceConfigItem, + ServiceConfigItem, +) +from selfprivacy_api.utils.regex_strings import SUBDOMAIN_REGEX class JitsiMeet(Service): """Class representing Jitsi service""" + config_items: dict[str, ServiceConfigItem] = { + "subdomain": StringServiceConfigItem( + id="subdomain", + default_value="meet", + description="Subdomain", + regex=SUBDOMAIN_REGEX, + widget="subdomain", + ), + "appName": StringServiceConfigItem( + id="appName", + default_value="Jitsi Meet", + description="The name displayed in the web interface", + ), + } + @staticmethod def get_id() -> str: """Return service id.""" diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index 14ea078..ec1546d 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -7,11 +7,26 @@ from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.services.nextcloud.icon import NEXTCLOUD_ICON +from selfprivacy_api.services.config_item import ( + StringServiceConfigItem, + ServiceConfigItem, +) +from selfprivacy_api.utils.regex_strings import SUBDOMAIN_REGEX class Nextcloud(Service): """Class representing Nextcloud service.""" + config_items: dict[str, ServiceConfigItem] = { + "subdomain": StringServiceConfigItem( + id="subdomain", + default_value="cloud", + description="Subdomain", + regex=SUBDOMAIN_REGEX, + widget="subdomain", + ), + } + @staticmethod def get_id() -> str: """Return service id.""" diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 2493c87..fac8d2d 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -11,11 +11,26 @@ from selfprivacy_api.utils.systemd import ( from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.roundcube.icon import ROUNDCUBE_ICON +from selfprivacy_api.services.config_item import ( + StringServiceConfigItem, + ServiceConfigItem, +) +from selfprivacy_api.utils.regex_strings import SUBDOMAIN_REGEX class Roundcube(Service): """Class representing roundcube service""" + config_items: dict[str, ServiceConfigItem] = { + "subdomain": StringServiceConfigItem( + id="subdomain", + default_value="cloud", + description="Subdomain", + regex=SUBDOMAIN_REGEX, + widget="subdomain", + ), + } + @staticmethod def get_id() -> str: """Return service id.""" diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index ba1ba10..6d6bd47 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod from typing import List, Optional from selfprivacy_api import utils +from selfprivacy_api.services.config_item import ServiceConfigItem from selfprivacy_api.utils.default_subdomains import DEFAULT_SUBDOMAINS from selfprivacy_api.utils import ReadUserData, WriteUserData, get_domain from selfprivacy_api.utils.waitloop import wait_until_true @@ -34,6 +35,8 @@ class Service(ABC): can be installed, configured and used by a user. """ + config_items: dict[str, "ServiceConfigItem"] = {} + @staticmethod @abstractmethod def get_id() -> str: @@ -188,14 +191,32 @@ class Service(ABC): pass @classmethod - @abstractmethod - def get_configuration(cls) -> dict: - pass + def get_configuration(cls): + with ReadUserData() as user_data: + return { + key: cls.config_items[key].as_dict( + user_data.get("modules", {}).get(cls.get_id(), {}) + ) + for key in cls.config_items + } @classmethod - @abstractmethod def set_configuration(cls, config_items): - pass + for key, value in config_items.items(): + if key not in cls.config_items: + raise ValueError(f"Key {key} is not valid for {cls.get_id()}") + if cls.config_items[key].validate_value(value) is False: + raise ValueError(f"Value {value} is not valid for {key}") + with WriteUserData() as user_data: + if "modules" not in user_data: + user_data["modules"] = {} + if cls.get_id() not in user_data["modules"]: + user_data["modules"][cls.get_id()] = {} + for key, value in config_items.items(): + cls.config_items[key].set_value( + value, + user_data["modules"][cls.get_id()], + ) @staticmethod @abstractmethod