mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Change stuff
This commit is contained in:
parent
c86504836a
commit
5cce6cfdae
9 changed files with 119 additions and 54 deletions
|
@ -1,24 +1,24 @@
|
|||
# Imports go here!
|
||||
from .api_royalnet_version import ApiRoyalnetVersionStar
|
||||
from .api_login_royalnet import ApiLoginRoyalnetStar
|
||||
from .api_token_info import ApiTokenInfoStar
|
||||
from .api_token_passwd import ApiTokenPasswdStar
|
||||
from .api_token_create import ApiTokenCreateStar
|
||||
from .api_auth_login_royalnet import ApiAuthLoginRoyalnetStar
|
||||
from .api_user_passwd import ApiUserPasswd
|
||||
from .api_auth_token import ApiAuthTokenStar
|
||||
from .api_user_get import ApiUserGetStar
|
||||
from .api_user_list import ApiUserListStar
|
||||
from .api_user_find import ApiUserFindStar
|
||||
from .api_user_create import ApiUserCreateStar
|
||||
from .docs import DocsStar
|
||||
|
||||
# Enter the PageStars of your Pack here!
|
||||
available_page_stars = [
|
||||
ApiRoyalnetVersionStar,
|
||||
ApiLoginRoyalnetStar,
|
||||
ApiTokenInfoStar,
|
||||
ApiTokenPasswdStar,
|
||||
ApiTokenCreateStar,
|
||||
ApiAuthLoginRoyalnetStar,
|
||||
ApiUserPasswd,
|
||||
ApiAuthTokenStar,
|
||||
ApiUserGetStar,
|
||||
ApiUserListStar,
|
||||
ApiUserFindStar,
|
||||
ApiUserCreateStar,
|
||||
DocsStar,
|
||||
]
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ from ..tables.users import User
|
|||
from ..tables.tokens import Token
|
||||
|
||||
|
||||
class ApiLoginRoyalnetStar(ApiStar):
|
||||
path = "/api/login/royalnet/v1"
|
||||
class ApiAuthLoginRoyalnetStar(ApiStar):
|
||||
path = "/api/auth/login/royalnet/v1"
|
||||
|
||||
methods = ["POST"]
|
||||
|
||||
|
@ -18,7 +18,7 @@ class ApiLoginRoyalnetStar(ApiStar):
|
|||
}
|
||||
}
|
||||
|
||||
tags = ["login"]
|
||||
tags = ["auth"]
|
||||
|
||||
async def post(self, data: ApiData) -> ru.JSON:
|
||||
"""Login with a Royalnet account.
|
|
@ -5,18 +5,29 @@ from royalnet.constellation.api import *
|
|||
from ..tables.tokens import Token
|
||||
|
||||
|
||||
class ApiTokenCreateStar(ApiStar):
|
||||
path = "/api/token/create/v1"
|
||||
class ApiAuthTokenStar(ApiStar):
|
||||
path = "/api/auth/token/v1"
|
||||
|
||||
methods = ["POST"]
|
||||
methods = ["GET", "POST"]
|
||||
|
||||
parameters = {
|
||||
"get": {},
|
||||
"post": {
|
||||
"duration": "The duration in seconds of the new token."
|
||||
}
|
||||
}
|
||||
|
||||
tags = ["login"]
|
||||
auth = {
|
||||
"get": True,
|
||||
"post": True,
|
||||
}
|
||||
|
||||
tags = ["auth"]
|
||||
|
||||
async def get(self, data: ApiData) -> ru.JSON:
|
||||
"""Get information about the current login token."""
|
||||
token = await data.token()
|
||||
return token.json()
|
||||
|
||||
async def post(self, data: ApiData) -> ru.JSON:
|
||||
"""Create a new login token for the authenticated user.
|
|
@ -1,13 +0,0 @@
|
|||
import royalnet.utils as ru
|
||||
from royalnet.constellation.api import *
|
||||
|
||||
|
||||
class ApiTokenInfoStar(ApiStar):
|
||||
path = "/api/token/info/v1"
|
||||
|
||||
tags = ["login"]
|
||||
|
||||
async def get(self, data: ApiData) -> ru.JSON:
|
||||
"""Get information about the current login token."""
|
||||
token = await data.token()
|
||||
return token.json()
|
50
royalnet/backpack/stars/api_user_create.py
Normal file
50
royalnet/backpack/stars/api_user_create.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
from typing import *
|
||||
import datetime
|
||||
import royalnet.constellation.api as rca
|
||||
import royalnet.utils as ru
|
||||
import royalnet.backpack.tables as rbt
|
||||
from ..tables import *
|
||||
|
||||
|
||||
class ApiUserCreateStar(rca.ApiStar):
|
||||
path = "/api/user/create/v1"
|
||||
|
||||
methods = ["POST"]
|
||||
|
||||
parameters = {
|
||||
"post": {
|
||||
"username": "The name of the user you are creating.",
|
||||
"password": "The password of the user you are creating.",
|
||||
"email": "(Optional) The email of the user you are creating.",
|
||||
"avatar_url": "(Optional) An URL pointing to the avatar of the user you are creating.",
|
||||
}
|
||||
}
|
||||
|
||||
tags = ["user"]
|
||||
|
||||
async def post(self, data: rca.ApiData) -> ru.JSON:
|
||||
"""Create a new Royalnet account."""
|
||||
UserT = self.alchemy.get(User)
|
||||
|
||||
username = data.str("username")
|
||||
password = data.str("password")
|
||||
email = data.str("email", optional=True)
|
||||
avatar_url = data.str("avatar_url", optional=True)
|
||||
|
||||
# Check if the username is used by an user or an alias
|
||||
user = await User.find(self.alchemy, data.session, username)
|
||||
if user is not None:
|
||||
raise rca.InvalidParameterError("An user with that username or alias already exists.")
|
||||
|
||||
# Create the user
|
||||
user = UserT(
|
||||
username=username,
|
||||
email=email,
|
||||
avatar_url=avatar_url
|
||||
)
|
||||
user.set_password(password)
|
||||
user.add_alias(self.alchemy, username)
|
||||
data.session.add(user)
|
||||
await data.session_commit()
|
||||
|
||||
return user.json()
|
|
@ -6,12 +6,12 @@ from sqlalchemy import and_
|
|||
from ..tables.tokens import Token
|
||||
|
||||
|
||||
class ApiTokenPasswdStar(ApiStar):
|
||||
path = "/api/token/passwd/v1"
|
||||
class ApiUserPasswd(ApiStar):
|
||||
path = "/api/user/passwd/v1"
|
||||
|
||||
methods = ["PUT"]
|
||||
|
||||
tags = ["token"]
|
||||
tags = ["user"]
|
||||
|
||||
parameters = {
|
||||
"put": {
|
||||
|
@ -19,10 +19,16 @@ class ApiTokenPasswdStar(ApiStar):
|
|||
}
|
||||
}
|
||||
|
||||
auth = {
|
||||
"put": True
|
||||
}
|
||||
|
||||
requires_auth = True
|
||||
|
||||
async def put(self, data: ApiData) -> ru.JSON:
|
||||
"""Change the password of the currently logged in user."""
|
||||
"""Change the password of the currently logged in user.
|
||||
|
||||
This method also revokes all the issued tokens for the user."""
|
||||
TokenT = self.alchemy.get(Token)
|
||||
token = await data.token()
|
||||
user = token.user
|
|
@ -42,11 +42,12 @@ class DocsStar(PageStar):
|
|||
<html lang="en">
|
||||
<head>
|
||||
<title>Royalnet Docs</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui.css">
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui-standalone-preset.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.23.4/swagger-ui.css">
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3.23.4/swagger-ui-bundle.js"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3.23.4/swagger-ui-standalone-preset.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="display: none;">{spec}</div>
|
||||
<div id="docs"/>
|
||||
<script>
|
||||
const ui = SwaggerUIBundle({{
|
||||
|
|
|
@ -3,36 +3,36 @@ class ApiError(Exception):
|
|||
|
||||
|
||||
class NotFoundError(ApiError):
|
||||
pass
|
||||
"""404"""
|
||||
|
||||
|
||||
class UnauthorizedError(ApiError):
|
||||
pass
|
||||
"""401"""
|
||||
|
||||
|
||||
class ForbiddenError(ApiError):
|
||||
pass
|
||||
"""403"""
|
||||
|
||||
|
||||
class BadRequestError(ApiError):
|
||||
pass
|
||||
"""400"""
|
||||
|
||||
|
||||
class ParameterError(BadRequestError):
|
||||
pass
|
||||
"""400"""
|
||||
|
||||
|
||||
class MissingParameterError(ParameterError):
|
||||
pass
|
||||
"""400"""
|
||||
|
||||
|
||||
class InvalidParameterError(ParameterError):
|
||||
pass
|
||||
"""400"""
|
||||
|
||||
|
||||
class MethodNotImplementedError(ApiError):
|
||||
pass
|
||||
"""405"""
|
||||
|
||||
|
||||
class UnsupportedError(MethodNotImplementedError):
|
||||
pass
|
||||
"""405"""
|
||||
|
|
|
@ -16,6 +16,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
class ApiStar(PageStar, ABC):
|
||||
parameters: Dict[str, Dict[str, str]] = {}
|
||||
auth: Dict[str, bool] = {}
|
||||
|
||||
tags: List[str] = []
|
||||
|
||||
|
@ -51,7 +52,7 @@ class ApiStar(PageStar, ABC):
|
|||
except ForbiddenError as e:
|
||||
return api_error(e, code=403)
|
||||
except MethodNotImplementedError as e:
|
||||
return api_error(e, code=501)
|
||||
return api_error(e, code=405)
|
||||
except BadRequestError as e:
|
||||
return api_error(e, code=400)
|
||||
except Exception as e:
|
||||
|
@ -63,16 +64,16 @@ class ApiStar(PageStar, ABC):
|
|||
await apidata.session_close()
|
||||
|
||||
async def get(self, data: ApiData) -> ru.JSON:
|
||||
raise MethodNotImplementedError()
|
||||
raise MethodNotImplementedError("GET is not implemented on this ApiStar")
|
||||
|
||||
async def post(self, data: ApiData) -> ru.JSON:
|
||||
raise MethodNotImplementedError()
|
||||
raise MethodNotImplementedError("POST is not implemented on this ApiStar")
|
||||
|
||||
async def put(self, data: ApiData) -> ru.JSON:
|
||||
raise MethodNotImplementedError()
|
||||
raise MethodNotImplementedError("PUT is not implemented on this ApiStar")
|
||||
|
||||
async def delete(self, data: ApiData) -> ru.JSON:
|
||||
raise MethodNotImplementedError()
|
||||
raise MethodNotImplementedError("DELETE is not implemented on this ApiStar")
|
||||
|
||||
def __swagger_for_a_method(self, method: Callable) -> ru.JSON:
|
||||
docstring = method.__doc__ or ""
|
||||
|
@ -85,16 +86,25 @@ class ApiStar(PageStar, ABC):
|
|||
|
||||
return {
|
||||
"operationId": f"{self.__class__.__name__}_{method.__name__}",
|
||||
"summary": ru.strip_tabs(summary) if summary is not None else None,
|
||||
"description": ru.strip_tabs(description) if description is not None else None,
|
||||
"summary": ru.strip_tabs(summary) if summary is not None else "",
|
||||
"description": ru.strip_tabs(description) if description is not None else "",
|
||||
"tags": self.tags,
|
||||
"security": [{"RoyalnetLoginToken": ["logged_in"]}],
|
||||
"security": [{"RoyalnetLoginToken": ["logged_in"]}] if self.auth.get(method.__name__) else [],
|
||||
"parameters": [{
|
||||
"name": parameter_name,
|
||||
"in": "query",
|
||||
"description": ru.strip_tabs(self.parameters[method.__name__][parameter_name]),
|
||||
"type": "string",
|
||||
} for parameter_name in self.parameters.get(method.__name__, [])]
|
||||
"schema": {},
|
||||
} for parameter_name in self.parameters.get(method.__name__, [])],
|
||||
"responses": {
|
||||
"200": {"description": "✅ OK!"},
|
||||
"400": {"description": "⚠️ Missing or invalid parameter."},
|
||||
"401": {"description": "⚠️ Invalid password."},
|
||||
"403": {"description": "⚠️ Missing or invalid token."},
|
||||
"404": {"description": "⚠️ Not found."},
|
||||
"405": {"description": "⚠️ Unsupported method."},
|
||||
"500": {"description": "⛔️ Serverside unhandled exception!"},
|
||||
}
|
||||
}
|
||||
|
||||
def swagger(self) -> ru.JSON:
|
||||
|
|
Loading…
Reference in a new issue