1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Change stuff

This commit is contained in:
Steffo 2020-06-22 17:01:29 +02:00
parent c86504836a
commit 5cce6cfdae
Signed by: steffo
GPG key ID: 896A80F55F7C97F0
9 changed files with 119 additions and 54 deletions

View file

@ -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,
]

View file

@ -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.

View file

@ -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.

View file

@ -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()

View 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()

View file

@ -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

View file

@ -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({{

View file

@ -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"""

View file

@ -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: