diff --git a/src/sumo/wrapper/_auth_provider.py b/src/sumo/wrapper/_auth_provider.py index 1f92153..f4fb717 100644 --- a/src/sumo/wrapper/_auth_provider.py +++ b/src/sumo/wrapper/_auth_provider.py @@ -36,6 +36,9 @@ def get_token(self): # ELSE return result["access_token"] + def get_authorization(self): + return {"Authorization": "Bearer " + self.get_token()} + pass @@ -68,13 +71,13 @@ def __init__(self, refresh_token, client_id, authority, resource_id): pass -def get_token_path(resource_id): +def get_token_path(resource_id, suffix): return os.path.join( - os.path.expanduser("~"), ".sumo", str(resource_id) + ".token" + os.path.expanduser("~"), ".sumo", str(resource_id) + suffix ) -def get_token_cache(resource_id): +def get_token_cache(resource_id, suffix): # https://github.com/AzureAD/microsoft-authentication-extensions-\ # for-python # Encryption not supported on linux servers like rgs, and @@ -82,7 +85,7 @@ def get_token_cache(resource_id): # Encryption is supported on Windows and Mac. cache = None - token_path = get_token_path(resource_id) + token_path = get_token_path(resource_id, suffix) if sys.platform.startswith("linux"): persistence = FilePersistence(token_path) cache = PersistedTokenCache(persistence) @@ -107,10 +110,10 @@ def get_token_cache(resource_id): return cache -def protect_token_cache(resource_id): - token_path = get_token_path(resource_id) +def protect_token_cache(resource_id, suffix): + token_path = get_token_path(resource_id, suffix) - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or sys.platform == "darwin": filemode = stat.filemode(os.stat(token_path).st_mode) if filemode != "-rw-------": os.chmod(token_path, 0o600) @@ -127,7 +130,7 @@ def protect_token_cache(resource_id): class AuthProviderInteractive(AuthProvider): def __init__(self, client_id, authority, resource_id): super().__init__(resource_id) - cache = get_token_cache(resource_id) + cache = get_token_cache(resource_id, ".token") self._app = msal.PublicClientApplication( client_id=client_id, authority=authority, token_cache=cache ) @@ -176,7 +179,7 @@ def login(self): ) return - protect_token_cache(self._resource_id) + protect_token_cache(self._resource_id, ".token") print("Equinor Azure login for Sumo access was successful") return @@ -186,7 +189,7 @@ def login(self): class AuthProviderDeviceCode(AuthProvider): def __init__(self, client_id, authority, resource_id): super().__init__(resource_id) - cache = get_token_cache(resource_id) + cache = get_token_cache(resource_id, ".token") self._app = msal.PublicClientApplication( client_id=client_id, authority=authority, token_cache=cache ) @@ -215,7 +218,7 @@ def login(self): % json.dumps(result, indent=4) ) - protect_token_cache(self._resource_id) + protect_token_cache(self._resource_id, ".token") return @@ -235,6 +238,21 @@ def get_token(self): pass +class AuthProviderSumoToken(AuthProvider): + def __init__(self, resource_id): + protect_token_cache(resource_id, ".sharedkey") + token_path = get_token_path(resource_id, ".sharedkey") + with open(token_path, "r") as f: + self._token = f.readline().strip() + return + + def get_token(self): + return self._token + + def get_authorization(self): + return {"X-SUMO-Token": self._token} + + def get_auth_provider( client_id, authority, @@ -252,6 +270,9 @@ def get_auth_provider( if access_token: return AuthProviderAccessToken(access_token) # ELSE + if os.path.exists(get_token_path(resource_id, ".sharedkey")): + return AuthProviderSumoToken(resource_id) + # ELSE if interactive: return AuthProviderInteractive(client_id, authority, resource_id) # ELSE diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index a74a042..cb4e577 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -146,13 +146,12 @@ def get(self, path: str, params: dict = None) -> dict: ) """ - token = self.auth.get_token() - headers = { "Content-Type": "application/json", - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + def _get(): return httpx.get( f"{self.base_url}{path}", @@ -214,8 +213,6 @@ def post( json=object_metadata ) """ - token = self.auth.get_token() - if blob and json: raise ValueError("Both blob and json given to post.") @@ -225,9 +222,10 @@ def post( headers = { "Content-Type": content_type, - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + def _post(): return httpx.post( f"{self.base_url}{path}", @@ -260,8 +258,6 @@ def put( Sumo response object """ - token = self.auth.get_token() - if blob and json: raise ValueError("Both blob and json given to post") @@ -273,9 +269,10 @@ def put( headers = { "Content-Type": content_type, - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + def _put(): return httpx.put( f"{self.base_url}{path}", @@ -309,13 +306,12 @@ def delete(self, path: str, params: dict = None) -> dict: sumo.delete(path=f"/objects('{object_id}')") """ - token = self.auth.get_token() - headers = { "Content-Type": "application/json", - "Authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + def _delete(): return httpx.delete( f"{self.base_url}{path}", @@ -374,13 +370,13 @@ async def get_async(self, path: str, params: dict = None): size=3 ) """ - token = self.auth.get_token() headers = { "Content-Type": "application/json", - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + async def _get(): async with httpx.AsyncClient(follow_redirects=True) as client: return await client.get( @@ -443,8 +439,6 @@ async def post_async( ) """ - token = self.auth.get_token() - if blob and json: raise ValueError("Both blob and json given to post.") @@ -454,9 +448,10 @@ async def post_async( headers = { "Content-Type": content_type, - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + async def _post(): async with httpx.AsyncClient() as client: return await client.post( @@ -490,8 +485,6 @@ async def put_async( Sumo response object """ - token = self.auth.get_token() - if blob and json: raise ValueError("Both blob and json given to post") @@ -503,9 +496,10 @@ async def put_async( headers = { "Content-Type": content_type, - "authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + async def _put(): async with httpx.AsyncClient() as client: return await client.put( @@ -540,13 +534,12 @@ async def delete_async(self, path: str, params: dict = None) -> dict: await sumo.delete_async(path=f"/objects('{object_id}')") """ - token = self.auth.get_token() - headers = { "Content-Type": "application/json", - "Authorization": f"Bearer {token}", } + headers.update(self.auth.get_authorization()) + async def _delete(): async with httpx.AsyncClient() as client: return await client.delete(