From 4823491e3eaf1ba77e38610aeeb467f9035dfe87 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Thu, 6 Jun 2024 23:14:07 +0400 Subject: [PATCH 01/18] feat: add roundcube service --- selfprivacy_api/services/__init__.py | 2 + .../services/roundcube/__init__.py | 104 ++++++++++++++++++ selfprivacy_api/services/roundcube/icon.py | 16 +++ 3 files changed, 122 insertions(+) create mode 100644 selfprivacy_api/services/roundcube/__init__.py create mode 100644 selfprivacy_api/services/roundcube/icon.py diff --git a/selfprivacy_api/services/__init__.py b/selfprivacy_api/services/__init__.py index f9dfac2..267cc31 100644 --- a/selfprivacy_api/services/__init__.py +++ b/selfprivacy_api/services/__init__.py @@ -4,6 +4,7 @@ import typing from selfprivacy_api.services.bitwarden import Bitwarden from selfprivacy_api.services.gitea import Gitea from selfprivacy_api.services.jitsimeet import JitsiMeet +from selfprivacy_api.services.roundcube import Roundcube from selfprivacy_api.services.mailserver import MailServer from selfprivacy_api.services.nextcloud import Nextcloud from selfprivacy_api.services.pleroma import Pleroma @@ -19,6 +20,7 @@ services: list[Service] = [ Pleroma(), Ocserv(), JitsiMeet(), + Roundcube(), ] diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py new file mode 100644 index 0000000..4deed57 --- /dev/null +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -0,0 +1,104 @@ +"""Class representing Roundcube service""" + +import base64 +import subprocess +from typing import Optional, List + +from selfprivacy_api.jobs import Job +from selfprivacy_api.utils.systemd import ( + get_service_status_from_several_units, +) +from selfprivacy_api.services.service import Service, ServiceStatus +from selfprivacy_api.utils import get_domain +from selfprivacy_api.utils.block_devices import BlockDevice +from selfprivacy_api.services.roundcube.icon import ROUNDCUBE_ICON + + +class Roundcube(Service): + """Class representing roundcube service""" + + @staticmethod + def get_id() -> str: + """Return service id.""" + return "roundcube" + + @staticmethod + def get_display_name() -> str: + """Return service display name.""" + return "roundcube" + + @staticmethod + def get_description() -> str: + """Return service description.""" + return "Roundcube is a open source webmail software." + + @staticmethod + def get_svg_icon() -> str: + """Read SVG icon from file and return it as base64 encoded string.""" + return base64.b64encode(ROUNDCUBE_ICON.encode("utf-8")).decode("utf-8") + + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://roundcube.{domain}" + + @staticmethod + def get_subdomain() -> Optional[str]: + return "roundcube" + + @staticmethod + def is_movable() -> bool: + return False + + @staticmethod + def is_required() -> bool: + return False + + @staticmethod + def get_backup_description() -> str: + return "Secrets that are used to encrypt the communication." + + @staticmethod + def get_status() -> ServiceStatus: + return get_service_status_from_several_units(["phpfpm-roundcube.service"]) + + @staticmethod + def stop(): + subprocess.run( + ["systemctl", "stop", "phpfpm-roundcube.service"], + check=False, + ) + + @staticmethod + def start(): + subprocess.run( + ["systemctl", "start", "phpfpm-roundcube.service"], + check=False, + ) + + @staticmethod + def restart(): + subprocess.run( + ["systemctl", "restart", "phpfpm-roundcube.service"], + check=False, + ) + + @staticmethod + def get_configuration(): + return {} + + @staticmethod + def set_configuration(config_items): + return super().set_configuration(config_items) + + @staticmethod + def get_logs(): + return "" + + @staticmethod + def get_folders() -> List[str]: + return ["/var/lib/postgresql"] + + def move_to_volume(self, volume: BlockDevice) -> Job: + raise NotImplementedError("roundcube service is not movable") diff --git a/selfprivacy_api/services/roundcube/icon.py b/selfprivacy_api/services/roundcube/icon.py new file mode 100644 index 0000000..5fb1288 --- /dev/null +++ b/selfprivacy_api/services/roundcube/icon.py @@ -0,0 +1,16 @@ +ROUNDCUBE_ICON = """ + + + + + + + + + +""" From 1b91168d060571efc9fc3b7ad22bcc9d60373bf7 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Mon, 10 Jun 2024 05:52:26 +0400 Subject: [PATCH 02/18] style: fix imports --- selfprivacy_api/graphql/queries/api_queries.py | 2 ++ selfprivacy_api/graphql/queries/backup.py | 1 + selfprivacy_api/graphql/queries/common.py | 1 + selfprivacy_api/graphql/queries/jobs.py | 2 ++ selfprivacy_api/graphql/queries/providers.py | 1 + selfprivacy_api/graphql/queries/services.py | 1 + selfprivacy_api/graphql/queries/storage.py | 9 ++++++--- selfprivacy_api/graphql/queries/system.py | 2 ++ selfprivacy_api/graphql/queries/users.py | 1 + 9 files changed, 17 insertions(+), 3 deletions(-) diff --git a/selfprivacy_api/graphql/queries/api_queries.py b/selfprivacy_api/graphql/queries/api_queries.py index 7052ded..77b0387 100644 --- a/selfprivacy_api/graphql/queries/api_queries.py +++ b/selfprivacy_api/graphql/queries/api_queries.py @@ -1,8 +1,10 @@ """API access status""" + # pylint: disable=too-few-public-methods import datetime import typing import strawberry + from strawberry.types import Info from selfprivacy_api.actions.api_tokens import ( get_api_tokens_with_caller_flag, diff --git a/selfprivacy_api/graphql/queries/backup.py b/selfprivacy_api/graphql/queries/backup.py index afb24ae..7695f0d 100644 --- a/selfprivacy_api/graphql/queries/backup.py +++ b/selfprivacy_api/graphql/queries/backup.py @@ -1,4 +1,5 @@ """Backup""" + # pylint: disable=too-few-public-methods import typing import strawberry diff --git a/selfprivacy_api/graphql/queries/common.py b/selfprivacy_api/graphql/queries/common.py index a1abbdc..09dbaf4 100644 --- a/selfprivacy_api/graphql/queries/common.py +++ b/selfprivacy_api/graphql/queries/common.py @@ -1,4 +1,5 @@ """Common types and enums used by different types of queries.""" + from enum import Enum import datetime import typing diff --git a/selfprivacy_api/graphql/queries/jobs.py b/selfprivacy_api/graphql/queries/jobs.py index e7b99e6..eebba43 100644 --- a/selfprivacy_api/graphql/queries/jobs.py +++ b/selfprivacy_api/graphql/queries/jobs.py @@ -1,7 +1,9 @@ """Jobs status""" + # pylint: disable=too-few-public-methods import typing import strawberry + from selfprivacy_api.graphql.common_types.jobs import ( ApiJob, get_api_job_by_id, diff --git a/selfprivacy_api/graphql/queries/providers.py b/selfprivacy_api/graphql/queries/providers.py index 2995fe8..c08ea6c 100644 --- a/selfprivacy_api/graphql/queries/providers.py +++ b/selfprivacy_api/graphql/queries/providers.py @@ -1,4 +1,5 @@ """Enums representing different service providers.""" + from enum import Enum import strawberry diff --git a/selfprivacy_api/graphql/queries/services.py b/selfprivacy_api/graphql/queries/services.py index 5398f81..3085d61 100644 --- a/selfprivacy_api/graphql/queries/services.py +++ b/selfprivacy_api/graphql/queries/services.py @@ -1,4 +1,5 @@ """Services status""" + # pylint: disable=too-few-public-methods import typing import strawberry diff --git a/selfprivacy_api/graphql/queries/storage.py b/selfprivacy_api/graphql/queries/storage.py index 4b9a291..c221d26 100644 --- a/selfprivacy_api/graphql/queries/storage.py +++ b/selfprivacy_api/graphql/queries/storage.py @@ -1,4 +1,5 @@ """Storage queries.""" + # pylint: disable=too-few-public-methods import typing import strawberry @@ -18,9 +19,11 @@ class Storage: """Get list of volumes""" return [ StorageVolume( - total_space=str(volume.fssize) - if volume.fssize is not None - else str(volume.size), + total_space=( + str(volume.fssize) + if volume.fssize is not None + else str(volume.size) + ), free_space=str(volume.fsavail), used_space=str(volume.fsused), root=volume.is_root(), diff --git a/selfprivacy_api/graphql/queries/system.py b/selfprivacy_api/graphql/queries/system.py index 82c9260..55537d7 100644 --- a/selfprivacy_api/graphql/queries/system.py +++ b/selfprivacy_api/graphql/queries/system.py @@ -1,8 +1,10 @@ """Common system information and settings""" + # pylint: disable=too-few-public-methods import os import typing import strawberry + from selfprivacy_api.graphql.common_types.dns import DnsRecord from selfprivacy_api.graphql.queries.common import Alert, Severity diff --git a/selfprivacy_api/graphql/queries/users.py b/selfprivacy_api/graphql/queries/users.py index d2c0555..992ce01 100644 --- a/selfprivacy_api/graphql/queries/users.py +++ b/selfprivacy_api/graphql/queries/users.py @@ -1,4 +1,5 @@ """Users""" + # pylint: disable=too-few-public-methods import typing import strawberry From 9c50f8bba75a71abccf9c3064c22eeeb282b8962 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Wed, 12 Jun 2024 17:56:43 +0400 Subject: [PATCH 03/18] fix from review --- selfprivacy_api/services/roundcube/__init__.py | 11 ++++++++--- selfprivacy_api/services/roundcube/icon.py | 17 ++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 4deed57..277292e 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -25,12 +25,12 @@ class Roundcube(Service): @staticmethod def get_display_name() -> str: """Return service display name.""" - return "roundcube" + return "Roundcube" @staticmethod def get_description() -> str: """Return service description.""" - return "Roundcube is a open source webmail software." + return "Roundcube is an open source webmail software." @staticmethod def get_svg_icon() -> str: @@ -41,10 +41,15 @@ class Roundcube(Service): def get_url() -> Optional[str]: """Return service url.""" domain = get_domain() - return f"https://roundcube.{domain}" + subdomain = get_subdomain() + return f"https://{subdomain}.{domain}" @staticmethod def get_subdomain() -> Optional[str]: + with ReadUserData() as data: + if "roundcube" in data["modules"]: + return data["modules"]["roundcube"]["subdomain"] + return "roundcube" @staticmethod diff --git a/selfprivacy_api/services/roundcube/icon.py b/selfprivacy_api/services/roundcube/icon.py index 5fb1288..4a08207 100644 --- a/selfprivacy_api/services/roundcube/icon.py +++ b/selfprivacy_api/services/roundcube/icon.py @@ -1,16 +1,7 @@ ROUNDCUBE_ICON = """ - - - - - - - - + + + + """ From a00c4d426858fa2b5836dbc04be0c8a4062e4f43 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Wed, 12 Jun 2024 18:48:56 +0400 Subject: [PATCH 04/18] fix: change return get_folders --- selfprivacy_api/services/roundcube/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 277292e..8884be5 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -103,7 +103,7 @@ class Roundcube(Service): @staticmethod def get_folders() -> List[str]: - return ["/var/lib/postgresql"] + return [] def move_to_volume(self, volume: BlockDevice) -> Job: raise NotImplementedError("roundcube service is not movable") From 31feeb211d39d4c2ce44aa88036dccbf4c133224 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Thu, 13 Jun 2024 19:48:58 +0400 Subject: [PATCH 05/18] fix: change roundcube to webmail --- selfprivacy_api/services/roundcube/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 8884be5..a2b2300 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -50,7 +50,7 @@ class Roundcube(Service): if "roundcube" in data["modules"]: return data["modules"]["roundcube"]["subdomain"] - return "roundcube" + return "webmail" @staticmethod def is_movable() -> bool: From 4d898f4ee803170ba66eb05e146fac7c814392c8 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 10:39:39 +0400 Subject: [PATCH 06/18] feat: add migration for services flake --- .../migrations/update_services_flake_list.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 selfprivacy_api/migrations/update_services_flake_list.py diff --git a/selfprivacy_api/migrations/update_services_flake_list.py b/selfprivacy_api/migrations/update_services_flake_list.py new file mode 100644 index 0000000..8d3b8e8 --- /dev/null +++ b/selfprivacy_api/migrations/update_services_flake_list.py @@ -0,0 +1,34 @@ +from selfprivacy_api.migrations.migration import Migration +from selfprivacy_api.jobs import JobStatus, Jobs + +from selfprivacy_api.services.flake_service_manager import FlakeServiceManager + +CORRECT_SERVICES_LIST = { + "bitwarden": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden", + "gitea": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea", + "jitsi-meet": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet", + "nextcloud": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/nextcloud", + "ocserv": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/ocserv", + "pleroma": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/pleroma", + "simple-nixos-mailserver": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/simple-nixos-mailserver", + "roundcube": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/roundcube", +} + + +class UpdateServicesFlakeList(Migration): + """Check if all required services are in the flake list""" + + def get_migration_name(self): + return "update_services_flake_list" + + def get_migration_description(self): + return "Check if all required services are in the flake list" + + def is_migration_needed(self): + with FlakeServiceManager: + if not manager.services == CORRECT_SERVICES_LIST: + return True + + def migrate(self): + with FlakeServiceManager: + manager.services = CORRECT_SERVICES_LIST From 78dec5c3478d9fcfebb45018b3eec4f87e0e9719 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 11:59:01 +0400 Subject: [PATCH 07/18] feat: move get_subdomain to parent class --- selfprivacy_api/migrations/update_services_flake_list.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/selfprivacy_api/migrations/update_services_flake_list.py b/selfprivacy_api/migrations/update_services_flake_list.py index 8d3b8e8..6f23903 100644 --- a/selfprivacy_api/migrations/update_services_flake_list.py +++ b/selfprivacy_api/migrations/update_services_flake_list.py @@ -25,10 +25,13 @@ class UpdateServicesFlakeList(Migration): return "Check if all required services are in the flake list" def is_migration_needed(self): - with FlakeServiceManager: - if not manager.services == CORRECT_SERVICES_LIST: + # this do not delete custom links for testing + for key, value in manager.services.items(): + if key not in CORRECT_SERVICES_LIST: return True def migrate(self): with FlakeServiceManager: - manager.services = CORRECT_SERVICES_LIST + for key, value in CORRECT_SERVICES_LIST.items(): + if key not in manager.services: + manager.services[key] = value From 2b9b81890bb19e88d75d7e368a06a68f31c30630 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 12:00:09 +0400 Subject: [PATCH 08/18] feat: move get_subdomain to parent class really --- selfprivacy_api/services/roundcube/__init__.py | 8 -------- selfprivacy_api/services/service.py | 8 +++++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index a2b2300..61a23ea 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -44,14 +44,6 @@ class Roundcube(Service): subdomain = get_subdomain() return f"https://{subdomain}.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - with ReadUserData() as data: - if "roundcube" in data["modules"]: - return data["modules"]["roundcube"]["subdomain"] - - return "webmail" - @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index 64a1e80..262d690 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -1,4 +1,5 @@ """Abstract class for a service running on a server""" + from abc import ABC, abstractmethod from typing import List, Optional @@ -73,13 +74,14 @@ class Service(ABC): """ pass - @staticmethod - @abstractmethod def get_subdomain() -> Optional[str]: """ The assigned primary subdomain for this service. """ - pass + with ReadUserData() as data: + if self.get_display_name() in data["modules"]: + if "subdomain" in data["modules"][self.get_display_name()]: + return data["modules"][self.get_display_name()]["subdomain"] @classmethod def get_user(cls) -> Optional[str]: From 9125d03b352a730eda2d0c2c469a690eef5b158e Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 12:05:58 +0400 Subject: [PATCH 09/18] fix: remove get sub domain from services --- selfprivacy_api/services/bitwarden/__init__.py | 5 +---- selfprivacy_api/services/gitea/__init__.py | 5 +---- selfprivacy_api/services/jitsimeet/__init__.py | 5 +---- selfprivacy_api/services/nextcloud/__init__.py | 5 +---- selfprivacy_api/services/ocserv/__init__.py | 5 +---- selfprivacy_api/services/pleroma/__init__.py | 5 +---- selfprivacy_api/services/test_service/__init__.py | 5 +---- 7 files changed, 7 insertions(+), 28 deletions(-) diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index 52f1466..6c44aeb 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -1,4 +1,5 @@ """Class representing Bitwarden service""" + import base64 import subprocess from typing import Optional, List @@ -43,10 +44,6 @@ class Bitwarden(Service): domain = get_domain() return f"https://password.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - return "password" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/gitea/__init__.py b/selfprivacy_api/services/gitea/__init__.py index 311d59e..7029b48 100644 --- a/selfprivacy_api/services/gitea/__init__.py +++ b/selfprivacy_api/services/gitea/__init__.py @@ -1,4 +1,5 @@ """Class representing Bitwarden service""" + import base64 import subprocess from typing import Optional, List @@ -39,10 +40,6 @@ class Gitea(Service): domain = get_domain() return f"https://git.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - return "git" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 53d572c..05ef2f7 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -1,4 +1,5 @@ """Class representing Jitsi Meet service""" + import base64 import subprocess from typing import Optional, List @@ -42,10 +43,6 @@ class JitsiMeet(Service): domain = get_domain() return f"https://meet.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - return "meet" - @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index 3e5b8d3..6aee771 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -1,4 +1,5 @@ """Class representing Nextcloud service.""" + import base64 import subprocess from typing import Optional, List @@ -41,10 +42,6 @@ class Nextcloud(Service): domain = get_domain() return f"https://cloud.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - return "cloud" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/ocserv/__init__.py b/selfprivacy_api/services/ocserv/__init__.py index 4dd802f..e21fe6e 100644 --- a/selfprivacy_api/services/ocserv/__init__.py +++ b/selfprivacy_api/services/ocserv/__init__.py @@ -1,4 +1,5 @@ """Class representing ocserv service.""" + import base64 import subprocess import typing @@ -33,10 +34,6 @@ class Ocserv(Service): """Return service url.""" return None - @staticmethod - def get_subdomain() -> typing.Optional[str]: - return "vpn" - @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/pleroma/__init__.py b/selfprivacy_api/services/pleroma/__init__.py index 44a9be8..eebd925 100644 --- a/selfprivacy_api/services/pleroma/__init__.py +++ b/selfprivacy_api/services/pleroma/__init__.py @@ -1,4 +1,5 @@ """Class representing Nextcloud service.""" + import base64 import subprocess from typing import Optional, List @@ -37,10 +38,6 @@ class Pleroma(Service): domain = get_domain() return f"https://social.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: - return "social" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/test_service/__init__.py b/selfprivacy_api/services/test_service/__init__.py index caf4666..2058d57 100644 --- a/selfprivacy_api/services/test_service/__init__.py +++ b/selfprivacy_api/services/test_service/__init__.py @@ -1,4 +1,5 @@ """Class representing Bitwarden service""" + import base64 import typing import subprocess @@ -63,10 +64,6 @@ class DummyService(Service): domain = "test.com" return f"https://password.{domain}" - @staticmethod - def get_subdomain() -> typing.Optional[str]: - return "password" - @classmethod def is_movable(cls) -> bool: return cls.movable From 7b9420c244b5fd72c48500971a1e730066fe6d53 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 12:35:59 +0400 Subject: [PATCH 10/18] feat: rewrite get_url() --- selfprivacy_api/services/bitwarden/__init__.py | 8 -------- selfprivacy_api/services/gitea/__init__.py | 8 -------- selfprivacy_api/services/jitsimeet/__init__.py | 7 ------- selfprivacy_api/services/nextcloud/__init__.py | 7 ------- selfprivacy_api/services/pleroma/__init__.py | 8 -------- selfprivacy_api/services/roundcube/__init__.py | 8 -------- selfprivacy_api/services/service.py | 7 ++++--- 7 files changed, 4 insertions(+), 49 deletions(-) diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index 6c44aeb..5d27569 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -4,8 +4,6 @@ import base64 import subprocess from typing import Optional, List -from selfprivacy_api.utils import get_domain - 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 @@ -38,12 +36,6 @@ class Bitwarden(Service): def get_user() -> str: return "vaultwarden" - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - return f"https://password.{domain}" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/gitea/__init__.py b/selfprivacy_api/services/gitea/__init__.py index 7029b48..3247040 100644 --- a/selfprivacy_api/services/gitea/__init__.py +++ b/selfprivacy_api/services/gitea/__init__.py @@ -4,8 +4,6 @@ import base64 import subprocess from typing import Optional, List -from selfprivacy_api.utils import get_domain - from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.services.gitea.icon import GITEA_ICON @@ -34,12 +32,6 @@ class Gitea(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(GITEA_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - return f"https://git.{domain}" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 05ef2f7..074c546 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -9,7 +9,6 @@ from selfprivacy_api.utils.systemd import ( get_service_status_from_several_units, ) from selfprivacy_api.services.service import Service, ServiceStatus -from selfprivacy_api.utils import get_domain from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.jitsimeet.icon import JITSI_ICON @@ -37,12 +36,6 @@ class JitsiMeet(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(JITSI_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - return f"https://meet.{domain}" - @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index 6aee771..eee9fa7 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -4,7 +4,6 @@ import base64 import subprocess from typing import Optional, List -from selfprivacy_api.utils import get_domain from selfprivacy_api.jobs import Job, Jobs from selfprivacy_api.utils.systemd import get_service_status @@ -36,12 +35,6 @@ class Nextcloud(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(NEXTCLOUD_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - return f"https://cloud.{domain}" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/pleroma/__init__.py b/selfprivacy_api/services/pleroma/__init__.py index eebd925..16ee70c 100644 --- a/selfprivacy_api/services/pleroma/__init__.py +++ b/selfprivacy_api/services/pleroma/__init__.py @@ -4,8 +4,6 @@ import base64 import subprocess from typing import Optional, List -from selfprivacy_api.utils import get_domain - from selfprivacy_api.services.owned_path import OwnedPath from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus @@ -32,12 +30,6 @@ class Pleroma(Service): def get_svg_icon() -> str: return base64.b64encode(PLEROMA_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - return f"https://social.{domain}" - @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 61a23ea..41bef32 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -9,7 +9,6 @@ from selfprivacy_api.utils.systemd import ( get_service_status_from_several_units, ) from selfprivacy_api.services.service import Service, ServiceStatus -from selfprivacy_api.utils import get_domain from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.roundcube.icon import ROUNDCUBE_ICON @@ -37,13 +36,6 @@ class Roundcube(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(ROUNDCUBE_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: - """Return service url.""" - domain = get_domain() - subdomain = get_subdomain() - return f"https://{subdomain}.{domain}" - @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index 262d690..ed55a0e 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -4,6 +4,7 @@ from abc import ABC, abstractmethod from typing import List, Optional from selfprivacy_api import utils +from selfprivacy_api.utils import get_domain from selfprivacy_api.utils import ReadUserData, WriteUserData from selfprivacy_api.utils.waitloop import wait_until_true from selfprivacy_api.utils.block_devices import BlockDevice, BlockDevices @@ -66,13 +67,13 @@ class Service(ABC): """ pass - @staticmethod - @abstractmethod def get_url() -> Optional[str]: """ The url of the service if it is accessible from the internet browser. """ - pass + domain = get_domain() + subdomain = self.get_subdomain() + return f"https://{subdomain}.{domain}" def get_subdomain() -> Optional[str]: """ From 82a0b557e154e6d95ba02c4a44819df9f0ed83ed Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sun, 16 Jun 2024 23:48:25 +0400 Subject: [PATCH 11/18] feat: add migration for userdata --- selfprivacy_api/migrations/update_userdata.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 selfprivacy_api/migrations/update_userdata.py diff --git a/selfprivacy_api/migrations/update_userdata.py b/selfprivacy_api/migrations/update_userdata.py new file mode 100644 index 0000000..9011731 --- /dev/null +++ b/selfprivacy_api/migrations/update_userdata.py @@ -0,0 +1,25 @@ +from selfprivacy_api.migrations.migration import Migration + +from selfprivacy_api.utils import ReadUserData, WriteUserData + + +class UpdateServicesFlakeList(Migration): + """Check if all required services are in the flake list""" + + def get_migration_name(self): + return "update_services_flake_list" + + def get_migration_description(self): + return "Check if all required services are in the flake list" + + def is_migration_needed(self): + with ReadUserData() as data: + if "roundcube" not in data["modules"]: + return True + + def migrate(self): + with WriteUserData() as data: + data["modules"]["roundcube"] = { + "enable": True, + "subdomain": "roundcube", + } From 416a0a8725209da40aa2c4a9b5cbb667532a6396 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Wed, 19 Jun 2024 15:20:31 +0400 Subject: [PATCH 12/18] fix: from review --- .../{update_userdata.py => add_roundcube_to_userdata.py} | 9 ++++----- selfprivacy_api/migrations/update_services_flake_list.py | 1 - selfprivacy_api/services/roundcube/__init__.py | 6 +++++- 3 files changed, 9 insertions(+), 7 deletions(-) rename selfprivacy_api/migrations/{update_userdata.py => add_roundcube_to_userdata.py} (67%) diff --git a/selfprivacy_api/migrations/update_userdata.py b/selfprivacy_api/migrations/add_roundcube_to_userdata.py similarity index 67% rename from selfprivacy_api/migrations/update_userdata.py rename to selfprivacy_api/migrations/add_roundcube_to_userdata.py index 9011731..2c6bafb 100644 --- a/selfprivacy_api/migrations/update_userdata.py +++ b/selfprivacy_api/migrations/add_roundcube_to_userdata.py @@ -3,14 +3,14 @@ from selfprivacy_api.migrations.migration import Migration from selfprivacy_api.utils import ReadUserData, WriteUserData -class UpdateServicesFlakeList(Migration): - """Check if all required services are in the flake list""" +class AddRoundcubeToUserdata(Migration): + """Add Roundcube to userdata.json if it does not exist""" def get_migration_name(self): - return "update_services_flake_list" + return "add_roundcube_to_userdata" def get_migration_description(self): - return "Check if all required services are in the flake list" + return "Add Roundcube to userdata.json if it does not exist" def is_migration_needed(self): with ReadUserData() as data: @@ -20,6 +20,5 @@ class UpdateServicesFlakeList(Migration): def migrate(self): with WriteUserData() as data: data["modules"]["roundcube"] = { - "enable": True, "subdomain": "roundcube", } diff --git a/selfprivacy_api/migrations/update_services_flake_list.py b/selfprivacy_api/migrations/update_services_flake_list.py index 6f23903..02671e8 100644 --- a/selfprivacy_api/migrations/update_services_flake_list.py +++ b/selfprivacy_api/migrations/update_services_flake_list.py @@ -25,7 +25,6 @@ class UpdateServicesFlakeList(Migration): return "Check if all required services are in the flake list" def is_migration_needed(self): - # this do not delete custom links for testing for key, value in manager.services.items(): if key not in CORRECT_SERVICES_LIST: return True diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 41bef32..7572770 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -44,9 +44,13 @@ class Roundcube(Service): def is_required() -> bool: return False + @staticmethod + def can_be_backed_up() -> bool: + return False + @staticmethod def get_backup_description() -> str: - return "Secrets that are used to encrypt the communication." + return "Nothing to backup." @staticmethod def get_status() -> ServiceStatus: From 02bc74f4c4a6cd3227a0cd31d1d08ca1af3b16c2 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Wed, 19 Jun 2024 16:18:21 +0400 Subject: [PATCH 13/18] fix: only roundcube migration, other services removed --- .../migrations/update_services_flake_list.py | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/selfprivacy_api/migrations/update_services_flake_list.py b/selfprivacy_api/migrations/update_services_flake_list.py index 02671e8..88f7307 100644 --- a/selfprivacy_api/migrations/update_services_flake_list.py +++ b/selfprivacy_api/migrations/update_services_flake_list.py @@ -3,17 +3,6 @@ from selfprivacy_api.jobs import JobStatus, Jobs from selfprivacy_api.services.flake_service_manager import FlakeServiceManager -CORRECT_SERVICES_LIST = { - "bitwarden": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden", - "gitea": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea", - "jitsi-meet": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet", - "nextcloud": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/nextcloud", - "ocserv": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/ocserv", - "pleroma": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/pleroma", - "simple-nixos-mailserver": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/simple-nixos-mailserver", - "roundcube": "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/roundcube", -} - class UpdateServicesFlakeList(Migration): """Check if all required services are in the flake list""" @@ -25,12 +14,13 @@ class UpdateServicesFlakeList(Migration): return "Check if all required services are in the flake list" def is_migration_needed(self): - for key, value in manager.services.items(): - if key not in CORRECT_SERVICES_LIST: + with FlakeServiceManager() as manager: + if "roundcube" not in manager.services: return True def migrate(self): - with FlakeServiceManager: - for key, value in CORRECT_SERVICES_LIST.items(): - if key not in manager.services: - manager.services[key] = value + with FlakeServiceManager() as manager: + if "roundcube" not in manager.services: + manager.services[ + "roundcube" + ] = "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/roundcube" From f1cc84b8c83306b07eeafb463a0611c4ac2b2481 Mon Sep 17 00:00:00 2001 From: nhnn Date: Fri, 21 Jun 2024 15:14:43 +0300 Subject: [PATCH 14/18] fix: add migrations to migration list in migrations/__init__.py --- selfprivacy_api/migrations/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selfprivacy_api/migrations/__init__.py b/selfprivacy_api/migrations/__init__.py index 2a2cbaa..badf40a 100644 --- a/selfprivacy_api/migrations/__init__.py +++ b/selfprivacy_api/migrations/__init__.py @@ -14,10 +14,14 @@ from selfprivacy_api.migrations.write_token_to_redis import WriteTokenToRedis from selfprivacy_api.migrations.check_for_system_rebuild_jobs import ( CheckForSystemRebuildJobs, ) +from selfprivacy_api.migrations.update_services_flake_list import UpdateServicesFlakeList +from selfprivacy_api.migrations.add_roundcube_to_userdata import AddRoundcubeToUserdata migrations = [ WriteTokenToRedis(), CheckForSystemRebuildJobs(), + UpdateServicesFlakeList(), + AddRoundcubeToUserdata(), ] From 306b7f898d7e88ae8fb8c1b429a6a15fb2d7f427 Mon Sep 17 00:00:00 2001 From: Inex Code Date: Wed, 26 Jun 2024 14:21:26 +0300 Subject: [PATCH 15/18] Revert "feat: rewrite get_url()" This reverts commit f834c85401073a19b18bcafbda837d82f6e5f383. --- selfprivacy_api/services/bitwarden/__init__.py | 8 ++++++++ selfprivacy_api/services/gitea/__init__.py | 8 ++++++++ selfprivacy_api/services/jitsimeet/__init__.py | 7 +++++++ selfprivacy_api/services/nextcloud/__init__.py | 7 +++++++ selfprivacy_api/services/pleroma/__init__.py | 8 ++++++++ selfprivacy_api/services/roundcube/__init__.py | 8 ++++++++ selfprivacy_api/services/service.py | 7 +++---- 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index 5d27569..6c44aeb 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -4,6 +4,8 @@ import base64 import subprocess from typing import Optional, List +from selfprivacy_api.utils import get_domain + 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 @@ -36,6 +38,12 @@ class Bitwarden(Service): def get_user() -> str: return "vaultwarden" + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://password.{domain}" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/gitea/__init__.py b/selfprivacy_api/services/gitea/__init__.py index 3247040..7029b48 100644 --- a/selfprivacy_api/services/gitea/__init__.py +++ b/selfprivacy_api/services/gitea/__init__.py @@ -4,6 +4,8 @@ import base64 import subprocess from typing import Optional, List +from selfprivacy_api.utils import get_domain + from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus from selfprivacy_api.services.gitea.icon import GITEA_ICON @@ -32,6 +34,12 @@ class Gitea(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(GITEA_ICON.encode("utf-8")).decode("utf-8") + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://git.{domain}" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 074c546..05ef2f7 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -9,6 +9,7 @@ from selfprivacy_api.utils.systemd import ( get_service_status_from_several_units, ) from selfprivacy_api.services.service import Service, ServiceStatus +from selfprivacy_api.utils import get_domain from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.jitsimeet.icon import JITSI_ICON @@ -36,6 +37,12 @@ class JitsiMeet(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(JITSI_ICON.encode("utf-8")).decode("utf-8") + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://meet.{domain}" + @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index eee9fa7..6aee771 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -4,6 +4,7 @@ import base64 import subprocess from typing import Optional, List +from selfprivacy_api.utils import get_domain from selfprivacy_api.jobs import Job, Jobs from selfprivacy_api.utils.systemd import get_service_status @@ -35,6 +36,12 @@ class Nextcloud(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(NEXTCLOUD_ICON.encode("utf-8")).decode("utf-8") + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://cloud.{domain}" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/pleroma/__init__.py b/selfprivacy_api/services/pleroma/__init__.py index 16ee70c..eebd925 100644 --- a/selfprivacy_api/services/pleroma/__init__.py +++ b/selfprivacy_api/services/pleroma/__init__.py @@ -4,6 +4,8 @@ import base64 import subprocess from typing import Optional, List +from selfprivacy_api.utils import get_domain + from selfprivacy_api.services.owned_path import OwnedPath from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus @@ -30,6 +32,12 @@ class Pleroma(Service): def get_svg_icon() -> str: return base64.b64encode(PLEROMA_ICON.encode("utf-8")).decode("utf-8") + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + return f"https://social.{domain}" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 7572770..9a52c3a 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -9,6 +9,7 @@ from selfprivacy_api.utils.systemd import ( get_service_status_from_several_units, ) from selfprivacy_api.services.service import Service, ServiceStatus +from selfprivacy_api.utils import get_domain from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.roundcube.icon import ROUNDCUBE_ICON @@ -36,6 +37,13 @@ class Roundcube(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(ROUNDCUBE_ICON.encode("utf-8")).decode("utf-8") + @staticmethod + def get_url() -> Optional[str]: + """Return service url.""" + domain = get_domain() + subdomain = get_subdomain() + return f"https://{subdomain}.{domain}" + @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index ed55a0e..262d690 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -4,7 +4,6 @@ from abc import ABC, abstractmethod from typing import List, Optional from selfprivacy_api import utils -from selfprivacy_api.utils import get_domain from selfprivacy_api.utils import ReadUserData, WriteUserData from selfprivacy_api.utils.waitloop import wait_until_true from selfprivacy_api.utils.block_devices import BlockDevice, BlockDevices @@ -67,13 +66,13 @@ class Service(ABC): """ pass + @staticmethod + @abstractmethod def get_url() -> Optional[str]: """ The url of the service if it is accessible from the internet browser. """ - domain = get_domain() - subdomain = self.get_subdomain() - return f"https://{subdomain}.{domain}" + pass def get_subdomain() -> Optional[str]: """ From 8bb916628719c1ace839898fb31241609ee05eea Mon Sep 17 00:00:00 2001 From: Inex Code Date: Wed, 26 Jun 2024 14:21:49 +0300 Subject: [PATCH 16/18] Revert "fix: remove get sub domain from services" This reverts commit 46fd7a237c6c1f8be0946313f45deac61a7d2a67. --- selfprivacy_api/services/bitwarden/__init__.py | 5 ++++- selfprivacy_api/services/gitea/__init__.py | 5 ++++- selfprivacy_api/services/jitsimeet/__init__.py | 5 ++++- selfprivacy_api/services/nextcloud/__init__.py | 5 ++++- selfprivacy_api/services/ocserv/__init__.py | 5 ++++- selfprivacy_api/services/pleroma/__init__.py | 5 ++++- selfprivacy_api/services/test_service/__init__.py | 5 ++++- 7 files changed, 28 insertions(+), 7 deletions(-) diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index 6c44aeb..52f1466 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -1,5 +1,4 @@ """Class representing Bitwarden service""" - import base64 import subprocess from typing import Optional, List @@ -44,6 +43,10 @@ class Bitwarden(Service): domain = get_domain() return f"https://password.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + return "password" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/gitea/__init__.py b/selfprivacy_api/services/gitea/__init__.py index 7029b48..311d59e 100644 --- a/selfprivacy_api/services/gitea/__init__.py +++ b/selfprivacy_api/services/gitea/__init__.py @@ -1,5 +1,4 @@ """Class representing Bitwarden service""" - import base64 import subprocess from typing import Optional, List @@ -40,6 +39,10 @@ class Gitea(Service): domain = get_domain() return f"https://git.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + return "git" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 05ef2f7..53d572c 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -1,5 +1,4 @@ """Class representing Jitsi Meet service""" - import base64 import subprocess from typing import Optional, List @@ -43,6 +42,10 @@ class JitsiMeet(Service): domain = get_domain() return f"https://meet.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + return "meet" + @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index 6aee771..3e5b8d3 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -1,5 +1,4 @@ """Class representing Nextcloud service.""" - import base64 import subprocess from typing import Optional, List @@ -42,6 +41,10 @@ class Nextcloud(Service): domain = get_domain() return f"https://cloud.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + return "cloud" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/ocserv/__init__.py b/selfprivacy_api/services/ocserv/__init__.py index e21fe6e..4dd802f 100644 --- a/selfprivacy_api/services/ocserv/__init__.py +++ b/selfprivacy_api/services/ocserv/__init__.py @@ -1,5 +1,4 @@ """Class representing ocserv service.""" - import base64 import subprocess import typing @@ -34,6 +33,10 @@ class Ocserv(Service): """Return service url.""" return None + @staticmethod + def get_subdomain() -> typing.Optional[str]: + return "vpn" + @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/pleroma/__init__.py b/selfprivacy_api/services/pleroma/__init__.py index eebd925..44a9be8 100644 --- a/selfprivacy_api/services/pleroma/__init__.py +++ b/selfprivacy_api/services/pleroma/__init__.py @@ -1,5 +1,4 @@ """Class representing Nextcloud service.""" - import base64 import subprocess from typing import Optional, List @@ -38,6 +37,10 @@ class Pleroma(Service): domain = get_domain() return f"https://social.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + return "social" + @staticmethod def is_movable() -> bool: return True diff --git a/selfprivacy_api/services/test_service/__init__.py b/selfprivacy_api/services/test_service/__init__.py index 2058d57..caf4666 100644 --- a/selfprivacy_api/services/test_service/__init__.py +++ b/selfprivacy_api/services/test_service/__init__.py @@ -1,5 +1,4 @@ """Class representing Bitwarden service""" - import base64 import typing import subprocess @@ -64,6 +63,10 @@ class DummyService(Service): domain = "test.com" return f"https://password.{domain}" + @staticmethod + def get_subdomain() -> typing.Optional[str]: + return "password" + @classmethod def is_movable(cls) -> bool: return cls.movable From c42e2ef3ac068e597378e0788b4a2e3d1b496ecf Mon Sep 17 00:00:00 2001 From: Inex Code Date: Wed, 26 Jun 2024 14:21:58 +0300 Subject: [PATCH 17/18] Revert "feat: move get_subdomain to parent class really" This reverts commit 4eaefc832113563441528f8fc8011d6959926e30. --- selfprivacy_api/services/roundcube/__init__.py | 8 ++++++++ selfprivacy_api/services/service.py | 8 +++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index 9a52c3a..b61282b 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -44,6 +44,14 @@ class Roundcube(Service): subdomain = get_subdomain() return f"https://{subdomain}.{domain}" + @staticmethod + def get_subdomain() -> Optional[str]: + with ReadUserData() as data: + if "roundcube" in data["modules"]: + return data["modules"]["roundcube"]["subdomain"] + + return "webmail" + @staticmethod def is_movable() -> bool: return False diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index 262d690..64a1e80 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -1,5 +1,4 @@ """Abstract class for a service running on a server""" - from abc import ABC, abstractmethod from typing import List, Optional @@ -74,14 +73,13 @@ class Service(ABC): """ pass + @staticmethod + @abstractmethod def get_subdomain() -> Optional[str]: """ The assigned primary subdomain for this service. """ - with ReadUserData() as data: - if self.get_display_name() in data["modules"]: - if "subdomain" in data["modules"][self.get_display_name()]: - return data["modules"][self.get_display_name()]["subdomain"] + pass @classmethod def get_user(cls) -> Optional[str]: From 6e0bf4f2a34b9ce55692404d374d4ea1d333bb14 Mon Sep 17 00:00:00 2001 From: Inex Code Date: Wed, 26 Jun 2024 15:00:51 +0300 Subject: [PATCH 18/18] chore: PR cleanup --- selfprivacy_api/migrations/__init__.py | 6 ++-- selfprivacy_api/migrations/add_roundcube.py | 36 +++++++++++++++++++ .../migrations/add_roundcube_to_userdata.py | 24 ------------- .../check_for_system_rebuild_jobs.py | 9 ++--- selfprivacy_api/migrations/migration.py | 8 ++--- .../migrations/update_services_flake_list.py | 26 -------------- .../migrations/write_token_to_redis.py | 9 ++--- .../services/bitwarden/__init__.py | 8 ++--- .../services/flake_service_manager.py | 6 ++-- selfprivacy_api/services/gitea/__init__.py | 8 ++--- .../services/jitsimeet/__init__.py | 8 ++--- .../services/mailserver/__init__.py | 8 ++--- .../services/nextcloud/__init__.py | 9 +++-- selfprivacy_api/services/ocserv/__init__.py | 8 ++--- selfprivacy_api/services/pleroma/__init__.py | 8 ++--- .../services/roundcube/__init__.py | 16 ++++----- selfprivacy_api/services/service.py | 8 ++--- .../services/test_service/__init__.py | 8 ++--- tests/data/turned_on.json | 3 ++ tests/test_flake_services_manager.py | 28 +++++++-------- .../no_services.nix | 4 +-- .../some_services.nix | 10 +++--- 22 files changed, 123 insertions(+), 135 deletions(-) create mode 100644 selfprivacy_api/migrations/add_roundcube.py delete mode 100644 selfprivacy_api/migrations/add_roundcube_to_userdata.py delete mode 100644 selfprivacy_api/migrations/update_services_flake_list.py diff --git a/selfprivacy_api/migrations/__init__.py b/selfprivacy_api/migrations/__init__.py index badf40a..c7f660d 100644 --- a/selfprivacy_api/migrations/__init__.py +++ b/selfprivacy_api/migrations/__init__.py @@ -14,14 +14,12 @@ from selfprivacy_api.migrations.write_token_to_redis import WriteTokenToRedis from selfprivacy_api.migrations.check_for_system_rebuild_jobs import ( CheckForSystemRebuildJobs, ) -from selfprivacy_api.migrations.update_services_flake_list import UpdateServicesFlakeList -from selfprivacy_api.migrations.add_roundcube_to_userdata import AddRoundcubeToUserdata +from selfprivacy_api.migrations.add_roundcube import AddRoundcube migrations = [ WriteTokenToRedis(), CheckForSystemRebuildJobs(), - UpdateServicesFlakeList(), - AddRoundcubeToUserdata(), + AddRoundcube(), ] diff --git a/selfprivacy_api/migrations/add_roundcube.py b/selfprivacy_api/migrations/add_roundcube.py new file mode 100644 index 0000000..3c422c2 --- /dev/null +++ b/selfprivacy_api/migrations/add_roundcube.py @@ -0,0 +1,36 @@ +from selfprivacy_api.migrations.migration import Migration + +from selfprivacy_api.services.flake_service_manager import FlakeServiceManager +from selfprivacy_api.utils import ReadUserData, WriteUserData + + +class AddRoundcube(Migration): + """Adds the Roundcube if it is not present.""" + + def get_migration_name(self) -> str: + return "add_roundcube" + + def get_migration_description(self) -> str: + return "Adds the Roundcube if it is not present." + + def is_migration_needed(self) -> bool: + with FlakeServiceManager() as manager: + if "roundcube" not in manager.services: + return True + with ReadUserData() as data: + if "roundcube" not in data["modules"]: + return True + return False + + def migrate(self) -> None: + with FlakeServiceManager() as manager: + if "roundcube" not in manager.services: + manager.services[ + "roundcube" + ] = "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/roundcube" + with WriteUserData() as data: + if "roundcube" not in data["modules"]: + data["modules"]["roundcube"] = { + "enable": False, + "subdomain": "roundcube", + } diff --git a/selfprivacy_api/migrations/add_roundcube_to_userdata.py b/selfprivacy_api/migrations/add_roundcube_to_userdata.py deleted file mode 100644 index 2c6bafb..0000000 --- a/selfprivacy_api/migrations/add_roundcube_to_userdata.py +++ /dev/null @@ -1,24 +0,0 @@ -from selfprivacy_api.migrations.migration import Migration - -from selfprivacy_api.utils import ReadUserData, WriteUserData - - -class AddRoundcubeToUserdata(Migration): - """Add Roundcube to userdata.json if it does not exist""" - - def get_migration_name(self): - return "add_roundcube_to_userdata" - - def get_migration_description(self): - return "Add Roundcube to userdata.json if it does not exist" - - def is_migration_needed(self): - with ReadUserData() as data: - if "roundcube" not in data["modules"]: - return True - - def migrate(self): - with WriteUserData() as data: - data["modules"]["roundcube"] = { - "subdomain": "roundcube", - } diff --git a/selfprivacy_api/migrations/check_for_system_rebuild_jobs.py b/selfprivacy_api/migrations/check_for_system_rebuild_jobs.py index 9bbac8a..bb8eb74 100644 --- a/selfprivacy_api/migrations/check_for_system_rebuild_jobs.py +++ b/selfprivacy_api/migrations/check_for_system_rebuild_jobs.py @@ -5,13 +5,13 @@ from selfprivacy_api.jobs import JobStatus, Jobs class CheckForSystemRebuildJobs(Migration): """Check if there are unfinished system rebuild jobs and finish them""" - def get_migration_name(self): + def get_migration_name(self) -> str: return "check_for_system_rebuild_jobs" - def get_migration_description(self): + def get_migration_description(self) -> str: return "Check if there are unfinished system rebuild jobs and finish them" - def is_migration_needed(self): + def is_migration_needed(self) -> bool: # Check if there are any unfinished system rebuild jobs for job in Jobs.get_jobs(): if ( @@ -25,8 +25,9 @@ class CheckForSystemRebuildJobs(Migration): JobStatus.RUNNING, ]: return True + return False - def migrate(self): + def migrate(self) -> None: # As the API is restarted, we assume that the jobs are finished for job in Jobs.get_jobs(): if ( diff --git a/selfprivacy_api/migrations/migration.py b/selfprivacy_api/migrations/migration.py index 1116672..8eb047d 100644 --- a/selfprivacy_api/migrations/migration.py +++ b/selfprivacy_api/migrations/migration.py @@ -12,17 +12,17 @@ class Migration(ABC): """ @abstractmethod - def get_migration_name(self): + def get_migration_name(self) -> str: pass @abstractmethod - def get_migration_description(self): + def get_migration_description(self) -> str: pass @abstractmethod - def is_migration_needed(self): + def is_migration_needed(self) -> bool: pass @abstractmethod - def migrate(self): + def migrate(self) -> None: pass diff --git a/selfprivacy_api/migrations/update_services_flake_list.py b/selfprivacy_api/migrations/update_services_flake_list.py deleted file mode 100644 index 88f7307..0000000 --- a/selfprivacy_api/migrations/update_services_flake_list.py +++ /dev/null @@ -1,26 +0,0 @@ -from selfprivacy_api.migrations.migration import Migration -from selfprivacy_api.jobs import JobStatus, Jobs - -from selfprivacy_api.services.flake_service_manager import FlakeServiceManager - - -class UpdateServicesFlakeList(Migration): - """Check if all required services are in the flake list""" - - def get_migration_name(self): - return "update_services_flake_list" - - def get_migration_description(self): - return "Check if all required services are in the flake list" - - def is_migration_needed(self): - with FlakeServiceManager() as manager: - if "roundcube" not in manager.services: - return True - - def migrate(self): - with FlakeServiceManager() as manager: - if "roundcube" not in manager.services: - manager.services[ - "roundcube" - ] = "git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/roundcube" diff --git a/selfprivacy_api/migrations/write_token_to_redis.py b/selfprivacy_api/migrations/write_token_to_redis.py index aab4f72..ccf1c04 100644 --- a/selfprivacy_api/migrations/write_token_to_redis.py +++ b/selfprivacy_api/migrations/write_token_to_redis.py @@ -15,10 +15,10 @@ from selfprivacy_api.utils import ReadUserData, UserDataFiles class WriteTokenToRedis(Migration): """Load Json tokens into Redis""" - def get_migration_name(self): + def get_migration_name(self) -> str: return "write_token_to_redis" - def get_migration_description(self): + def get_migration_description(self) -> str: return "Loads the initial token into redis token storage" def is_repo_empty(self, repo: AbstractTokensRepository) -> bool: @@ -38,7 +38,7 @@ class WriteTokenToRedis(Migration): print(e) return None - def is_migration_needed(self): + def is_migration_needed(self) -> bool: try: if self.get_token_from_json() is not None and self.is_repo_empty( RedisTokensRepository() @@ -47,8 +47,9 @@ class WriteTokenToRedis(Migration): except Exception as e: print(e) return False + return False - def migrate(self): + def migrate(self) -> None: # Write info about providers to userdata.json try: token = self.get_token_from_json() diff --git a/selfprivacy_api/services/bitwarden/__init__.py b/selfprivacy_api/services/bitwarden/__init__.py index 52f1466..56ee6e5 100644 --- a/selfprivacy_api/services/bitwarden/__init__.py +++ b/selfprivacy_api/services/bitwarden/__init__.py @@ -37,14 +37,14 @@ class Bitwarden(Service): def get_user() -> str: return "vaultwarden" - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() return f"https://password.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return "password" @staticmethod diff --git a/selfprivacy_api/services/flake_service_manager.py b/selfprivacy_api/services/flake_service_manager.py index 63c2279..8b76e5d 100644 --- a/selfprivacy_api/services/flake_service_manager.py +++ b/selfprivacy_api/services/flake_service_manager.py @@ -34,20 +34,20 @@ class FlakeServiceManager: file.write( """ { - description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc";\n + description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc";\n """ ) for key, value in self.services.items(): file.write( f""" - inputs.{key}.url = {value}; + inputs.{key}.url = {value}; """ ) file.write( """ - outputs = _: { }; + outputs = _: { }; } """ ) diff --git a/selfprivacy_api/services/gitea/__init__.py b/selfprivacy_api/services/gitea/__init__.py index 311d59e..88df4ed 100644 --- a/selfprivacy_api/services/gitea/__init__.py +++ b/selfprivacy_api/services/gitea/__init__.py @@ -33,14 +33,14 @@ class Gitea(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(GITEA_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() return f"https://git.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return "git" @staticmethod diff --git a/selfprivacy_api/services/jitsimeet/__init__.py b/selfprivacy_api/services/jitsimeet/__init__.py index 53d572c..27a497a 100644 --- a/selfprivacy_api/services/jitsimeet/__init__.py +++ b/selfprivacy_api/services/jitsimeet/__init__.py @@ -36,14 +36,14 @@ class JitsiMeet(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(JITSI_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() return f"https://meet.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return "meet" @staticmethod diff --git a/selfprivacy_api/services/mailserver/__init__.py b/selfprivacy_api/services/mailserver/__init__.py index d2e9b5d..aba302d 100644 --- a/selfprivacy_api/services/mailserver/__init__.py +++ b/selfprivacy_api/services/mailserver/__init__.py @@ -35,13 +35,13 @@ class MailServer(Service): def get_user() -> str: return "virtualMail" - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" return None - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return None @staticmethod diff --git a/selfprivacy_api/services/nextcloud/__init__.py b/selfprivacy_api/services/nextcloud/__init__.py index 3e5b8d3..275b11d 100644 --- a/selfprivacy_api/services/nextcloud/__init__.py +++ b/selfprivacy_api/services/nextcloud/__init__.py @@ -4,7 +4,6 @@ import subprocess from typing import Optional, List from selfprivacy_api.utils import get_domain -from selfprivacy_api.jobs import Job, Jobs from selfprivacy_api.utils.systemd import get_service_status from selfprivacy_api.services.service import Service, ServiceStatus @@ -35,14 +34,14 @@ class Nextcloud(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(NEXTCLOUD_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() return f"https://cloud.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return "cloud" @staticmethod diff --git a/selfprivacy_api/services/ocserv/__init__.py b/selfprivacy_api/services/ocserv/__init__.py index 4dd802f..f600772 100644 --- a/selfprivacy_api/services/ocserv/__init__.py +++ b/selfprivacy_api/services/ocserv/__init__.py @@ -28,13 +28,13 @@ class Ocserv(Service): def get_svg_icon() -> str: return base64.b64encode(OCSERV_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> typing.Optional[str]: + @classmethod + def get_url(cls) -> typing.Optional[str]: """Return service url.""" return None - @staticmethod - def get_subdomain() -> typing.Optional[str]: + @classmethod + def get_subdomain(cls) -> typing.Optional[str]: return "vpn" @staticmethod diff --git a/selfprivacy_api/services/pleroma/__init__.py b/selfprivacy_api/services/pleroma/__init__.py index 44a9be8..64edd96 100644 --- a/selfprivacy_api/services/pleroma/__init__.py +++ b/selfprivacy_api/services/pleroma/__init__.py @@ -31,14 +31,14 @@ class Pleroma(Service): def get_svg_icon() -> str: return base64.b64encode(PLEROMA_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() return f"https://social.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: return "social" @staticmethod diff --git a/selfprivacy_api/services/roundcube/__init__.py b/selfprivacy_api/services/roundcube/__init__.py index b61282b..22604f5 100644 --- a/selfprivacy_api/services/roundcube/__init__.py +++ b/selfprivacy_api/services/roundcube/__init__.py @@ -2,14 +2,14 @@ import base64 import subprocess -from typing import Optional, List +from typing import List, Optional from selfprivacy_api.jobs import Job from selfprivacy_api.utils.systemd import ( get_service_status_from_several_units, ) from selfprivacy_api.services.service import Service, ServiceStatus -from selfprivacy_api.utils import get_domain +from selfprivacy_api.utils import ReadUserData, get_domain from selfprivacy_api.utils.block_devices import BlockDevice from selfprivacy_api.services.roundcube.icon import ROUNDCUBE_ICON @@ -37,20 +37,20 @@ class Roundcube(Service): """Read SVG icon from file and return it as base64 encoded string.""" return base64.b64encode(ROUNDCUBE_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> Optional[str]: + @classmethod + def get_url(cls) -> Optional[str]: """Return service url.""" domain = get_domain() - subdomain = get_subdomain() + subdomain = cls.get_subdomain() return f"https://{subdomain}.{domain}" - @staticmethod - def get_subdomain() -> Optional[str]: + @classmethod + def get_subdomain(cls) -> Optional[str]: with ReadUserData() as data: if "roundcube" in data["modules"]: return data["modules"]["roundcube"]["subdomain"] - return "webmail" + return "roundcube" @staticmethod def is_movable() -> bool: diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index 64a1e80..6e3decf 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -65,17 +65,17 @@ class Service(ABC): """ pass - @staticmethod + @classmethod @abstractmethod - def get_url() -> Optional[str]: + def get_url(cls) -> Optional[str]: """ The url of the service if it is accessible from the internet browser. """ pass - @staticmethod + @classmethod @abstractmethod - def get_subdomain() -> Optional[str]: + def get_subdomain(cls) -> Optional[str]: """ The assigned primary subdomain for this service. """ diff --git a/selfprivacy_api/services/test_service/__init__.py b/selfprivacy_api/services/test_service/__init__.py index caf4666..de3c493 100644 --- a/selfprivacy_api/services/test_service/__init__.py +++ b/selfprivacy_api/services/test_service/__init__.py @@ -57,14 +57,14 @@ class DummyService(Service): # return "" return base64.b64encode(BITWARDEN_ICON.encode("utf-8")).decode("utf-8") - @staticmethod - def get_url() -> typing.Optional[str]: + @classmethod + def get_url(cls) -> typing.Optional[str]: """Return service url.""" domain = "test.com" return f"https://password.{domain}" - @staticmethod - def get_subdomain() -> typing.Optional[str]: + @classmethod + def get_subdomain(cls) -> typing.Optional[str]: return "password" @classmethod diff --git a/tests/data/turned_on.json b/tests/data/turned_on.json index 0bcc2f0..9c285b1 100644 --- a/tests/data/turned_on.json +++ b/tests/data/turned_on.json @@ -62,6 +62,9 @@ "simple-nixos-mailserver": { "enable": true, "location": "sdb" + }, + "roundcube": { + "enable": true } }, "volumes": [ diff --git a/tests/test_flake_services_manager.py b/tests/test_flake_services_manager.py index 4650b6d..93c6e1d 100644 --- a/tests/test_flake_services_manager.py +++ b/tests/test_flake_services_manager.py @@ -4,40 +4,40 @@ from selfprivacy_api.services.flake_service_manager import FlakeServiceManager all_services_file = """ { - description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; + description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; - inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; + inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; - inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; + inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; - inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; + inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; - inputs.nextcloud.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/nextcloud; + inputs.nextcloud.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/nextcloud; - inputs.ocserv.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/ocserv; + inputs.ocserv.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/ocserv; - inputs.pleroma.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/pleroma; + inputs.pleroma.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/pleroma; - inputs.simple-nixos-mailserver.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/simple-nixos-mailserver; + inputs.simple-nixos-mailserver.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/simple-nixos-mailserver; - outputs = _: { }; + outputs = _: { }; } """ some_services_file = """ { - description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; + description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; - inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; + inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; - inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; + inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; - inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; + inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; - outputs = _: { }; + outputs = _: { }; } """ diff --git a/tests/test_flake_services_manager/no_services.nix b/tests/test_flake_services_manager/no_services.nix index 5967016..8588bc7 100644 --- a/tests/test_flake_services_manager/no_services.nix +++ b/tests/test_flake_services_manager/no_services.nix @@ -1,4 +1,4 @@ { - description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; - outputs = _: { }; + description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; + outputs = _: { }; } diff --git a/tests/test_flake_services_manager/some_services.nix b/tests/test_flake_services_manager/some_services.nix index 4bbb919..8c2e6af 100644 --- a/tests/test_flake_services_manager/some_services.nix +++ b/tests/test_flake_services_manager/some_services.nix @@ -1,12 +1,12 @@ { - description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; + description = "SelfPrivacy NixOS PoC modules/extensions/bundles/packages/etc"; - inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; + inputs.bitwarden.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/bitwarden; - inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; + inputs.gitea.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/gitea; - inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; + inputs.jitsi-meet.url = git+https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-config.git?ref=flakes&dir=sp-modules/jitsi-meet; - outputs = _: { }; + outputs = _: { }; }