mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Add basic login token creation
This commit is contained in:
parent
353b94f1ba
commit
741b9f50db
11 changed files with 99 additions and 13 deletions
|
@ -1,10 +1,12 @@
|
||||||
# Imports go here!
|
# Imports go here!
|
||||||
from .api_royalnet_version import ApiRoyalnetVersionStar
|
from .api_royalnet_version import ApiRoyalnetVersionStar
|
||||||
|
from .api_royalnet_login import ApiRoyalnetLoginStar
|
||||||
|
|
||||||
|
|
||||||
# Enter the PageStars of your Pack here!
|
# Enter the PageStars of your Pack here!
|
||||||
available_page_stars = [
|
available_page_stars = [
|
||||||
ApiRoyalnetVersionStar,
|
ApiRoyalnetVersionStar,
|
||||||
|
ApiRoyalnetLoginStar,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
32
royalnet/backpack/stars/api_royalnet_login.py
Normal file
32
royalnet/backpack/stars/api_royalnet_login.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import datetime
|
||||||
|
import royalnet.utils as ru
|
||||||
|
from royalnet.constellation.api import *
|
||||||
|
from ..tables.users import User
|
||||||
|
from ..tables.aliases import Alias
|
||||||
|
from ..tables.tokens import Token
|
||||||
|
|
||||||
|
|
||||||
|
class ApiRoyalnetLoginStar(ApiStar):
|
||||||
|
path = "/api/royalnet/login/v1"
|
||||||
|
|
||||||
|
async def api(self, data: ApiDataDict) -> dict:
|
||||||
|
TokenT = self.alchemy.get(Token)
|
||||||
|
UserT = self.alchemy.get(User)
|
||||||
|
AliasT = self.alchemy.get(Alias)
|
||||||
|
|
||||||
|
username = data["username"]
|
||||||
|
password = data["password"]
|
||||||
|
|
||||||
|
async with self.session_acm() as session:
|
||||||
|
user: User = await ru.asyncify(session.query(UserT).filter_by(username=username).one_or_none)
|
||||||
|
if user is None:
|
||||||
|
raise NotFoundException("User not found")
|
||||||
|
pswd_check = user.test_password(password)
|
||||||
|
if not pswd_check:
|
||||||
|
raise ApiError("Invalid password")
|
||||||
|
token: Token = TokenT.generate(user=user, expiration_delta=datetime.timedelta(days=7))
|
||||||
|
session.add(token)
|
||||||
|
await ru.asyncify(session.commit)
|
||||||
|
response = token.json()
|
||||||
|
|
||||||
|
return response
|
|
@ -1,11 +1,11 @@
|
||||||
import royalnet.version as rv
|
import royalnet.version as rv
|
||||||
from royalnet.constellation import ApiStar
|
from royalnet.constellation.api import *
|
||||||
|
|
||||||
|
|
||||||
class ApiRoyalnetVersionStar(ApiStar):
|
class ApiRoyalnetVersionStar(ApiStar):
|
||||||
path = "/api/royalnet/version"
|
path = "/api/royalnet/version/v1"
|
||||||
|
|
||||||
async def api(self, data: dict) -> dict:
|
async def api(self, data: ApiDataDict) -> dict:
|
||||||
return {
|
return {
|
||||||
"semantic": rv.semantic
|
"semantic": rv.semantic
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .telegram import Telegram
|
||||||
from .discord import Discord
|
from .discord import Discord
|
||||||
from .matrix import Matrix
|
from .matrix import Matrix
|
||||||
from .aliases import Alias
|
from .aliases import Alias
|
||||||
|
from .tokens import Token
|
||||||
|
|
||||||
# Enter the tables of your Pack here!
|
# Enter the tables of your Pack here!
|
||||||
available_tables = {
|
available_tables = {
|
||||||
|
@ -11,7 +12,8 @@ available_tables = {
|
||||||
Telegram,
|
Telegram,
|
||||||
Discord,
|
Discord,
|
||||||
Matrix,
|
Matrix,
|
||||||
Alias
|
Alias,
|
||||||
|
Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
import secrets
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import *
|
from sqlalchemy.orm import *
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
@ -26,3 +27,16 @@ class Token:
|
||||||
@property
|
@property
|
||||||
def expired(self):
|
def expired(self):
|
||||||
return datetime.datetime.now() > self.expiration
|
return datetime.datetime.now() > self.expiration
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate(cls, user, expiration_delta: datetime.timedelta):
|
||||||
|
# noinspection PyArgumentList
|
||||||
|
token = cls(user=user, expiration=datetime.datetime.now() + expiration_delta, token=secrets.token_urlsafe())
|
||||||
|
return token
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"user": self.user.json(),
|
||||||
|
"token": self.token,
|
||||||
|
"expiration": self.expiration.isoformat()
|
||||||
|
}
|
||||||
|
|
|
@ -17,15 +17,9 @@ You can install them with: ::
|
||||||
from .constellation import Constellation
|
from .constellation import Constellation
|
||||||
from .star import Star
|
from .star import Star
|
||||||
from .pagestar import PageStar
|
from .pagestar import PageStar
|
||||||
from .apistar import ApiStar
|
|
||||||
from .jsonapi import api_response, api_success, api_error
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Constellation",
|
"Constellation",
|
||||||
"Star",
|
"Star",
|
||||||
"PageStar",
|
"PageStar",
|
||||||
"ApiStar",
|
|
||||||
"api_response",
|
|
||||||
"api_success",
|
|
||||||
"api_error",
|
|
||||||
]
|
]
|
||||||
|
|
16
royalnet/constellation/api/__init__.py
Normal file
16
royalnet/constellation/api/__init__.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from .apistar import ApiStar
|
||||||
|
from .jsonapi import api_response, api_success, api_error
|
||||||
|
from .apidatadict import ApiDataDict
|
||||||
|
from .apierrors import ApiError, MissingParameterException, NotFoundException, UnauthorizedException
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ApiStar",
|
||||||
|
"api_response",
|
||||||
|
"api_success",
|
||||||
|
"api_error",
|
||||||
|
"ApiDataDict",
|
||||||
|
"ApiError",
|
||||||
|
"MissingParameterException",
|
||||||
|
"NotFoundException",
|
||||||
|
]
|
6
royalnet/constellation/api/apidatadict.py
Normal file
6
royalnet/constellation/api/apidatadict.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from .apierrors import MissingParameterException
|
||||||
|
|
||||||
|
|
||||||
|
class ApiDataDict(dict):
|
||||||
|
def __missing__(self, key):
|
||||||
|
raise MissingParameterException(f"Missing '{key}'")
|
14
royalnet/constellation/api/apierrors.py
Normal file
14
royalnet/constellation/api/apierrors.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class ApiError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NotFoundException(ApiError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UnauthorizedException(ApiError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MissingParameterException(ApiError):
|
||||||
|
pass
|
|
@ -3,8 +3,10 @@ from json import JSONDecodeError
|
||||||
from abc import *
|
from abc import *
|
||||||
from starlette.requests import Request
|
from starlette.requests import Request
|
||||||
from starlette.responses import JSONResponse
|
from starlette.responses import JSONResponse
|
||||||
from .pagestar import PageStar
|
from ..pagestar import PageStar
|
||||||
from .jsonapi import api_error, api_success
|
from .jsonapi import api_error, api_success
|
||||||
|
from .apidatadict import ApiDataDict
|
||||||
|
from .apierrors import ApiError, NotFoundException
|
||||||
|
|
||||||
|
|
||||||
class ApiStar(PageStar, ABC):
|
class ApiStar(PageStar, ABC):
|
||||||
|
@ -17,9 +19,13 @@ class ApiStar(PageStar, ABC):
|
||||||
except JSONDecodeError:
|
except JSONDecodeError:
|
||||||
data = {}
|
data = {}
|
||||||
try:
|
try:
|
||||||
response = await self.api(data)
|
response = await self.api(ApiDataDict(data))
|
||||||
|
except NotFoundException as e:
|
||||||
|
return api_error(e, code=404)
|
||||||
|
except ApiError as e:
|
||||||
|
return api_error(e, code=400)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return api_error(e)
|
return api_error(e, code=500)
|
||||||
return api_success(response)
|
return api_success(response)
|
||||||
|
|
||||||
async def api(self, data: dict) -> dict:
|
async def api(self, data: dict) -> dict:
|
Loading…
Reference in a new issue