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! # Imports go here!
from .api_royalnet_version import ApiRoyalnetVersionStar from .api_royalnet_version import ApiRoyalnetVersionStar
from .api_login_royalnet import ApiLoginRoyalnetStar from .api_auth_login_royalnet import ApiAuthLoginRoyalnetStar
from .api_token_info import ApiTokenInfoStar from .api_user_passwd import ApiUserPasswd
from .api_token_passwd import ApiTokenPasswdStar from .api_auth_token import ApiAuthTokenStar
from .api_token_create import ApiTokenCreateStar
from .api_user_get import ApiUserGetStar from .api_user_get import ApiUserGetStar
from .api_user_list import ApiUserListStar from .api_user_list import ApiUserListStar
from .api_user_find import ApiUserFindStar from .api_user_find import ApiUserFindStar
from .api_user_create import ApiUserCreateStar
from .docs import DocsStar from .docs import DocsStar
# Enter the PageStars of your Pack here! # Enter the PageStars of your Pack here!
available_page_stars = [ available_page_stars = [
ApiRoyalnetVersionStar, ApiRoyalnetVersionStar,
ApiLoginRoyalnetStar, ApiAuthLoginRoyalnetStar,
ApiTokenInfoStar, ApiUserPasswd,
ApiTokenPasswdStar, ApiAuthTokenStar,
ApiTokenCreateStar,
ApiUserGetStar, ApiUserGetStar,
ApiUserListStar, ApiUserListStar,
ApiUserFindStar, ApiUserFindStar,
ApiUserCreateStar,
DocsStar, DocsStar,
] ]

View file

@ -6,8 +6,8 @@ from ..tables.users import User
from ..tables.tokens import Token from ..tables.tokens import Token
class ApiLoginRoyalnetStar(ApiStar): class ApiAuthLoginRoyalnetStar(ApiStar):
path = "/api/login/royalnet/v1" path = "/api/auth/login/royalnet/v1"
methods = ["POST"] methods = ["POST"]
@ -18,7 +18,7 @@ class ApiLoginRoyalnetStar(ApiStar):
} }
} }
tags = ["login"] tags = ["auth"]
async def post(self, data: ApiData) -> ru.JSON: async def post(self, data: ApiData) -> ru.JSON:
"""Login with a Royalnet account. """Login with a Royalnet account.

View file

@ -5,18 +5,29 @@ from royalnet.constellation.api import *
from ..tables.tokens import Token from ..tables.tokens import Token
class ApiTokenCreateStar(ApiStar): class ApiAuthTokenStar(ApiStar):
path = "/api/token/create/v1" path = "/api/auth/token/v1"
methods = ["POST"] methods = ["GET", "POST"]
parameters = { parameters = {
"get": {},
"post": { "post": {
"duration": "The duration in seconds of the new token." "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: async def post(self, data: ApiData) -> ru.JSON:
"""Create a new login token for the authenticated user. """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 from ..tables.tokens import Token
class ApiTokenPasswdStar(ApiStar): class ApiUserPasswd(ApiStar):
path = "/api/token/passwd/v1" path = "/api/user/passwd/v1"
methods = ["PUT"] methods = ["PUT"]
tags = ["token"] tags = ["user"]
parameters = { parameters = {
"put": { "put": {
@ -19,10 +19,16 @@ class ApiTokenPasswdStar(ApiStar):
} }
} }
auth = {
"put": True
}
requires_auth = True requires_auth = True
async def put(self, data: ApiData) -> ru.JSON: 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) TokenT = self.alchemy.get(Token)
token = await data.token() token = await data.token()
user = token.user user = token.user

View file

@ -42,11 +42,12 @@ class DocsStar(PageStar):
<html lang="en"> <html lang="en">
<head> <head>
<title>Royalnet Docs</title> <title>Royalnet Docs</title>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui.css"> <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/swagger-ui-bundle.js"></script> <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.12.1/swagger-ui-standalone-preset.js"></script> <script src="https://unpkg.com/swagger-ui-dist@3.23.4/swagger-ui-standalone-preset.js"></script>
</head> </head>
<body> <body>
<div style="display: none;">{spec}</div>
<div id="docs"/> <div id="docs"/>
<script> <script>
const ui = SwaggerUIBundle({{ const ui = SwaggerUIBundle({{

View file

@ -3,36 +3,36 @@ class ApiError(Exception):
class NotFoundError(ApiError): class NotFoundError(ApiError):
pass """404"""
class UnauthorizedError(ApiError): class UnauthorizedError(ApiError):
pass """401"""
class ForbiddenError(ApiError): class ForbiddenError(ApiError):
pass """403"""
class BadRequestError(ApiError): class BadRequestError(ApiError):
pass """400"""
class ParameterError(BadRequestError): class ParameterError(BadRequestError):
pass """400"""
class MissingParameterError(ParameterError): class MissingParameterError(ParameterError):
pass """400"""
class InvalidParameterError(ParameterError): class InvalidParameterError(ParameterError):
pass """400"""
class MethodNotImplementedError(ApiError): class MethodNotImplementedError(ApiError):
pass """405"""
class UnsupportedError(MethodNotImplementedError): class UnsupportedError(MethodNotImplementedError):
pass """405"""

View file

@ -16,6 +16,7 @@ log = logging.getLogger(__name__)
class ApiStar(PageStar, ABC): class ApiStar(PageStar, ABC):
parameters: Dict[str, Dict[str, str]] = {} parameters: Dict[str, Dict[str, str]] = {}
auth: Dict[str, bool] = {}
tags: List[str] = [] tags: List[str] = []
@ -51,7 +52,7 @@ class ApiStar(PageStar, ABC):
except ForbiddenError as e: except ForbiddenError as e:
return api_error(e, code=403) return api_error(e, code=403)
except MethodNotImplementedError as e: except MethodNotImplementedError as e:
return api_error(e, code=501) return api_error(e, code=405)
except BadRequestError as e: except BadRequestError as e:
return api_error(e, code=400) return api_error(e, code=400)
except Exception as e: except Exception as e:
@ -63,16 +64,16 @@ class ApiStar(PageStar, ABC):
await apidata.session_close() await apidata.session_close()
async def get(self, data: ApiData) -> ru.JSON: 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: 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: 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: 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: def __swagger_for_a_method(self, method: Callable) -> ru.JSON:
docstring = method.__doc__ or "" docstring = method.__doc__ or ""
@ -85,16 +86,25 @@ class ApiStar(PageStar, ABC):
return { return {
"operationId": f"{self.__class__.__name__}_{method.__name__}", "operationId": f"{self.__class__.__name__}_{method.__name__}",
"summary": ru.strip_tabs(summary) if summary 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 None, "description": ru.strip_tabs(description) if description is not None else "",
"tags": self.tags, "tags": self.tags,
"security": [{"RoyalnetLoginToken": ["logged_in"]}], "security": [{"RoyalnetLoginToken": ["logged_in"]}] if self.auth.get(method.__name__) else [],
"parameters": [{ "parameters": [{
"name": parameter_name, "name": parameter_name,
"in": "query", "in": "query",
"description": ru.strip_tabs(self.parameters[method.__name__][parameter_name]), "description": ru.strip_tabs(self.parameters[method.__name__][parameter_name]),
"type": "string", "schema": {},
} for parameter_name in self.parameters.get(method.__name__, [])] } 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: def swagger(self) -> ru.JSON: