1
+ import base64
2
+ import arrow
3
+
1
4
from typing import Any , cast
2
5
from datetime import timedelta
3
6
4
- from superdesk .core import get_app_config
7
+ from superdesk .utc import utcnow
8
+ from superdesk .core import json , get_app_config
5
9
from superdesk .core .types import Request
6
10
from superdesk import get_resource_service
7
11
from superdesk .errors import SuperdeskApiError
8
12
from superdesk .resource_fields import LAST_UPDATED , ID_FIELD
9
- from superdesk .utc import utcnow
10
13
11
14
from .user_auth import UserAuthProtocol
12
15
13
16
14
17
class TokenAuthorization (UserAuthProtocol ):
18
+ @staticmethod
19
+ def _decode_token (token : str ) -> str :
20
+ """
21
+ Tries to decode the auth header token. Decode logic based on internal logic from
22
+ `werkzeug.datastructures.Authorization`
23
+ """
24
+ try :
25
+ return base64 .b64decode (token ).decode ().partition (":" )[0 ]
26
+ except Exception :
27
+ return token
28
+
15
29
async def authenticate (self , request : Request ):
16
30
token = request .get_header ("Authorization" )
17
31
new_session = True
32
+
18
33
if token :
19
34
token = token .strip ()
20
35
if token .lower ().startswith (("token" , "bearer" )):
@@ -29,6 +44,10 @@ async def authenticate(self, request: Request):
29
44
30
45
# Check provided token is valid
31
46
auth_service = get_resource_service ("auth" )
47
+
48
+ # tokens are no longer decoded internally by flask/quart
49
+ # so we need to do it ourselves
50
+ token = self ._decode_token (token )
32
51
auth_token = auth_service .find_one (token = token , req = None )
33
52
34
53
if not auth_token :
@@ -54,12 +73,15 @@ async def start_session(self, request: Request, user: dict[str, Any], **kwargs)
54
73
await self .stop_session (request )
55
74
raise SuperdeskApiError .unauthorizedError ()
56
75
57
- request .storage .session .set ("session_token" , auth_token )
76
+ request .storage .session .set ("session_token" , json . dumps ( auth_token ) )
58
77
await super ().start_session (request , user , ** kwargs )
59
78
60
79
async def continue_session (self , request : Request , user : dict [str , Any ], ** kwargs ) -> None :
61
80
auth_token = request .storage .session .get ("session_token" )
62
81
82
+ if isinstance (auth_token , str ):
83
+ auth_token = json .loads (auth_token )
84
+
63
85
if not auth_token :
64
86
await self .stop_session (request )
65
87
raise SuperdeskApiError .unauthorizedError ()
@@ -74,7 +96,9 @@ async def continue_session(self, request: Request, user: dict[str, Any], **kwarg
74
96
now = utcnow ()
75
97
auth_updated = False
76
98
session_update_seconds = cast (int , get_app_config ("SESSION_UPDATE_SECONDS" , 30 ))
77
- if auth_token [LAST_UPDATED ] + timedelta (seconds = session_update_seconds ) < now :
99
+ auth_last_updated = arrow .get (auth_token [LAST_UPDATED ])
100
+
101
+ if auth_last_updated + timedelta (seconds = session_update_seconds ) < now :
78
102
auth_service = get_resource_service ("auth" )
79
103
auth_service .update_session ({LAST_UPDATED : now })
80
104
auth_updated = True
0 commit comments