@@ -49,8 +49,6 @@ def lambda_handler(event, context):
4949 KeyError: If the secret json does not contain the expected keys
5050
5151 """
52- # Thick client to match functionality of cx_oracle
53- oracledb .init_oracle_client ()
5452
5553 arn = event ['SecretId' ]
5654 token = event ['ClientRequestToken' ]
@@ -327,18 +325,97 @@ def get_connection(secret_dict):
327325 """
328326 # Parse and validate the secret JSON string
329327 port = str (secret_dict ['port' ]) if 'port' in secret_dict else '1521'
328+ use_ssl , fall_back = get_ssl_config (secret_dict )
330329
331- # Try to obtain a connection to the db
330+ conn = connect_and_authenticate (secret_dict , port , use_ssl )
331+
332+ if conn or not fall_back :
333+ return conn
334+ else :
335+ return connect_and_authenticate (secret_dict , port , False )
336+
337+
338+ def connect_and_authenticate (secret_dict , port , use_ssl ):
339+ """Connects to Oracle DB and authenticates
340+
341+ This helper function tries to connect to the database using the supplied
342+ connection parameters and authenticates. If successful, it returns the
343+ connection, else None
344+
345+ Args:
346+ secret_dict (dict): The Secret Dictionary
347+
348+ port (str): The database connection port
349+
350+ use_ssl (bool): Flag indicating whether to use SSL/TLS encryption
351+
352+ Returns:
353+ Connection: The oracledb.Connection object if successful. None otherwise
354+
355+ Raises:
356+ KeyError: If the secret json does not contain the expected keys
357+
358+ """
332359 try :
333- conn = oracledb .connect (user = secret_dict ['username' ],
334- password = secret_dict ['password' ],
335- dsn = secret_dict ['host' ] + ':' + port + '/' + secret_dict ['dbname' ])
360+ if use_ssl :
361+ oracle_dsn = '''(description= (address=(protocol=tcps)
362+ (port=''' + port + ''')(host=''' + secret_dict ['host' ] + '''))(connect_data=(SID=''' + secret_dict ['dbname' ] + ''')))'''
363+ conn = oracledb .connect (user = secret_dict ['username' ],
364+ password = secret_dict ['password' ],
365+ dsn = oracle_dsn )
366+ elif not use_ssl :
367+ conn = oracledb .connect (user = secret_dict ['username' ],
368+ password = secret_dict ['password' ],
369+ dsn = secret_dict ['host' ] + ':' + port + '/' + secret_dict ['dbname' ])
336370 logger .info ("Successfully established connection as user '%s' with host: '%s'" % (secret_dict ['username' ], secret_dict ['host' ]))
371+
337372 return conn
338373 except (oracledb .DatabaseError , oracledb .OperationalError ):
339374 return None
340375
341376
377+ def get_ssl_config (secret_dict ):
378+ """Gets the desired SSL and fall back behavior using a secret dictionary
379+
380+ This helper function uses the existance and value the 'ssl' key in a secret dictionary
381+ to determine desired SSL connectivity configuration. Its behavior is as follows:
382+ - 'ssl' key DNE or invalid type/value: return True, True
383+ - 'ssl' key is bool: return secret_dict['ssl'], False
384+ - 'ssl' key equals "true" ignoring case: return True, False
385+ - 'ssl' key equals "false" ignoring case: return False, False
386+
387+ Args:
388+ secret_dict (dict): The Secret Dictionary
389+
390+ Returns:
391+ Tuple(use_ssl, fall_back): SSL configuration
392+ - use_ssl (bool): Flag indicating if an SSL connection should be attempted
393+ - fall_back (bool): Flag indicating if non-SSL connection should be attempted if SSL connection fails
394+
395+ """
396+ # Default to True for SSL and fall_back mode if 'ssl' key DNE
397+ if 'ssl' not in secret_dict :
398+ return True , True
399+
400+ # Handle type bool
401+ if isinstance (secret_dict ['ssl' ], bool ):
402+ return secret_dict ['ssl' ], False
403+
404+ # Handle type string
405+ if isinstance (secret_dict ['ssl' ], str ):
406+ ssl = secret_dict ['ssl' ].lower ()
407+ if ssl == "true" :
408+ return True , False
409+ elif ssl == "false" :
410+ return False , False
411+ else :
412+ # Invalid string value, default to True for both SSL and fall_back mode
413+ return True , True
414+
415+ # Invalid type, default to True for both SSL and fall_back mode
416+ return True , True
417+
418+
342419def get_secret_dict (service_client , arn , stage , token = None , master_secret = False ):
343420 """Gets the secret dictionary corresponding for the secret arn, stage, and token
344421
0 commit comments