1616LDAP_SEARCH_ATTRIBUTE_QUERY = '2'
1717SPAWNER_ATTRIBUTE = '3'
1818SPAWNER_USER_ATTRIBUTE = '4'
19+ LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY = '5'
1920
2021DYNAMIC_ATTRIBUTE_METHODS = (SPAWNER_SUBMIT_DATA ,
2122 LDAP_SEARCH_ATTRIBUTE_QUERY ,
2223 SPAWNER_ATTRIBUTE ,
23- SPAWNER_USER_ATTRIBUTE )
24+ SPAWNER_USER_ATTRIBUTE ,
25+ LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY )
2426INCREMENT_ATTRIBUTE = '1'
2527SEARCH_RESULT_OPERATION_ACTIONS = (INCREMENT_ATTRIBUTE ,)
2628
@@ -346,10 +348,8 @@ def perform_search_result_operation(logger, conn_manager, base_dn,
346348
347349
348350def get_interpolated_dynamic_attributes (logger , sources , dynamic_attributes ):
349- set_attributes = {}
351+ return_dict = {}
350352 for attr_key , attr_val in dynamic_attributes .items ():
351- # Check sources for LDAP_SEARCH_ATTRIBUTE_QUERY
352- # key response with values
353353 val = None
354354 if attr_val not in DYNAMIC_ATTRIBUTE_METHODS :
355355 logger .error ("LDAP - Illegal dynamic_attributes value: {}"
@@ -363,6 +363,14 @@ def get_interpolated_dynamic_attributes(logger, sources, dynamic_attributes):
363363 and sources [LDAP_SEARCH_ATTRIBUTE_QUERY ]:
364364 val = get_dict_key (sources [LDAP_SEARCH_ATTRIBUTE_QUERY ],
365365 attr_key )
366+ if attr_val == LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY :
367+ if LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY in sources \
368+ and sources [LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY ]:
369+ val = get_dict_key (sources [LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY ],
370+ attr_key )
371+ if isinstance (val , (list , set , tuple )):
372+ val = val [0 ]
373+
366374 if attr_val == SPAWNER_SUBMIT_DATA :
367375 if SPAWNER_SUBMIT_DATA in sources \
368376 and sources [SPAWNER_SUBMIT_DATA ]:
@@ -376,13 +384,11 @@ def get_interpolated_dynamic_attributes(logger, sources, dynamic_attributes):
376384 if SPAWNER_USER_ATTRIBUTE in sources \
377385 and sources [SPAWNER_USER_ATTRIBUTE ]:
378386 val = get_attr (sources [SPAWNER_USER_ATTRIBUTE ], attr_key )
379- if not val :
380- logger .error ("LDAP - Missing {} in {} which is required for {} in "
381- "get_interpolated_dynamic_attributes" .format (
382- attr_val , sources , attr_key ))
383- return False
384- set_attributes [attr_key ] = val
385- return set_attributes
387+ if val :
388+ return_dict [attr_key ] = val
389+ logger .debug ("LDAP - prepared interpolated_attributes {}" .format (
390+ return_dict ))
391+ return return_dict
386392
387393
388394def update_spawner_attributes (spawner , spawner_attributes ):
@@ -583,6 +589,7 @@ def setup_ldap_entry_hook(spawner):
583589 "LDAP - Retrived attributes {}" .format (attributes ))
584590 # Extract attributes from existing object
585591 sources = {LDAP_SEARCH_ATTRIBUTE_QUERY : attributes ,
592+ LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY : attributes ,
586593 SPAWNER_SUBMIT_DATA : ldap_dict ,
587594 SPAWNER_ATTRIBUTE : spawner ,
588595 SPAWNER_USER_ATTRIBUTE : spawner .user }
@@ -660,6 +667,8 @@ def setup_ldap_entry_hook(spawner):
660667 return False
661668 attributes [attr_key ] = post_operation_val
662669 sources .update ({LDAP_SEARCH_ATTRIBUTE_QUERY :
670+ {attr_key : post_operation_val },
671+ LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY :
663672 {attr_key : post_operation_val }})
664673
665674 ldap_dict .update (attributes )
@@ -671,26 +680,24 @@ def setup_ldap_entry_hook(spawner):
671680 spawner .log .debug (
672681 "LDAP - Sources state before interpolation "
673682 "with dynamic attributes {}" .format (sources ))
674- prepared_dynamic_attributes = get_interpolated_dynamic_attributes (
683+
684+ prepared_object_attributes = get_interpolated_dynamic_attributes (
675685 spawner .log , sources , instance .dynamic_attributes )
676- spawner .log .debug ("LDAP - dynamic_attributes "
677- "post interpolated: {}" .format (
678- prepared_dynamic_attributes ))
679-
680- if instance .dynamic_attributes and not prepared_dynamic_attributes :
681- spawner .log .error ("LDAP - Failed to setup prepared_attributes:"
682- " {} with attribute_dict: {}" .format (
683- prepared_dynamic_attributes , ldap_dict ))
686+
687+ spawner .log .debug ("LDAP - prepared_object_attributes:"
688+ " {}" .format (prepared_object_attributes ))
689+
690+ if instance .dynamic_attributes and not prepared_object_attributes :
691+ spawner .log .error ("LDAP - Failed to setup "
692+ "prepared_object_attributes: {} with "
693+ "attribute_dict: {}" .format (
694+ prepared_object_attributes , ldap_dict )
695+ )
684696 return False
685697
686698 # Format dn provided variables
687- recursive_format (instance .set_spawner_attributes ,
688- prepared_dynamic_attributes )
689699 recursive_format (instance .object_attributes ,
690- prepared_dynamic_attributes )
691-
692- spawner .log .debug ("LDAP - prepared spawner attributes {}" .format (
693- instance .set_spawner_attributes ))
700+ prepared_object_attributes )
694701 spawner .log .debug ("LDAP - prepared object attributes {}" .format (
695702 instance .object_attributes ))
696703
@@ -733,14 +740,41 @@ def setup_ldap_entry_hook(spawner):
733740 search_base , search_filter ))
734741 success = search_for (conn_manager .get_connection (),
735742 search_base ,
736- search_filter )
743+ search_filter ,
744+ attributes = ALL_ATTRIBUTES )
737745 if not success :
738746 spawner .log .error ("Failed to find {} at {}" .format (
739747 (search_base , search_filter ), instance .url ))
740748 return False
741749 spawner .log .info ("LDAP - found {} in {}" .format (
742750 conn_manager .get_response (), instance .url ))
743751
752+ response = conn_manager .get_response ()
753+ if len (response ) > 1 :
754+ spawner .log .error (
755+ "LDAP - multiple entries: {} were found with:"
756+ " {}" .format (response , search_filter ))
757+ return False
758+
759+ attributes = conn_manager .get_response_attributes ()
760+ # TODO, validate all the attributes are as expected
761+ if not attributes :
762+ spawner .log .error (
763+ "LDAP - No attributes were returned from "
764+ "existing dn: {} with search_filer: {}" .format (ldap_data ,
765+ search_filter ))
766+ return False
767+
768+ sources .update ({LDAP_SEARCH_ATTRIBUTE_QUERY : attributes ,
769+ LDAP_FIRST_SEARCH_ATTRIBUTE_QUERY : attributes })
770+ prepared_spawner_attributes = get_interpolated_dynamic_attributes (
771+ spawner .log , sources , instance .dynamic_attributes )
772+
773+ recursive_format (instance .set_spawner_attributes ,
774+ prepared_spawner_attributes )
775+ spawner .log .debug ("LDAP - formatted set_spawner_attributes: "
776+ "{} for the new entry: {}" .format (
777+ instance .set_spawner_attributes , attributes ))
744778 # Pass prepared attributes to spawner attributes
745779 update_spawner_attributes (spawner , instance .set_spawner_attributes )
746780 return True
0 commit comments