2525import gc
2626import six
2727
28+ #
29+ # Allow override to specify the PAM password in effect for the test rodsuser.
30+ #
31+ TEST_PAM_PW_OVERRIDE = os .environ .get ('PYTHON_IRODSCLIENT_TEST_PAM_PW_OVERRIDE' ,'' )
32+ TEST_PAM_PW = TEST_PAM_PW_OVERRIDE or 'test123'
33+
34+ TEST_IRODS_PW = 'apass'
35+ TEST_RODS_USER = 'alissa'
36+
37+
2838try :
2939 from re import _pattern_type as regex_type
3040except ImportError :
@@ -117,21 +127,17 @@ class TestLogins(unittest.TestCase):
117127 3. Must add & override configuration entries in /var/lib/irods/irods_environment
118128 Per https://slides.com/irods/ugm2018-ssl-and-pam-configuration#/3/7
119129
120- 4. Create rodsuser alissa and corresponding unix user with the appropriate
121- passwords as below.
122130 '''
123131
124- test_rods_user = 'alissa'
125-
126132 user_auth_envs = {
127133 '.irods.pam' : {
128- 'USER' : test_rods_user ,
129- 'PASSWORD' : 'test123' , # UNIX pw
134+ 'USER' : TEST_RODS_USER ,
135+ 'PASSWORD' : TEST_PAM_PW ,
130136 'AUTH' : 'pam'
131137 },
132138 '.irods.native' : {
133- 'USER' : test_rods_user ,
134- 'PASSWORD' : 'apass' , # iRODS pw
139+ 'USER' : TEST_RODS_USER ,
140+ 'PASSWORD' : TEST_IRODS_PW ,
135141 'AUTH' : 'native'
136142 }
137143 }
@@ -151,13 +157,12 @@ def setenv(self,var,newvalue):
151157 else :
152158 os .environ [var ]= oldvalue
153159
154- @classmethod
155- def create_env_dirs (cls ):
160+ def create_env_dirs (self ):
156161 dirs = {}
157162 retval = []
158163 # -- create environment configurations and secrets
159164 with pam_password_in_plaintext ():
160- for dirname ,lookup in cls .user_auth_envs .items ():
165+ for dirname ,lookup in self .user_auth_envs .items ():
161166 if lookup ['AUTH' ] == 'pam' :
162167 ses = iRODSSession ( host = gethostname (),
163168 user = lookup ['USER' ],
@@ -174,7 +179,7 @@ def create_env_dirs(cls):
174179 #elif lookup['AUTH'] == 'XXXXXX': # TODO: insert other authentication schemes here
175180 elif lookup ['AUTH' ] in ('native' , '' ,None ):
176181 scrambled_pw = pw_encode ( lookup ['PASSWORD' ] )
177- cl_env = client_env_from_server_env (cls . test_rods_user )
182+ cl_env = client_env_from_server_env (TEST_RODS_USER )
178183 if lookup .get ('AUTH' ,None ) is not None : # - specify auth scheme only if given
179184 cl_env ['irods_authentication_scheme' ] = lookup ['AUTH' ]
180185 dirbase = os .path .join (os .environ ['HOME' ],dirname )
@@ -195,43 +200,22 @@ def create_env_dirs(cls):
195200 return retval
196201
197202
198- @staticmethod
199- def get_server_ssl_negotiation ( session ):
200-
201- rule_body = textwrap .dedent ('''
202- test { *out=""; acPreConnect(*out);
203- writeLine("stdout", "*out");
204- }
205- ''' )
206- myrule = Rule (session , body = rule_body , params = {}, output = 'ruleExecOut' )
207- out_array = myrule .execute ()
208- buf = out_array .MsParam_PI [0 ].inOutStruct .stdoutBuf .buf .decode ('utf-8' )
209- eol_offset = buf .find ('\n ' )
210- return buf [:eol_offset ] if eol_offset >= 0 else None
211-
212203 @classmethod
213204 def setUpClass (cls ):
214205 cls .admin = helpers .make_session ()
215- if cls .test_rods_user in (row [User .name ] for row in cls .admin .query (User .name )):
216- cls .server_ssl_setting = cls .get_server_ssl_negotiation ( cls .admin )
217- cls .envdirs = cls .create_env_dirs ()
218- if not cls .envdirs :
219- raise RuntimeError ('Could not create one or more client environments' )
220206
221207 @classmethod
222208 def tearDownClass (cls ):
223- for envdir in getattr (cls , 'envdirs' , []):
224- shutil .rmtree (envdir , ignore_errors = True )
225209 cls .admin .cleanup ()
226210
227211 def setUp (self ):
228- if not getattr (self , 'envdirs' , []):
229- self .skipTest ('The test_rods_user "{}" does not exist' .format (self .test_rods_user ))
230212 if os .environ ['HOME' ] != '/var/lib/irods' :
231213 self .skipTest ('Must be run as irods' )
232214 super (TestLogins ,self ).setUp ()
233215
234216 def tearDown (self ):
217+ for envdir in getattr (self , 'envdirs' , []):
218+ shutil .rmtree (envdir , ignore_errors = True )
235219 super (TestLogins ,self ).tearDown ()
236220
237221 def validate_session (self , session , verbose = False , ** options ):
@@ -241,97 +225,106 @@ def validate_session(self, session, verbose=False, **options):
241225 self .assertTrue (session .collections .get (home_coll ).path == home_coll )
242226 if verbose : print (home_coll )
243227 # - check user is as expected
244- self .assertEqual ( session .username , self . test_rods_user )
228+ self .assertEqual ( session .username , TEST_RODS_USER )
245229 # - check socket type (normal vs SSL) against whether ssl requested
246230 use_ssl = options .pop ('ssl' ,None )
247231 if use_ssl is not None :
248232 my_connect = [s for s in (session .pool .active | session .pool .idle )] [0 ]
249233 self .assertEqual ( bool ( use_ssl ), my_connect .socket .__class__ is ssl .SSLSocket )
250234
251235
252- # def test_demo(self): self.demo()
253-
254- # def demo(self): # for future reference - skipping based on CS_NEG_DONT_CARE setting
255- # if self.server_ssl_setting == 'CS_NEG_DONT_CARE':
256- # self.skipTest('skipping b/c setting is DONT_CARE')
257- # self.assertTrue (False)
236+ @contextlib .contextmanager
237+ def _setup_rodsuser_and_optional_pw (self , name , make_irods_pw = False ):
238+ try :
239+ self .admin .users .create (name , 'rodsuser' )
240+ if make_irods_pw :
241+ self .admin .users .modify (name ,'password' ,TEST_IRODS_PW )
242+ yield
243+ finally :
244+ self .admin .users .remove ( name )
258245
246+ def tst0 (self , ssl_opt , auth_opt , env_opt , name = TEST_RODS_USER , make_irods_pw = False ):
259247
260- def tst0 (self , ssl_opt , auth_opt , env_opt ):
261- auth_opt_explicit = 'native' if auth_opt == '' else auth_opt
262- verbosity = False
263- #verbosity='' # -- debug - sanity check by printing out options applied
264- out = {'' :'' }
265- if env_opt :
266- with self .setenv ('IRODS_ENVIRONMENT_FILE' , json_env_fullpath (auth_opt_explicit )) as env_file ,\
267- self .setenv ('IRODS_AUTHENTICATION_FILE' , secrets_fullpath (auth_opt_explicit )):
268- cli_env_extras = {} if not (ssl_opt ) else dict ( CLIENT_OPTIONS_FOR_SSL )
248+ with self ._setup_rodsuser_and_optional_pw (name = name , make_irods_pw = make_irods_pw ):
249+ self .envdirs = self .create_env_dirs ()
250+ if not self .envdirs :
251+ raise RuntimeError ('Could not create one or more client environments' )
252+ auth_opt_explicit = 'native' if auth_opt == '' else auth_opt
253+ verbosity = False
254+ #verbosity='' # -- debug - sanity check by printing out options applied
255+ out = {'' :'' }
256+ if env_opt :
257+ with self .setenv ('IRODS_ENVIRONMENT_FILE' , json_env_fullpath (auth_opt_explicit )) as env_file ,\
258+ self .setenv ('IRODS_AUTHENTICATION_FILE' , secrets_fullpath (auth_opt_explicit )):
259+ cli_env_extras = {} if not (ssl_opt ) else dict ( CLIENT_OPTIONS_FOR_SSL )
260+ if auth_opt :
261+ cli_env_extras .update ( irods_authentication_scheme = auth_opt )
262+ remove = []
263+ else :
264+ remove = [regex ('authentication_' )]
265+ with helpers .file_backed_up (env_file ):
266+ json_file_update ( env_file , keys_to_delete = remove , ** cli_env_extras )
267+ session = iRODSSession (irods_env_file = env_file )
268+ with open (env_file ) as f :
269+ out = json .load (f )
270+ self .validate_session ( session , verbose = verbosity , ssl = ssl_opt )
271+ session .cleanup ()
272+ out ['ARGS' ]= 'no'
273+ else :
274+ session_options = {}
269275 if auth_opt :
270- cli_env_extras .update ( irods_authentication_scheme = auth_opt )
271- remove = []
272- else :
273- remove = [regex ('authentication_' )]
274- with helpers .file_backed_up (env_file ):
275- json_file_update ( env_file , keys_to_delete = remove , ** cli_env_extras )
276- session = iRODSSession (irods_env_file = env_file )
277- with open (env_file ) as f :
278- out = json .load (f )
279- self .validate_session ( session , verbose = verbosity , ssl = ssl_opt )
280- session .cleanup ()
281- out ['ARGS' ]= 'no'
282- else :
283- session_options = {}
284- if auth_opt :
285- session_options .update (authentication_scheme = auth_opt )
286- if ssl_opt :
287- SSL_cert = CLIENT_OPTIONS_FOR_SSL ["irods_ssl_ca_certificate_file" ]
288- session_options .update (
289- ssl_context = ssl .create_default_context ( purpose = ssl .Purpose .SERVER_AUTH ,
290- capath = None ,
291- cadata = None ,
292- cafile = SSL_cert ),
293- ** CLIENT_OPTIONS_FOR_SSL )
294- lookup = self .user_auth_envs ['.irods.' + ('native' if not (auth_opt ) else auth_opt )]
295- session = iRODSSession ( host = gethostname (),
296- user = lookup ['USER' ],
297- zone = 'tempZone' ,
298- password = lookup ['PASSWORD' ],
299- port = 1247 ,
300- ** session_options )
301- out = session_options
302- self .validate_session ( session , verbose = verbosity , ssl = ssl_opt )
303- session .cleanup ()
304- out ['ARGS' ]= 'yes'
305-
306- if verbosity == '' :
307- print ('--- ssl:' ,ssl_opt ,'/ auth:' ,repr (auth_opt ),'/ env:' ,env_opt )
308- print ('--- > ' ,json .dumps ({k :v for k ,v in out .items () if k != 'ssl_context' },indent = 4 ))
309- print ('---' )
276+ session_options .update (authentication_scheme = auth_opt )
277+ if ssl_opt :
278+ SSL_cert = CLIENT_OPTIONS_FOR_SSL ["irods_ssl_ca_certificate_file" ]
279+ session_options .update (
280+ ssl_context = ssl .create_default_context ( purpose = ssl .Purpose .SERVER_AUTH ,
281+ capath = None ,
282+ cadata = None ,
283+ cafile = SSL_cert ),
284+ ** CLIENT_OPTIONS_FOR_SSL )
285+ lookup = self .user_auth_envs ['.irods.' + ('native' if not (auth_opt ) else auth_opt )]
286+ session = iRODSSession ( host = gethostname (),
287+ user = lookup ['USER' ],
288+ zone = 'tempZone' ,
289+ password = lookup ['PASSWORD' ],
290+ port = 1247 ,
291+ ** session_options )
292+ out = session_options
293+ self .validate_session ( session , verbose = verbosity , ssl = ssl_opt )
294+ session .cleanup ()
295+ out ['ARGS' ]= 'yes'
296+
297+ if verbosity == '' :
298+ print ('--- ssl:' ,ssl_opt ,'/ auth:' ,repr (auth_opt ),'/ env:' ,env_opt )
299+ print ('--- > ' ,json .dumps ({k :v for k ,v in out .items () if k != 'ssl_context' },indent = 4 ))
300+ print ('---' )
301+
302+
310303
311304 # == test defaulting to 'native'
312305
313306 def test_01 (self ):
314- self .tst0 ( ssl_opt = True , auth_opt = '' , env_opt = False )
307+ self .tst0 ( ssl_opt = True , auth_opt = '' , env_opt = False , make_irods_pw = True )
315308 def test_02 (self ):
316- self .tst0 ( ssl_opt = False , auth_opt = '' , env_opt = False )
309+ self .tst0 ( ssl_opt = False , auth_opt = '' , env_opt = False , make_irods_pw = True )
317310 def test_03 (self ):
318- self .tst0 ( ssl_opt = True , auth_opt = '' , env_opt = True )
311+ self .tst0 ( ssl_opt = True , auth_opt = '' , env_opt = True , make_irods_pw = True )
319312 def test_04 (self ):
320- self .tst0 ( ssl_opt = False , auth_opt = '' , env_opt = True )
313+ self .tst0 ( ssl_opt = False , auth_opt = '' , env_opt = True , make_irods_pw = True )
321314
322315 # == test explicit scheme 'native'
323316
324317 def test_1 (self ):
325- self .tst0 ( ssl_opt = True , auth_opt = 'native' , env_opt = False )
318+ self .tst0 ( ssl_opt = True , auth_opt = 'native' , env_opt = False , make_irods_pw = True )
326319
327320 def test_2 (self ):
328- self .tst0 ( ssl_opt = False , auth_opt = 'native' , env_opt = False )
321+ self .tst0 ( ssl_opt = False , auth_opt = 'native' , env_opt = False , make_irods_pw = True )
329322
330323 def test_3 (self ):
331- self .tst0 ( ssl_opt = True , auth_opt = 'native' , env_opt = True )
324+ self .tst0 ( ssl_opt = True , auth_opt = 'native' , env_opt = True , make_irods_pw = True )
332325
333326 def test_4 (self ):
334- self .tst0 ( ssl_opt = False , auth_opt = 'native' , env_opt = True )
327+ self .tst0 ( ssl_opt = False , auth_opt = 'native' , env_opt = True , make_irods_pw = True )
335328
336329 # == test explicit scheme 'pam'
337330
0 commit comments