Commit b6a156a6 authored by Alex's avatar Alex
Browse files

Add check for login refresh

parent 4a511930
import requests
from typing import Tuple
MATERIALS_API_LOGIN_URL = "https://api-materials.doc.ic.ac.uk/auth/login"
MATERIALS_API_LOGOUT_URL = "https://api-materials.doc.ic.ac.uk/auth/logout"
MATERIALS_API_REFRESH_URL = "https://api-materials.doc.ic.ac.uk/auth/refresh"
def login(username: str, password: str) -> str:
def login(username: str, password: str) -> Tuple[str, str]:
"""
Authenticates a user given their username and password. Returns an access_token to be used
for subsequent requests in the Authorization header.
Authenticates a user given their username and password. Returns an access_token and
a refresh_token to be used for subsequent requests in the Authorization header.
"""
headers = {
"Content-Type": "application/json"
......@@ -20,7 +21,19 @@ def login(username: str, password: str) -> str:
resp = requests.post(MATERIALS_API_LOGIN_URL, json=body, headers=headers)
data = resp.json()
return str(data["access_token"])
return str(data["access_token"]), str(data["refresh_token"])
def refresh(refresh_token: str) -> str:
"""
Returns a new access token given a refresh token.
"""
def logout():
pass
\ No newline at end of file
headers = {
"Authorization": f"Bearer {refresh_token}"
}
resp = requests.post(MATERIALS_API_REFRESH_URL, json={}, headers=headers)
data = resp.json()
return str(data["access_token"])
......@@ -7,15 +7,17 @@ from .resources import Resources, Resource
MATERIALS_API_STATUS_URL = "https://api-materials.doc.ic.ac.uk/status"
class Materials:
def __init__(self, token: str):
self._access_token = token
def __init__(self, access_token: str, refresh_token: str = ""):
self._access_token = access_token
self._refresh_token = refresh_token
self._has_refreshed = False
def get_as_dict(self) -> dict:
return vars(self)
@staticmethod
def from_dict(client: dict):
return Materials(client["_access_token"])
return Materials(client["_access_token"], client["_refresh_token"])
@staticmethod
def _is_alive() -> bool:
......@@ -23,6 +25,11 @@ class Materials:
data = resp.json()
return data["status"] == "alive"
def _refresh_client(self):
self._access_token = auth.refresh(self._refresh_token)
self._refresh_token = ""
self._has_refreshed = True
@staticmethod
def create_client(username: str, password: str):
"""
......@@ -31,7 +38,13 @@ class Materials:
if not Materials._is_alive():
raise Exception("The Materials API is currently down.")
return Materials(auth.login(username, password))
return Materials(*auth.login(username, password))
def requires_new_login(self) -> bool:
"""
Check whether you need to request for a new login, to keep the client alive.
"""
return self._has_refreshed
def get_courses_for_year(self, academic_year: str) -> List[Course]:
"""
......@@ -39,7 +52,14 @@ class Materials:
user during the given the academic_year string.
(e.g. 2122 for the year 2021/2022).
"""
return Courses.get_for_year(self._access_token, academic_year)
try:
return Courses.get_for_year(self._access_token, academic_year)
except:
if not self._has_refreshed:
self._refresh_client()
return self.get_courses_for_year(academic_year)
else:
raise ValueError("The client access token has expired, please request a new login for the user")
def get_resources_for_year(self, academic_year: str) -> List[Resource]:
"""
......@@ -47,4 +67,11 @@ class Materials:
user during the given the academic_year string.
(e.g. 2122 for the year 2021/2022).
"""
return Resources.get_for_year(self._access_token, academic_year)
\ No newline at end of file
try:
return Resources.get_for_year(self._access_token, academic_year)
except:
if not self._has_refreshed:
self._refresh_client()
return self.get_courses_for_year(academic_year)
else:
raise ValueError("The client access token has expired, please request a new login for the user")
......@@ -54,6 +54,8 @@ def using_materials(f):
materials_client = None
try:
materials_client = Materials.from_dict(session[SESSION_KEY_NAME])
if materials_client.requires_new_login() and IMPERIAL_DOC_MATERIALS_REDIRECT_URL:
return redirect(IMPERIAL_DOC_MATERIALS_URL_PREFIX + str(url_for(IMPERIAL_DOC_MATERIALS_REDIRECT_URL, next=request.url)))
except:
if IMPERIAL_DOC_MATERIALS_REDIRECT_URL:
return redirect(IMPERIAL_DOC_MATERIALS_URL_PREFIX + str(url_for(IMPERIAL_DOC_MATERIALS_REDIRECT_URL, next=request.url)))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment