Skip to content

Commit cc02044

Browse files
authored
Shared access key (#182)
* Add SUMO_TOKEN (shared key) authorization. --------- Co-authored-by: Raymond Wiker <rayw@equinor.com>
1 parent d457e3c commit cc02044

2 files changed

Lines changed: 48 additions & 34 deletions

File tree

src/sumo/wrapper/_auth_provider.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ def get_token(self):
3636
# ELSE
3737
return result["access_token"]
3838

39+
def get_authorization(self):
40+
return {"Authorization": "Bearer " + self.get_token()}
41+
3942
pass
4043

4144

@@ -68,21 +71,21 @@ def __init__(self, refresh_token, client_id, authority, resource_id):
6871
pass
6972

7073

71-
def get_token_path(resource_id):
74+
def get_token_path(resource_id, suffix):
7275
return os.path.join(
73-
os.path.expanduser("~"), ".sumo", str(resource_id) + ".token"
76+
os.path.expanduser("~"), ".sumo", str(resource_id) + suffix
7477
)
7578

7679

77-
def get_token_cache(resource_id):
80+
def get_token_cache(resource_id, suffix):
7881
# https://github.com/AzureAD/microsoft-authentication-extensions-\
7982
# for-python
8083
# Encryption not supported on linux servers like rgs, and
8184
# neither is common usage from many cluster nodes.
8285
# Encryption is supported on Windows and Mac.
8386

8487
cache = None
85-
token_path = get_token_path(resource_id)
88+
token_path = get_token_path(resource_id, suffix)
8689
if sys.platform.startswith("linux"):
8790
persistence = FilePersistence(token_path)
8891
cache = PersistedTokenCache(persistence)
@@ -107,10 +110,10 @@ def get_token_cache(resource_id):
107110
return cache
108111

109112

110-
def protect_token_cache(resource_id):
111-
token_path = get_token_path(resource_id)
113+
def protect_token_cache(resource_id, suffix):
114+
token_path = get_token_path(resource_id, suffix)
112115

113-
if sys.platform.startswith("linux"):
116+
if sys.platform.startswith("linux") or sys.platform == "darwin":
114117
filemode = stat.filemode(os.stat(token_path).st_mode)
115118
if filemode != "-rw-------":
116119
os.chmod(token_path, 0o600)
@@ -127,7 +130,7 @@ def protect_token_cache(resource_id):
127130
class AuthProviderInteractive(AuthProvider):
128131
def __init__(self, client_id, authority, resource_id):
129132
super().__init__(resource_id)
130-
cache = get_token_cache(resource_id)
133+
cache = get_token_cache(resource_id, ".token")
131134
self._app = msal.PublicClientApplication(
132135
client_id=client_id, authority=authority, token_cache=cache
133136
)
@@ -176,7 +179,7 @@ def login(self):
176179
)
177180
return
178181

179-
protect_token_cache(self._resource_id)
182+
protect_token_cache(self._resource_id, ".token")
180183
print("Equinor Azure login for Sumo access was successful")
181184
return
182185

@@ -186,7 +189,7 @@ def login(self):
186189
class AuthProviderDeviceCode(AuthProvider):
187190
def __init__(self, client_id, authority, resource_id):
188191
super().__init__(resource_id)
189-
cache = get_token_cache(resource_id)
192+
cache = get_token_cache(resource_id, ".token")
190193
self._app = msal.PublicClientApplication(
191194
client_id=client_id, authority=authority, token_cache=cache
192195
)
@@ -215,7 +218,7 @@ def login(self):
215218
% json.dumps(result, indent=4)
216219
)
217220

218-
protect_token_cache(self._resource_id)
221+
protect_token_cache(self._resource_id, ".token")
219222

220223
return
221224

@@ -235,6 +238,21 @@ def get_token(self):
235238
pass
236239

237240

241+
class AuthProviderSumoToken(AuthProvider):
242+
def __init__(self, resource_id):
243+
protect_token_cache(resource_id, ".sharedkey")
244+
token_path = get_token_path(resource_id, ".sharedkey")
245+
with open(token_path, "r") as f:
246+
self._token = f.readline().strip()
247+
return
248+
249+
def get_token(self):
250+
return self._token
251+
252+
def get_authorization(self):
253+
return {"X-SUMO-Token": self._token}
254+
255+
238256
def get_auth_provider(
239257
client_id,
240258
authority,
@@ -252,6 +270,9 @@ def get_auth_provider(
252270
if access_token:
253271
return AuthProviderAccessToken(access_token)
254272
# ELSE
273+
if os.path.exists(get_token_path(resource_id, ".sharedkey")):
274+
return AuthProviderSumoToken(resource_id)
275+
# ELSE
255276
if interactive:
256277
return AuthProviderInteractive(client_id, authority, resource_id)
257278
# ELSE

src/sumo/wrapper/sumo_client.py

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,12 @@ def get(self, path: str, params: dict = None) -> dict:
146146
)
147147
"""
148148

149-
token = self.auth.get_token()
150-
151149
headers = {
152150
"Content-Type": "application/json",
153-
"authorization": f"Bearer {token}",
154151
}
155152

153+
headers.update(self.auth.get_authorization())
154+
156155
def _get():
157156
return httpx.get(
158157
f"{self.base_url}{path}",
@@ -214,8 +213,6 @@ def post(
214213
json=object_metadata
215214
)
216215
"""
217-
token = self.auth.get_token()
218-
219216
if blob and json:
220217
raise ValueError("Both blob and json given to post.")
221218

@@ -225,9 +222,10 @@ def post(
225222

226223
headers = {
227224
"Content-Type": content_type,
228-
"authorization": f"Bearer {token}",
229225
}
230226

227+
headers.update(self.auth.get_authorization())
228+
231229
def _post():
232230
return httpx.post(
233231
f"{self.base_url}{path}",
@@ -260,8 +258,6 @@ def put(
260258
Sumo response object
261259
"""
262260

263-
token = self.auth.get_token()
264-
265261
if blob and json:
266262
raise ValueError("Both blob and json given to post")
267263

@@ -273,9 +269,10 @@ def put(
273269

274270
headers = {
275271
"Content-Type": content_type,
276-
"authorization": f"Bearer {token}",
277272
}
278273

274+
headers.update(self.auth.get_authorization())
275+
279276
def _put():
280277
return httpx.put(
281278
f"{self.base_url}{path}",
@@ -309,13 +306,12 @@ def delete(self, path: str, params: dict = None) -> dict:
309306
sumo.delete(path=f"/objects('{object_id}')")
310307
"""
311308

312-
token = self.auth.get_token()
313-
314309
headers = {
315310
"Content-Type": "application/json",
316-
"Authorization": f"Bearer {token}",
317311
}
318312

313+
headers.update(self.auth.get_authorization())
314+
319315
def _delete():
320316
return httpx.delete(
321317
f"{self.base_url}{path}",
@@ -374,13 +370,13 @@ async def get_async(self, path: str, params: dict = None):
374370
size=3
375371
)
376372
"""
377-
token = self.auth.get_token()
378373

379374
headers = {
380375
"Content-Type": "application/json",
381-
"authorization": f"Bearer {token}",
382376
}
383377

378+
headers.update(self.auth.get_authorization())
379+
384380
async def _get():
385381
async with httpx.AsyncClient(follow_redirects=True) as client:
386382
return await client.get(
@@ -443,8 +439,6 @@ async def post_async(
443439
)
444440
"""
445441

446-
token = self.auth.get_token()
447-
448442
if blob and json:
449443
raise ValueError("Both blob and json given to post.")
450444

@@ -454,9 +448,10 @@ async def post_async(
454448

455449
headers = {
456450
"Content-Type": content_type,
457-
"authorization": f"Bearer {token}",
458451
}
459452

453+
headers.update(self.auth.get_authorization())
454+
460455
async def _post():
461456
async with httpx.AsyncClient() as client:
462457
return await client.post(
@@ -490,8 +485,6 @@ async def put_async(
490485
Sumo response object
491486
"""
492487

493-
token = self.auth.get_token()
494-
495488
if blob and json:
496489
raise ValueError("Both blob and json given to post")
497490

@@ -503,9 +496,10 @@ async def put_async(
503496

504497
headers = {
505498
"Content-Type": content_type,
506-
"authorization": f"Bearer {token}",
507499
}
508500

501+
headers.update(self.auth.get_authorization())
502+
509503
async def _put():
510504
async with httpx.AsyncClient() as client:
511505
return await client.put(
@@ -540,13 +534,12 @@ async def delete_async(self, path: str, params: dict = None) -> dict:
540534
await sumo.delete_async(path=f"/objects('{object_id}')")
541535
"""
542536

543-
token = self.auth.get_token()
544-
545537
headers = {
546538
"Content-Type": "application/json",
547-
"Authorization": f"Bearer {token}",
548539
}
549540

541+
headers.update(self.auth.get_authorization())
542+
550543
async def _delete():
551544
async with httpx.AsyncClient() as client:
552545
return await client.delete(

0 commit comments

Comments
 (0)