98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
from datetime import datetime, timedelta
|
|
|
|
import json
|
|
import mysql.connector as sql
|
|
from mysql.connector import IntegrityError
|
|
import requests
|
|
|
|
class BackendException(Exception):
|
|
def __init__(self, status_code, status_message):
|
|
self.status = status_code
|
|
self.message = status_message
|
|
|
|
|
|
class Authenticator:
|
|
def __init__(self, config, logger):
|
|
self.logger = logger
|
|
self.perm_url = config['api']['permission_url'].rstrip('/')
|
|
self.headers = {'Accept': 'application/json',
|
|
'Content-Type': 'application/json'}
|
|
self.ttl = timedelta(seconds=int(config['api']['cache_seconds']))
|
|
self.session = requests.Session()
|
|
self.conninfo = {
|
|
'user': config['db']['user'],
|
|
'password': config['db']['password'],
|
|
'database': config['db']['database'],
|
|
'host': config['db'].get('host' 'localhost'),
|
|
'port': config['db'].get('port', 3306)
|
|
}
|
|
|
|
def authenticate(self, token):
|
|
# DEBUG
|
|
#return 'granted'
|
|
# END DEBUG
|
|
|
|
# DEBUG
|
|
#result = self._make_request(token)
|
|
#self.logger.error("Got response %s for %s", result, token)
|
|
#return result
|
|
# END DEBUG
|
|
|
|
self._cache_clean()
|
|
|
|
result = self._cache_read(token)
|
|
if result:
|
|
self.logger.debug("Got %s from cache for %s",
|
|
result, token)
|
|
return result
|
|
|
|
result = self._make_request(token)
|
|
self.logger.debug("Got %s from auth for %s",
|
|
result, token)
|
|
try:
|
|
self._cache_save(token, result)
|
|
self.logger.debug("Saved %s to cache for %s",
|
|
result, token)
|
|
except IntegrityError as e:
|
|
result = self._cache_read(token)
|
|
self.logger.debug("Got %s from cache under race for %s",
|
|
result, token)
|
|
return result
|
|
|
|
def _cache_clean(self):
|
|
with sql.connect(**self.conninfo) as db:
|
|
with db.cursor() as c:
|
|
c.execute("delete from `cache` where `end` < %s",
|
|
(datetime.now().timestamp(),))
|
|
db.commit()
|
|
|
|
def _cache_read(self, token):
|
|
with sql.connect(**self.conninfo) as db:
|
|
with db.cursor() as c:
|
|
c.execute("select `result` from `cache` where `token` = %s",
|
|
(token,))
|
|
result = c.fetchone()
|
|
if result:
|
|
return result[0]
|
|
return None
|
|
|
|
def _cache_save(self, token, result):
|
|
with sql.connect(**self.conninfo) as db:
|
|
with db.cursor() as c:
|
|
stmt = "insert into `cache`(`token`, `result`, `end`) " + \
|
|
"values (%s, %s, %s)"
|
|
end = datetime.now() + self.ttl
|
|
c.execute(stmt, (token, result, end.timestamp()))
|
|
db.commit()
|
|
|
|
|
|
def _make_request(self, token):
|
|
data = {'token': token}
|
|
response = self.session.post(self.perm_url,
|
|
headers=self.headers,
|
|
data=json.dumps(data))
|
|
if not response.ok:
|
|
raise BackendException(response.status_code,
|
|
response.json()['message'])
|
|
return response.json()['permission']
|