crafty-4/app/classes/web/api_handler.py

97 lines
3.0 KiB
Python
Raw Normal View History

2020-09-06 04:13:42 +00:00
import logging
2022-01-15 00:23:50 +00:00
import re
2020-09-06 04:13:42 +00:00
from app.classes.web.base_handler import BaseHandler
2020-09-06 04:13:42 +00:00
2022-03-08 04:40:44 +00:00
logger = logging.getLogger(__name__)
bearer_pattern = re.compile(r"^Bearer", flags=re.IGNORECASE)
2020-09-06 04:13:42 +00:00
class ApiHandler(BaseHandler):
def return_response(self, status: int, data: dict):
# Define a standardized response
self.set_status(status)
2020-09-06 04:13:42 +00:00
self.write(data)
2022-01-15 00:23:50 +00:00
def access_denied(self, user, reason=""):
if reason:
reason = " because " + reason
logger.info(
"User %s from IP %s was denied access to the API route "
+ self.request.path
+ reason,
user,
self.get_remote_ip(),
)
self.finish(
self.return_response(
403,
{
"error": "ACCESS_DENIED",
"info": "You were denied access to the requested resource",
},
)
)
def authenticate_user(self) -> bool:
2020-09-06 04:13:42 +00:00
try:
2022-03-08 04:40:44 +00:00
logger.debug("Searching for specified token")
2022-01-15 00:23:50 +00:00
api_token = self.get_argument("token", "")
if api_token is None and self.request.headers.get("Authorization"):
api_token = bearer_pattern.sub(
"", self.request.headers.get("Authorization")
)
2022-01-15 00:23:50 +00:00
elif api_token is None:
api_token = self.get_cookie("token")
2022-01-15 00:23:50 +00:00
user_data = self.controller.users.get_user_by_api_token(api_token)
2022-03-08 04:40:44 +00:00
logger.debug("Checking results")
2020-09-06 04:13:42 +00:00
if user_data:
2020-09-06 04:58:17 +00:00
# Login successful! Check perms
2022-03-08 04:40:44 +00:00
logger.info(f"User {user_data['username']} has authenticated to API")
# TODO: Role check
return True # This is to set the "authenticated"
2020-09-06 04:13:42 +00:00
else:
logging.debug("Auth unsuccessful")
self.access_denied("unknown", "the user provided an invalid token")
2022-01-15 00:23:50 +00:00
return False
except Exception as e:
2022-03-08 04:40:44 +00:00
logger.warning("An error occured while authenticating an API user: %s", e)
self.finish(
self.return_response(
403,
{
"error": "ACCESS_DENIED",
"info": "An error occured while authenticating the user",
},
)
)
2022-01-15 00:23:50 +00:00
return False
2020-09-06 04:13:42 +00:00
2020-09-06 04:58:17 +00:00
class ServersStats(ApiHandler):
2020-09-06 04:58:17 +00:00
def get(self):
"""Get details about all servers"""
authenticated = self.authenticate_user()
if not authenticated:
return
2020-09-06 04:58:17 +00:00
# Get server stats
# TODO Check perms
self.finish(self.write({"servers": self.controller.stats.get_servers_stats()}))
2020-09-06 04:58:17 +00:00
class NodeStats(ApiHandler):
2020-09-06 04:58:17 +00:00
def get(self):
"""Get stats for particular node"""
authenticated = self.authenticate_user()
if not authenticated:
return
2020-09-06 04:58:17 +00:00
# Get node stats
node_stats = self.controller.stats.get_node_stats()
2020-09-06 04:58:17 +00:00
node_stats.pop("servers")
self.finish(self.write(node_stats))