Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions hydra_client/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
port = 8080
domain = '127.0.0.1'
json_path = 'json'
seed = 'changeme'
cache_password = True
cipherkey=b'M0EppyrL8yf9cTE7z5UywMBl1202aSTCntQ4ZFXLiiE='
72 changes: 61 additions & 11 deletions hydra_client/connection/base_connection.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from .. import config

import os
import logging
import collections
import six

import os
import tempfile
import getpass
import random
from cryptography.fernet import Fernet

import hydra_base

import getpass
from .. import config

import logging
log = logging.getLogger(__name__)

DEFAULT_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f000Z"
Expand Down Expand Up @@ -48,10 +49,6 @@ def get_url(self, url, path):

"""

#Remove trailing slashes
if len(url) > 0 and url[-1] == '/':
url = url[0:-1]

if url is None:
port = config.port
domain = config.domain
Expand All @@ -62,6 +59,11 @@ def get_url(self, url, path):
ret_url = "%s:%s/%s" % (domain, port, path)
else:
log.info("Using user-defined URL: %s", url)

#Remove trailing slashes
if len(url) > 0 and url[-1] == '/':
url = url[0:-1]

port = self.get_port(url)
hostname = self.get_hostname(url)
url_path = self.get_path(url)
Expand Down Expand Up @@ -183,6 +185,14 @@ def get_username_and_password(self, username, password):
else:
ret_username = username

#Check if the password is in a cache
password_cached = False
if password is None:
password = self.get_cached_password()
if password is not None:
password_cached = True


if password is None:
log.info("No password specified. Defaulting looking at 'HYDRA_PASSWORD'")

Expand All @@ -191,6 +201,46 @@ def get_username_and_password(self, username, password):
if ret_password is None:
ret_password = getpass.getpass()
else:
ret_password=password
ret_password = password

if config.cache_password is True and password_cached is False:
self.cache_password(ret_password)

return ret_username, ret_password

def cache_password(self, password):
"""
Save password to a cached file in /tmp.
"""
encrypter = Fernet(config.cipherkey)
encoded_text = encrypter.encrypt(password.encode('utf-8'))
tmp = tempfile.gettempdir()
random.seed(config.seed)
i = int(random.random() * 10e16)
filename = f'.{i}'
pwdfile = os.path.join(tmp, filename)
with open(pwdfile, 'w') as f:
f.write(encoded_text.decode('utf-8'))

def get_cached_password(self):
"""
Save password to a cached file in /tmp.
"""

encrypter = Fernet(config.cipherkey)
tmp = tempfile.gettempdir()
random.seed(config.seed)
i = int(random.random() * 10e16)
filename = f'.{i}'
pwdfile = os.path.join(tmp, filename)

if not os.path.exists(pwdfile):
return None
log.info("Using cached password")

with open(pwdfile, 'r') as f:
encoded_text = f.read()

password = encrypter.decrypt(encoded_text.encode('utf-8'))

return password.decode('utf-8')
16 changes: 13 additions & 3 deletions hydra_client/connection/remote_json_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

class RemoteJSONConnection(BaseConnection):
""" Remote connection to a Hydra server. """
def __init__(self, url=None, session_id=None, app_name=None, test_server=None):
def __init__(self, url=None, session_id=None, app_name=None, test_server=None, **kwargs):
"""
args:
url: The url of the hydra platform server
Expand All @@ -46,7 +46,7 @@ def __init__(self, url=None, session_id=None, app_name=None, test_server=None):
"""
super(RemoteJSONConnection, self).__init__(app_name=app_name)

self.user_id = None
self.user_id = None
self.url = self.get_url(url, 'json')
self.app_name = app_name if app_name else ''
self.session_id = session_id
Expand Down Expand Up @@ -134,6 +134,7 @@ def call(self, func, *args, **kwargs):
}
if func != 'login':
log.info("Args %s", call)

cookie = {'beaker.session.id':self.session_id,
'user_id': str(self.user_id),
'appname': self.app_name.replace(' ', '_')#for some reason, beaker fails when the appname cookie has a space in it
Expand Down Expand Up @@ -163,7 +164,7 @@ def call(self, func, *args, **kwargs):

if self.session_id is None:

self.session_id = r.cookies['beaker.session.id']
self.session_id = r.cookies.get('beaker.session.id')
log.info(self.session_id)

json_ret = json.loads(r.content)
Expand Down Expand Up @@ -199,6 +200,15 @@ def login(self, username=None, password=None):

return self.user_id, self.session_id

def get_remote_session(self, session_id):
resp = self.call('get_remote_session', {'session_id': session_id})
if resp.get('user_id') is not None:
log.info("Session found for user: %s", self.user_id)
else:
log.warning("No session found with ID %s", session_id)
self.login()



class JsonConnection(RemoteJSONConnection):
def __init__(self, *args, **kwargs):
Expand Down