This repository has been archived by the owner on Jan 20, 2024. It is now read-only.
/
__init__.py
69 lines (62 loc) · 2.31 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from time import time as time_lib
from functools import wraps
from flask import request
from project_amber.db import db
from project_amber.const import MSG_NO_TOKEN, MSG_INVALID_TOKEN, \
MSG_USER_NOT_FOUND, MSG_USER_EXISTS
from project_amber.errors import Unauthorized, BadRequest, NotFound, \
InternalServerError, Conflict
from project_amber.models.auth import User, Session
class LoginUser:
"""
Representational class for request checks. Contains the user name
and ID. The corresponding fields are `name` and `id`, respectively.
Also contains a token field.
"""
def __init__(self, name: str, uid: int, token: str, login_time: int):
self.name = name
self.id = uid
self.token = token
self.login_time = login_time
class RequestParams:
"""
Representational class for request parameters.
"""
def __init__(self):
self.authenticated = False
def middleware() -> RequestParams:
"""
Simple middleware. Checks for invalid request payloads, drops errors
on need, etc.
Returns `True` if a request needs to be authenticated, `False` otherwise.
"""
if not request.is_json and request.method in ["POST", "PUT", "PATCH"]:
raise BadRequest
params = RequestParams()
if not request.path in ["/api/login", "/api/signup"] \
and request.method != "OPTIONS":
params.authenticated = True
return params
def handleLogin() -> LoginUser:
"""
Login handler. Works with Flask's `request`. Returns an object
containing the user's name and their ID. Raises an exception if
the auth token is not valid.
"""
token = request.headers.get("X-Auth-Token")
if token is None:
raise Unauthorized(MSG_NO_TOKEN)
user_session = db.session.query(Session).filter_by(token=token).one_or_none()
if user_session is None:
raise Unauthorized(MSG_INVALID_TOKEN)
user = db.session.query(User).filter_by(id=user_session.user).one_or_none()
if user is None:
raise InternalServerError(MSG_USER_NOT_FOUND)
user_details = LoginUser(user.name, user.id, token, user_session.login_time)
return user_details
def time() -> int:
"""
Wrapper around `time.time()`. Converts the result to `int` to prevent
getting fractions of seconds on some platforms.
"""
return int(time_lib())