2022-06-24 17:12:32 +00:00
|
|
|
"""GraphQL API for SelfPrivacy."""
|
|
|
|
# pylint: disable=too-few-public-methods
|
2022-08-01 10:40:40 +00:00
|
|
|
|
2022-08-25 17:03:56 +00:00
|
|
|
import asyncio
|
2024-05-22 11:04:37 +00:00
|
|
|
from typing import AsyncGenerator, List
|
2022-06-24 17:12:32 +00:00
|
|
|
import strawberry
|
2024-07-15 12:59:15 +00:00
|
|
|
from strawberry.types import Info
|
2024-05-27 20:21:11 +00:00
|
|
|
|
2022-06-29 17:39:46 +00:00
|
|
|
from selfprivacy_api.graphql import IsAuthenticated
|
2023-06-21 03:46:56 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.deprecated_mutations import (
|
|
|
|
DeprecatedApiMutations,
|
|
|
|
DeprecatedJobMutations,
|
|
|
|
DeprecatedServicesMutations,
|
|
|
|
DeprecatedStorageMutations,
|
|
|
|
DeprecatedSystemMutations,
|
|
|
|
DeprecatedUsersMutations,
|
|
|
|
)
|
2023-07-20 15:25:32 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.api_mutations import ApiMutations
|
2022-08-25 17:03:56 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.job_mutations import JobMutations
|
|
|
|
from selfprivacy_api.graphql.mutations.mutation_interface import GenericMutationReturn
|
|
|
|
from selfprivacy_api.graphql.mutations.services_mutations import ServicesMutations
|
|
|
|
from selfprivacy_api.graphql.mutations.storage_mutations import StorageMutations
|
2022-07-12 13:24:29 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.system_mutations import SystemMutations
|
2023-06-14 09:52:44 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.backup_mutations import BackupMutations
|
2022-06-24 17:12:32 +00:00
|
|
|
|
2022-06-29 17:39:46 +00:00
|
|
|
from selfprivacy_api.graphql.queries.api_queries import Api
|
2023-06-13 21:00:29 +00:00
|
|
|
from selfprivacy_api.graphql.queries.backup import Backup
|
2022-08-25 17:03:56 +00:00
|
|
|
from selfprivacy_api.graphql.queries.jobs import Job
|
2024-05-30 07:05:36 +00:00
|
|
|
from selfprivacy_api.graphql.queries.logs import LogEntry, Logs
|
2022-08-25 17:03:56 +00:00
|
|
|
from selfprivacy_api.graphql.queries.services import Services
|
2022-07-25 14:08:31 +00:00
|
|
|
from selfprivacy_api.graphql.queries.storage import Storage
|
2022-06-24 17:12:32 +00:00
|
|
|
from selfprivacy_api.graphql.queries.system import System
|
|
|
|
|
2024-05-22 11:04:37 +00:00
|
|
|
from selfprivacy_api.graphql.subscriptions.jobs import ApiJob
|
2024-05-27 21:13:57 +00:00
|
|
|
from selfprivacy_api.graphql.subscriptions.jobs import (
|
|
|
|
job_updates as job_update_generator,
|
|
|
|
)
|
2024-05-30 07:05:36 +00:00
|
|
|
from selfprivacy_api.graphql.subscriptions.logs import log_stream
|
2024-05-15 20:43:17 +00:00
|
|
|
|
2023-06-21 03:46:56 +00:00
|
|
|
from selfprivacy_api.graphql.mutations.users_mutations import UsersMutations
|
2022-08-01 10:40:40 +00:00
|
|
|
from selfprivacy_api.graphql.queries.users import Users
|
2022-08-25 17:03:56 +00:00
|
|
|
from selfprivacy_api.jobs.test import test_job
|
2022-08-01 10:40:40 +00:00
|
|
|
|
2022-06-24 17:12:32 +00:00
|
|
|
|
|
|
|
@strawberry.type
|
|
|
|
class Query:
|
|
|
|
"""Root schema for queries"""
|
2022-06-24 18:14:20 +00:00
|
|
|
|
2022-06-24 17:12:32 +00:00
|
|
|
@strawberry.field
|
|
|
|
def api(self) -> Api:
|
|
|
|
"""API access status"""
|
|
|
|
return Api()
|
|
|
|
|
2023-06-21 03:46:56 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def system(self) -> System:
|
|
|
|
"""System queries"""
|
|
|
|
return System()
|
|
|
|
|
2024-05-27 09:59:43 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def logs(self) -> Logs:
|
|
|
|
"""Log queries"""
|
|
|
|
return Logs()
|
|
|
|
|
2022-08-01 10:40:40 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def users(self) -> Users:
|
|
|
|
"""Users queries"""
|
|
|
|
return Users()
|
|
|
|
|
2022-07-25 14:08:31 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def storage(self) -> Storage:
|
|
|
|
"""Storage queries"""
|
|
|
|
return Storage()
|
|
|
|
|
2022-08-25 17:03:56 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def jobs(self) -> Job:
|
|
|
|
"""Jobs queries"""
|
|
|
|
return Job()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def services(self) -> Services:
|
|
|
|
"""Services queries"""
|
|
|
|
return Services()
|
|
|
|
|
2023-06-13 21:00:29 +00:00
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def backup(self) -> Backup:
|
|
|
|
"""Backup queries"""
|
|
|
|
return Backup()
|
|
|
|
|
2022-07-07 13:53:19 +00:00
|
|
|
|
2022-06-29 17:39:46 +00:00
|
|
|
@strawberry.type
|
2022-08-01 10:40:40 +00:00
|
|
|
class Mutation(
|
2023-06-21 03:46:56 +00:00
|
|
|
DeprecatedApiMutations,
|
|
|
|
DeprecatedSystemMutations,
|
|
|
|
DeprecatedUsersMutations,
|
|
|
|
DeprecatedStorageMutations,
|
|
|
|
DeprecatedServicesMutations,
|
|
|
|
DeprecatedJobMutations,
|
2022-08-01 10:40:40 +00:00
|
|
|
):
|
2022-06-29 17:39:46 +00:00
|
|
|
"""Root schema for mutations"""
|
2022-07-07 13:53:19 +00:00
|
|
|
|
2023-06-21 03:46:56 +00:00
|
|
|
@strawberry.field
|
|
|
|
def api(self) -> ApiMutations:
|
|
|
|
"""API mutations"""
|
|
|
|
return ApiMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def system(self) -> SystemMutations:
|
|
|
|
"""System mutations"""
|
|
|
|
return SystemMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def users(self) -> UsersMutations:
|
|
|
|
"""Users mutations"""
|
|
|
|
return UsersMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def storage(self) -> StorageMutations:
|
|
|
|
"""Storage mutations"""
|
|
|
|
return StorageMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def services(self) -> ServicesMutations:
|
|
|
|
"""Services mutations"""
|
|
|
|
return ServicesMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def jobs(self) -> JobMutations:
|
|
|
|
"""Jobs mutations"""
|
|
|
|
return JobMutations()
|
|
|
|
|
|
|
|
@strawberry.field(permission_classes=[IsAuthenticated])
|
|
|
|
def backup(self) -> BackupMutations:
|
|
|
|
"""Backup mutations"""
|
|
|
|
return BackupMutations()
|
|
|
|
|
2022-08-25 17:03:56 +00:00
|
|
|
@strawberry.mutation(permission_classes=[IsAuthenticated])
|
|
|
|
def test_mutation(self) -> GenericMutationReturn:
|
|
|
|
"""Test mutation"""
|
|
|
|
test_job()
|
|
|
|
return GenericMutationReturn(
|
|
|
|
success=True,
|
|
|
|
message="Test mutation",
|
|
|
|
code=200,
|
|
|
|
)
|
|
|
|
|
2022-07-07 13:53:19 +00:00
|
|
|
|
2024-05-27 20:21:11 +00:00
|
|
|
# A cruft for Websockets
|
2024-07-15 12:59:15 +00:00
|
|
|
def authenticated(info: Info) -> bool:
|
2024-05-27 20:21:11 +00:00
|
|
|
return IsAuthenticated().has_permission(source=None, info=info)
|
|
|
|
|
|
|
|
|
2024-07-15 12:59:15 +00:00
|
|
|
def reject_if_unauthenticated(info: Info):
|
2024-05-27 20:38:51 +00:00
|
|
|
if not authenticated(info):
|
|
|
|
raise Exception(IsAuthenticated().message)
|
|
|
|
|
|
|
|
|
2022-08-25 17:03:56 +00:00
|
|
|
@strawberry.type
|
|
|
|
class Subscription:
|
2024-05-27 20:21:11 +00:00
|
|
|
"""Root schema for subscriptions.
|
|
|
|
Every field here should be an AsyncIterator or AsyncGenerator
|
|
|
|
It is not a part of the spec but graphql-core (dep of strawberryql)
|
|
|
|
demands it while the spec is vague in this area."""
|
2022-08-25 17:03:56 +00:00
|
|
|
|
2024-05-22 11:04:37 +00:00
|
|
|
@strawberry.subscription
|
2024-07-15 12:59:15 +00:00
|
|
|
async def job_updates(self, info: Info) -> AsyncGenerator[List[ApiJob], None]:
|
2024-05-27 20:38:51 +00:00
|
|
|
reject_if_unauthenticated(info)
|
2024-05-27 21:13:57 +00:00
|
|
|
return job_update_generator()
|
2024-05-22 11:04:37 +00:00
|
|
|
|
2024-05-15 20:43:17 +00:00
|
|
|
@strawberry.subscription
|
2024-05-27 21:13:57 +00:00
|
|
|
# Used for testing, consider deletion to shrink attack surface
|
2024-07-15 12:59:15 +00:00
|
|
|
async def count(self, info: Info) -> AsyncGenerator[int, None]:
|
2024-05-27 20:38:51 +00:00
|
|
|
reject_if_unauthenticated(info)
|
2024-05-15 20:43:17 +00:00
|
|
|
for i in range(10):
|
2022-08-25 17:03:56 +00:00
|
|
|
yield i
|
|
|
|
await asyncio.sleep(0.5)
|
|
|
|
|
2024-05-30 07:05:36 +00:00
|
|
|
@strawberry.subscription
|
2024-07-15 12:59:15 +00:00
|
|
|
async def log_entries(self, info: Info) -> AsyncGenerator[LogEntry, None]:
|
2024-05-30 07:05:36 +00:00
|
|
|
reject_if_unauthenticated(info)
|
|
|
|
return log_stream()
|
|
|
|
|
2022-08-25 17:03:56 +00:00
|
|
|
|
2023-06-21 03:46:56 +00:00
|
|
|
schema = strawberry.Schema(
|
|
|
|
query=Query,
|
|
|
|
mutation=Mutation,
|
|
|
|
subscription=Subscription,
|
|
|
|
)
|