Skip to content

Commit

Permalink
Shared access key (#182)
Browse files Browse the repository at this point in the history
* Add SUMO_TOKEN (shared key) authorization.

---------

Co-authored-by: Raymond Wiker <rayw@equinor.com>
  • Loading branch information
rwiker and Raymond Wiker authored Dec 21, 2023
1 parent d457e3c commit cc02044
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 34 deletions.
43 changes: 32 additions & 11 deletions src/sumo/wrapper/_auth_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def get_token(self):
# ELSE
return result["access_token"]

def get_authorization(self):
return {"Authorization": "Bearer " + self.get_token()}

pass


Expand Down Expand Up @@ -68,21 +71,21 @@ 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
# neither is common usage from many cluster nodes.
# 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)
Expand All @@ -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)
Expand All @@ -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
)
Expand Down Expand Up @@ -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

Expand All @@ -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
)
Expand Down Expand Up @@ -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

Expand All @@ -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,
Expand All @@ -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
Expand Down
39 changes: 16 additions & 23 deletions src/sumo/wrapper/sumo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}",
Expand Down Expand Up @@ -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.")

Expand All @@ -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}",
Expand Down Expand Up @@ -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")

Expand All @@ -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}",
Expand Down Expand Up @@ -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}",
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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.")

Expand All @@ -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(
Expand Down Expand Up @@ -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")

Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit cc02044

Please sign in to comment.