From fe08ac2a19bf4dddb07859a61f0aad57d67807bf Mon Sep 17 00:00:00 2001 From: Trent Smith Date: Fri, 7 Sep 2018 12:30:13 -0700 Subject: [PATCH 1/3] The life time of a token can be adjusted for authentication sessions. By adding the kwarg token_expiration to a SwaggerClient request you can specify how long before a generated security token expires. --- hca/util/__init__.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hca/util/__init__.py b/hca/util/__init__.py index 055868e7..64309718 100755 --- a/hca/util/__init__.py +++ b/hca/util/__init__.py @@ -120,7 +120,7 @@ def __init__(self, client, parameters, path_parameters, http_method, method_name self.__dict__.update(locals()) self._context_manager_response = None - def _request(self, req_args, url=None, stream=False, headers=None): + def _request(self, req_args, url=None, stream=False, headers=None, **kwargs): supplied_path_params = [p for p in req_args if p in self.path_parameters and req_args[p] is not None] if url is None: url = self.client.host + self.client.http_paths[self.method_name][frozenset(supplied_path_params)] @@ -130,7 +130,7 @@ def _request(self, req_args, url=None, stream=False, headers=None): if self.parameters.get(k, {}).get("in") == "query" and v is not None} body = {k: v for k, v in req_args.items() if k in self.body_props and v is not None} if "security" in self.method_data: - session = self.client.get_authenticated_session() + session = self.client.get_authenticated_session(**kwargs) else: session = self.client.get_session() @@ -182,6 +182,7 @@ def iterate(self, **kwargs): class SwaggerClient(object): scheme = "https" retry_policy = RetryPolicy(read=10, status=10, status_forcelist=frozenset({500, 502, 503, 504})) + default_token_expiration = 3600 _authenticated_session = None _session = None _spec_valid_for_days = 7 @@ -336,7 +337,7 @@ def _get_oauth_token_from_service_account_credentials(self): r.session.close() return credentials.token, credentials.expiry - def _get_jwt_from_service_account_credentials(self): + def _get_jwt_from_service_account_credentials(self, token_expiration): assert 'GOOGLE_APPLICATION_CREDENTIALS' in os.environ service_account_credentials_filename = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] if not os.path.isfile(service_account_credentials_filename): @@ -347,26 +348,27 @@ def _get_jwt_from_service_account_credentials(self): audience = "https://dev.data.humancellatlas.org/" iat = time.time() - exp = iat + 3600 + exp = iat + token_expiration payload = {'iss': service_credentials["client_email"], 'sub': service_credentials["client_email"], 'aud': audience, 'iat': iat, 'exp': exp, 'email': service_credentials["client_email"], - 'scope': ['email', 'openid', 'offline_access'] + 'scope': ['email', 'openid', 'offline_access'], + 'https://auth.data.humancellatlas.org/group': 'hca' } - payload['https://auth.data.humancellatlas.org/group'] = 'hca' additional_headers = {'kid': service_credentials["private_key_id"]} signed_jwt = jwt.encode(payload, service_credentials["private_key"], headers=additional_headers, algorithm='RS256').decode() return signed_jwt, exp - def get_authenticated_session(self): + def get_authenticated_session(self, **kwargs): if self._authenticated_session is None: oauth2_client_data = self.application_secrets["installed"] if 'GOOGLE_APPLICATION_CREDENTIALS' in os.environ: - token, expires_at = self._get_jwt_from_service_account_credentials() + token, expires_at = self._get_jwt_from_service_account_credentials( + kwargs.get('token_expiration', self.default_token_expiration)) # TODO: (akislyuk) figure out the right strategy for persisting the service account oauth2 token self._authenticated_session = OAuth2Session(client_id=oauth2_client_data["client_id"], token=dict(access_token=token), From 6409e33c14ead1241ddd5d4ef7714d71a59a8b25 Mon Sep 17 00:00:00 2001 From: Trent Smith Date: Tue, 11 Sep 2018 13:50:42 -0400 Subject: [PATCH 2/3] setting token_expiration in swaggerclient --- hca/util/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hca/util/__init__.py b/hca/util/__init__.py index 64309718..f9ae6cfd 100755 --- a/hca/util/__init__.py +++ b/hca/util/__init__.py @@ -130,7 +130,7 @@ def _request(self, req_args, url=None, stream=False, headers=None, **kwargs): if self.parameters.get(k, {}).get("in") == "query" and v is not None} body = {k: v for k, v in req_args.items() if k in self.body_props and v is not None} if "security" in self.method_data: - session = self.client.get_authenticated_session(**kwargs) + session = self.client.get_authenticated_session() else: session = self.client.get_session() @@ -182,7 +182,7 @@ def iterate(self, **kwargs): class SwaggerClient(object): scheme = "https" retry_policy = RetryPolicy(read=10, status=10, status_forcelist=frozenset({500, 502, 503, 504})) - default_token_expiration = 3600 + token_expiration = 3600 _authenticated_session = None _session = None _spec_valid_for_days = 7 @@ -337,7 +337,7 @@ def _get_oauth_token_from_service_account_credentials(self): r.session.close() return credentials.token, credentials.expiry - def _get_jwt_from_service_account_credentials(self, token_expiration): + def _get_jwt_from_service_account_credentials(self): assert 'GOOGLE_APPLICATION_CREDENTIALS' in os.environ service_account_credentials_filename = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] if not os.path.isfile(service_account_credentials_filename): @@ -348,7 +348,7 @@ def _get_jwt_from_service_account_credentials(self, token_expiration): audience = "https://dev.data.humancellatlas.org/" iat = time.time() - exp = iat + token_expiration + exp = iat + self.token_expiration payload = {'iss': service_credentials["client_email"], 'sub': service_credentials["client_email"], 'aud': audience, @@ -367,8 +367,7 @@ def get_authenticated_session(self, **kwargs): if self._authenticated_session is None: oauth2_client_data = self.application_secrets["installed"] if 'GOOGLE_APPLICATION_CREDENTIALS' in os.environ: - token, expires_at = self._get_jwt_from_service_account_credentials( - kwargs.get('token_expiration', self.default_token_expiration)) + token, expires_at = self._get_jwt_from_service_account_credentials() # TODO: (akislyuk) figure out the right strategy for persisting the service account oauth2 token self._authenticated_session = OAuth2Session(client_id=oauth2_client_data["client_id"], token=dict(access_token=token), From 0733ef6b6db68cfa217aee97c585ef34a4d72ec4 Mon Sep 17 00:00:00 2001 From: Trent Smith Date: Tue, 11 Sep 2018 14:51:23 -0400 Subject: [PATCH 3/3] removing extras kwargs --- hca/util/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hca/util/__init__.py b/hca/util/__init__.py index f9ae6cfd..0b3bbb6c 100755 --- a/hca/util/__init__.py +++ b/hca/util/__init__.py @@ -120,7 +120,7 @@ def __init__(self, client, parameters, path_parameters, http_method, method_name self.__dict__.update(locals()) self._context_manager_response = None - def _request(self, req_args, url=None, stream=False, headers=None, **kwargs): + def _request(self, req_args, url=None, stream=False, headers=None): supplied_path_params = [p for p in req_args if p in self.path_parameters and req_args[p] is not None] if url is None: url = self.client.host + self.client.http_paths[self.method_name][frozenset(supplied_path_params)] @@ -363,7 +363,7 @@ def _get_jwt_from_service_account_credentials(self): algorithm='RS256').decode() return signed_jwt, exp - def get_authenticated_session(self, **kwargs): + def get_authenticated_session(self): if self._authenticated_session is None: oauth2_client_data = self.application_secrets["installed"] if 'GOOGLE_APPLICATION_CREDENTIALS' in os.environ: