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
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
from app.classes.web.base_handler import BaseHandler
|
2020-09-06 04:13:42 +00:00
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
2022-01-15 00:23:50 +00:00
|
|
|
bearer_pattern = re.compile(r'^Bearer', flags=re.IGNORECASE)
|
2020-09-06 04:13:42 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
class ApiHandler(BaseHandler):
|
2022-01-26 01:45:30 +00:00
|
|
|
|
2021-04-17 15:19:19 +00:00
|
|
|
def return_response(self, status: int, data: dict):
|
2022-01-26 01:45:30 +00:00
|
|
|
# Define a standardized response
|
2021-04-17 15:19:19 +00:00
|
|
|
self.set_status(status)
|
2020-09-06 04:13:42 +00:00
|
|
|
self.write(data)
|
2022-01-15 00:23:50 +00:00
|
|
|
|
2021-04-17 15:19:19 +00:00
|
|
|
def access_denied(self, user, reason=''):
|
2022-01-26 01:45:30 +00:00
|
|
|
if reason:
|
|
|
|
reason = ' because ' + reason
|
2021-04-17 15:19:19 +00:00
|
|
|
log.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'
|
|
|
|
}))
|
2022-01-26 01:45:30 +00:00
|
|
|
|
2021-04-17 15:19:19 +00:00
|
|
|
def authenticate_user(self) -> bool:
|
2020-09-06 04:13:42 +00:00
|
|
|
try:
|
|
|
|
log.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'))
|
|
|
|
elif api_token is None:
|
|
|
|
api_token = self.get_cookie('token')
|
|
|
|
user_data = self.controller.users.get_user_by_api_token(api_token)
|
|
|
|
|
2020-09-06 04:13:42 +00:00
|
|
|
log.debug("Checking results")
|
|
|
|
if user_data:
|
2020-09-06 04:58:17 +00:00
|
|
|
# Login successful! Check perms
|
2022-01-26 01:45:30 +00:00
|
|
|
log.info(f"User {user_data['username']} has authenticated to API")
|
|
|
|
# TODO: Role check
|
2021-04-17 15:19:19 +00:00
|
|
|
|
|
|
|
return True # This is to set the "authenticated"
|
2020-09-06 04:13:42 +00:00
|
|
|
else:
|
|
|
|
logging.debug("Auth unsuccessful")
|
2021-04-17 15:19:19 +00:00
|
|
|
self.access_denied("unknown", "the user provided an invalid token")
|
2022-01-15 00:23:50 +00:00
|
|
|
return False
|
2021-04-17 15:19:19 +00:00
|
|
|
except Exception as e:
|
|
|
|
log.warning("An error occured while authenticating an API user: %s", e)
|
2022-01-26 01:45:30 +00:00
|
|
|
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
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
class ServersStats(ApiHandler):
|
2020-09-06 04:58:17 +00:00
|
|
|
def get(self):
|
|
|
|
"""Get details about all servers"""
|
2021-04-17 15:19:19 +00:00
|
|
|
authenticated = self.authenticate_user()
|
2022-01-26 01:45:30 +00:00
|
|
|
if not authenticated:
|
|
|
|
return
|
|
|
|
|
2020-09-06 04:58:17 +00:00
|
|
|
# Get server stats
|
2021-04-17 15:19:19 +00:00
|
|
|
# TODO Check perms
|
2021-03-22 04:02:18 +00:00
|
|
|
self.finish(self.write({"servers": self.controller.stats.get_servers_stats()}))
|
2020-09-06 04:58:17 +00:00
|
|
|
|
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
class NodeStats(ApiHandler):
|
2020-09-06 04:58:17 +00:00
|
|
|
def get(self):
|
|
|
|
"""Get stats for particular node"""
|
2021-04-17 15:19:19 +00:00
|
|
|
authenticated = self.authenticate_user()
|
2022-01-26 01:45:30 +00:00
|
|
|
if not authenticated:
|
|
|
|
return
|
|
|
|
|
2020-09-06 04:58:17 +00:00
|
|
|
# Get node stats
|
2021-03-22 04:02:18 +00:00
|
|
|
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))
|