Add a JSON schema route

This commit is contained in:
luukas 2022-05-18 15:58:54 +03:00
parent 5bff6c12b4
commit 4c64497a2f
4 changed files with 202 additions and 15 deletions

View File

@ -1,4 +1,8 @@
from app.classes.web.routes.api.index_handler import ApiIndexHandler
from app.classes.web.routes.api.jsonschema import (
ApiJsonSchemaHandler,
ApiJsonSchemaListHandler,
)
from app.classes.web.routes.api.not_found import ApiNotFoundHandler
from app.classes.web.routes.api.auth.invalidate_tokens import (
ApiAuthInvalidateTokensHandler,
@ -28,27 +32,63 @@ from app.classes.web.routes.api.users.user.public import ApiUsersUserPublicHandl
def api_handlers(handler_args):
return [
# Auth routes
(r"/api/v2/auth/login/?", ApiAuthLoginHandler, handler_args),
(
r"/api/v2/auth/login/?",
ApiAuthLoginHandler,
handler_args,
),
(
r"/api/v2/auth/invalidate_tokens/?",
ApiAuthInvalidateTokensHandler,
handler_args,
),
# User routes
(r"/api/v2/users/?", ApiUsersIndexHandler, handler_args),
(r"/api/v2/users/([a-z0-9_]+)/?", ApiUsersUserIndexHandler, handler_args),
(r"/api/v2/users/(@me)/?", ApiUsersUserIndexHandler, handler_args),
(r"/api/v2/users/([a-z0-9_]+)/pfp/?", ApiUsersUserPfpHandler, handler_args),
(r"/api/v2/users/(@me)/pfp/?", ApiUsersUserPfpHandler, handler_args),
(
r"/api/v2/users/?",
ApiUsersIndexHandler,
handler_args,
),
(
r"/api/v2/users/([a-z0-9_]+)/?",
ApiUsersUserIndexHandler,
handler_args,
),
(
r"/api/v2/users/(@me)/?",
ApiUsersUserIndexHandler,
handler_args,
),
(
r"/api/v2/users/([a-z0-9_]+)/pfp/?",
ApiUsersUserPfpHandler,
handler_args,
),
(
r"/api/v2/users/(@me)/pfp/?",
ApiUsersUserPfpHandler,
handler_args,
),
(
r"/api/v2/users/([a-z0-9_]+)/public/?",
ApiUsersUserPublicHandler,
handler_args,
),
(r"/api/v2/users/(@me)/public/?", ApiUsersUserPublicHandler, handler_args),
(
r"/api/v2/users/(@me)/public/?",
ApiUsersUserPublicHandler,
handler_args,
),
# Server routes
(r"/api/v2/servers/?", ApiServersIndexHandler, handler_args),
(r"/api/v2/servers/([0-9]+)/?", ApiServersServerIndexHandler, handler_args),
(
r"/api/v2/servers/?",
ApiServersIndexHandler,
handler_args,
),
(
r"/api/v2/servers/([0-9]+)/?",
ApiServersServerIndexHandler,
handler_args,
),
(
r"/api/v2/servers/([0-9]+)/stats/?",
ApiServersServerStatsHandler,
@ -59,7 +99,11 @@ def api_handlers(handler_args):
ApiServersServerActionHandler,
handler_args,
),
(r"/api/v2/servers/([0-9]+)/logs/?", ApiServersServerLogsHandler, handler_args),
(
r"/api/v2/servers/([0-9]+)/logs/?",
ApiServersServerLogsHandler,
handler_args,
),
(
r"/api/v2/servers/([0-9]+)/users/?",
ApiServersServerUsersHandler,
@ -70,8 +114,16 @@ def api_handlers(handler_args):
ApiServersServerPublicHandler,
handler_args,
),
(r"/api/v2/roles/?", ApiRolesIndexHandler, handler_args),
(r"/api/v2/roles/([a-z0-9_]+)/?", ApiRolesRoleIndexHandler, handler_args),
(
r"/api/v2/roles/?",
ApiRolesIndexHandler,
handler_args,
),
(
r"/api/v2/roles/([a-z0-9_]+)/?",
ApiRolesRoleIndexHandler,
handler_args,
),
(
r"/api/v2/roles/([a-z0-9_]+)/servers/?",
ApiRolesRoleServersHandler,
@ -82,6 +134,24 @@ def api_handlers(handler_args):
ApiRolesRoleUsersHandler,
handler_args,
),
(r"/api/v2/?", ApiIndexHandler, handler_args),
(r"/api/v2/(.*)", ApiNotFoundHandler, handler_args),
(
r"/api/v2/jsonschema/?",
ApiJsonSchemaListHandler,
handler_args,
),
(
r"/api/v2/jsonschema/([a-z0-9_]+)/?",
ApiJsonSchemaHandler,
handler_args,
),
(
r"/api/v2/?",
ApiIndexHandler,
handler_args,
),
(
r"/api/v2/(.*)",
ApiNotFoundHandler,
handler_args,
),
]

View File

@ -0,0 +1,107 @@
import typing as t
from app.classes.web.base_api_handler import BaseApiHandler
from app.classes.web.routes.api.auth.login import login_schema
from app.classes.web.routes.api.roles.role.index import modify_role_schema
from app.classes.web.routes.api.roles.index import create_role_schema
from app.classes.web.routes.api.servers.server.index import server_patch_schema
from app.classes.web.routes.api.servers.index import new_server_schema
SCHEMA_LIST: t.Final = [
"login",
"modify_role",
"create_role",
"server_patch",
"new_server",
"user_patch",
"new_user",
]
class ApiJsonSchemaListHandler(BaseApiHandler):
def get(self):
self.finish_json(
200,
{"status": "ok", "data": SCHEMA_LIST},
)
class ApiJsonSchemaHandler(BaseApiHandler):
def get(self, schema_name: str):
if schema_name == "login":
self.finish_json(
200,
{"status": "ok", "data": login_schema},
)
elif schema_name == "modify_role":
self.finish_json(
200,
{"status": "ok", "data": modify_role_schema},
)
elif schema_name == "create_role":
self.finish_json(
200,
{"status": "ok", "data": create_role_schema},
)
elif schema_name == "server_patch":
self.finish_json(200, server_patch_schema)
elif schema_name == "new_server":
self.finish_json(
200,
new_server_schema,
)
elif schema_name == "user_patch":
self.finish_json(
200,
{
"status": "ok",
"data": {
"type": "object",
"properties": {
**self.controller.users.user_jsonschema_props,
},
"anyOf": [
# Require at least one property
{"required": [name]}
for name in [
"username",
"password",
"email",
"enabled",
"lang",
"superuser",
"permissions",
"roles",
"hints",
]
],
"additionalProperties": False,
},
},
)
elif schema_name == "new_user":
self.finish_json(
200,
{
"status": "ok",
"data": {
"type": "object",
"properties": {
**self.controller.users.user_jsonschema_props,
},
"required": ["username", "password"],
"additionalProperties": False,
},
},
)
else:
self.finish_json(
404,
{
"status": "error",
"error": "UNKNOWN_JSON_SCHEMA",
"info": (
f"Unknown JSON schema: {schema_name}."
f" Here's a list of all the valid schema names: {SCHEMA_LIST}"
),
},
)

View File

@ -1,9 +1,18 @@
from typing import Awaitable, Callable, Optional
from app.classes.web.base_api_handler import BaseApiHandler
class ApiNotFoundHandler(BaseApiHandler):
def get(self, page: str):
def _not_found(self, page: str) -> None:
self.finish_json(
404,
{"status": "error", "error": "API_HANDLER_NOT_FOUND", "page": page},
)
head = _not_found # type: Callable[..., Optional[Awaitable[None]]]
get = _not_found # type: Callable[..., Optional[Awaitable[None]]]
post = _not_found # type: Callable[..., Optional[Awaitable[None]]]
delete = _not_found # type: Callable[..., Optional[Awaitable[None]]]
patch = _not_found # type: Callable[..., Optional[Awaitable[None]]]
put = _not_found # type: Callable[..., Optional[Awaitable[None]]]
options = _not_found # type: Callable[..., Optional[Awaitable[None]]]

View File

@ -8,6 +8,7 @@ from app.classes.web.base_api_handler import BaseApiHandler
logger = logging.getLogger(__name__)
# TODO: modify monitoring
server_patch_schema = {
"type": "object",
"properties": {