Skip to content

Commit 9088d63

Browse files
authored
Merge pull request #176 from adobe-apiplatform/issue-159
Fix #159 - more secure credential handling
2 parents a5d88f2 + df6d2d8 commit 9088d63

File tree

2 files changed

+58
-38
lines changed

2 files changed

+58
-38
lines changed

user_sync/app.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -233,25 +233,24 @@ def create_config_loader_options(args):
233233

234234
# --users
235235
users_args = args.users
236-
if users_args is not None:
237-
users_action = None if len(users_args) == 0 else user_sync.helper.normalize_string(users_args.pop(0))
238-
if (users_action == None or users_action == 'all'):
239-
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
240-
elif (users_action == 'file'):
241-
if len(users_args) == 0:
242-
raise AssertionException('Missing file path for --users %s [file_path]' % users_action)
243-
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_csv'
244-
config_options['directory_connector_overridden_options'] = {'file_path': users_args.pop(0)}
245-
elif (users_action == 'mapped'):
246-
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
247-
config_options['directory_group_mapped'] = True
248-
elif (users_action == 'group'):
249-
if len(users_args) == 0:
250-
raise AssertionException('Missing groups for --users %s [groups]' % users_action)
251-
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
252-
config_options['directory_group_filter'] = users_args.pop(0).split(',')
253-
else:
254-
raise AssertionException('Unknown argument --users %s' % users_action)
236+
users_action = None if not users_args else user_sync.helper.normalize_string(users_args.pop(0))
237+
if (users_action == None or users_action == 'all'):
238+
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
239+
elif (users_action == 'file'):
240+
if len(users_args) == 0:
241+
raise AssertionException('Missing file path for --users %s [file_path]' % users_action)
242+
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_csv'
243+
config_options['directory_connector_overridden_options'] = {'file_path': users_args.pop(0)}
244+
elif (users_action == 'mapped'):
245+
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
246+
config_options['directory_group_mapped'] = True
247+
elif (users_action == 'group'):
248+
if len(users_args) == 0:
249+
raise AssertionException('Missing groups for --users %s [groups]' % users_action)
250+
config_options['directory_connector_module_name'] = 'user_sync.connector.directory_ldap'
251+
config_options['directory_group_filter'] = users_args.pop(0).split(',')
252+
else:
253+
raise AssertionException('Unknown argument --users %s' % users_action)
255254

256255
username_filter_pattern = args.username_filter_pattern
257256
if (username_filter_pattern):

user_sync/config.py

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import logging
2222
import os
2323
import re
24+
import subprocess
2425
import types
2526

2627
import keyring
@@ -641,6 +642,7 @@ def load_sub_config(cls, filename):
641642
def load_other_config(cls, filename):
642643
'''
643644
same as load_root_config, but does no post-processing.
645+
:type filename: str
644646
'''
645647
return cls.load_from_yaml(filename, {})
646648

@@ -667,25 +669,41 @@ def load_from_yaml(cls, filename, path_keys):
667669
does the key have a default value so that must be added to
668670
the dictionary if there is not already a value found.
669671
'''
670-
cls.filepath = os.path.abspath(filename)
671-
cls.filename = os.path.split(cls.filepath)[1]
672-
cls.dirpath = os.path.dirname(cls.filepath)
673-
if not os.path.isfile(cls.filepath):
674-
raise AssertionException('No such configuration file: %s' % (cls.filepath,))
675-
676-
# read the dict from the YAML file
677-
try:
678-
with open(filename, 'r', 1) as input_file:
679-
yml = yaml.load(input_file)
680-
except IOError as e:
681-
# if a file operation error occurred while loading the
682-
# configuration file, swallow up the exception and re-raise this
683-
# as an configuration loader exception.
684-
raise AssertionException('Error reading configuration file: %s' % e)
685-
except yaml.error.MarkedYAMLError as e:
686-
# same as above, but indicate this problem has to do with
687-
# parsing the configuration file.
688-
raise AssertionException('Error parsing configuration file: %s' % e)
672+
if filename.startswith('$(') and filename.endswith(')'):
673+
# it's a command line to execute and read standard output
674+
dir_end = filename.index(']')
675+
if filename.startswith('$([') and dir_end > 0:
676+
dir = filename[3:dir_end]
677+
cmd = filename[dir_end+1:-1]
678+
else:
679+
dir = os.path.abspath(".")
680+
cmd = filename[3:-1]
681+
try:
682+
bytes = subprocess.check_output(cmd, cwd=dir, shell=True)
683+
yml = yaml.load(bytes)
684+
except subprocess.CalledProcessError as e:
685+
raise AssertionException("Error executing process '%s' in dir '%s': %s" % (cmd, dir, e))
686+
except yaml.error.MarkedYAMLError as e:
687+
raise AssertionException('Error parsing process YAML data: %s' % e)
688+
else:
689+
# it's a pathname to a configuration file to read
690+
cls.filepath = os.path.abspath(filename)
691+
if not os.path.isfile(cls.filepath):
692+
raise AssertionException('No such configuration file: %s' % (cls.filepath,))
693+
cls.filename = os.path.split(cls.filepath)[1]
694+
cls.dirpath = os.path.dirname(cls.filepath)
695+
try:
696+
with open(filename, 'r', 1) as input_file:
697+
yml = yaml.load(input_file)
698+
except IOError as e:
699+
# if a file operation error occurred while loading the
700+
# configuration file, swallow up the exception and re-raise this
701+
# as an configuration loader exception.
702+
raise AssertionException('Error reading configuration file: %s' % e)
703+
except yaml.error.MarkedYAMLError as e:
704+
# same as above, but indicate this problem has to do with
705+
# parsing the configuration file.
706+
raise AssertionException('Error parsing configuration file: %s' % e)
689707

690708
# process the content of the dict
691709
for path_key, options in path_keys.iteritems():
@@ -773,6 +791,9 @@ def relative_path(cls, val, must_exist):
773791
if not isinstance(val, types.StringTypes):
774792
raise AssertionException("Expected pathname for setting %s in config file %s" %
775793
(cls.key_path, cls.filename))
794+
if val.startswith('$(') and val.endswith(')'):
795+
# this presumes
796+
return "$([" + cls.dirpath + "]" + val[2:-1] + ")"
776797
if cls.dirpath and not os.path.isabs(val):
777798
val = os.path.abspath(os.path.join(cls.dirpath, val))
778799
if must_exist and not os.path.isfile(val):

0 commit comments

Comments
 (0)