Announcement Announcement Module
Collapse
No announcement yet.
Leaf Nodes Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Leaf Nodes

    I am currently using WebSphere Portal, and the WebSphere LDAP interfaces (PUMA). However, I have had very little success using their interfaces. Before I invest a bunch of time trying to integrate Spring, I wanted to know if anyone has come across the following in Spring:

    Scenario: We manage authentication via LDAP. When a new employee is hired, we add them to the LDAP, and set a flag for them to reset their password. When the user completes this process, a "Leaf Node" (aka terminal node, or sub-node) is created, which states that they have reset their password.

    - ActiveDirectory Hierarchy
    ->OU=MIS
    --->OU=AppDev
    ----->CN=bobsmith
    --------->...
    --------->CN=pwdReset
    --------->...
    ----->CN=janedoe
    --------->...

    Notice that bobsmith has "CN=pwdReset" because he has already reset his password. But, janedoe has not reset her password, and so there is no "Leaf Node". They each have all sorts of other attributes (hence the "..."), and I am able to pull all of those attributes back, but I cannot pull back this pwdReset attribute.

    When I look at the ActiveDirectory through an LDAP Browser, the "CN=pwdReset" is of type "entry", while all of the other attributes are of the type "text attribute".

    **************** code to pull back Attributes (specifically: user.getAttributeNames()
    PortletServiceHome psh;

    try {
    // get the puma user object
    javax.naming.Context ctx = new javax.naming.InitialContext();
    psh = (PortletServiceHome) ctx.lookup("portletservice/com.ibm.portal.um.portletservice.PumaHome");

    if (psh != null) {
    PumaHome service = (PumaHome) psh
    .getPortletService(PumaHome.class);
    PumaProfile pp = service.getProfile(request);
    User user = (User) pp.getCurrentUser();

    if(logger.isDebugEnabled()){
    logger.debug("===== Begin attributes for user: " + currentUsername);
    Enumeration attributeNamesEnum = user.getAttributeNames();
    while (attributeNamesEnum.hasMoreElements()) {
    String attributeName = (String) attributeNamesEnum
    .nextElement();
    logger.debug(attributeName + " = " + user.get(attributeName));
    }

    List attrs = pp.getDefinedUserAttributeDefinitions();

    com.ibm.portal.puma.User usr = (com.ibm.portal.puma.User) pp.getCurrentUser();
    logger.debug("\t user = " + usr); // "CN=pwdReset" is not displayed here either
    }
    }

    } catch (Exception e) {
    e.printStackTrace();
    }

    This code allows me to pull back all of the other attributes, but it does not bring back "CN=pwdReset".

    Any thoughts or suggestions would be appreciated on how to pull back this pwdReset "Leaf Node"

  • #2
    If it is an entry, then you won't find it in the attributes list. You need to look up the entry explicitly. Here is an integration test that succeeds if there is a subnode "cn=pwdReset", and fails if there is none:

    Code:
    	@Autowired
    	private LdapTemplate tested;
    	...
    	@Test
    	public void testLookupPwdResetAsSubNode() {
    		Object result = null;
    		try {
    			result = tested.lookup("cn=pwdReset,cn=Some Person,ou=company1,c=Sweden");
    		}
    		catch (NameNotFoundException e) {
    			// do nothing, which should leave result as null
    		}
    		assertNotNull("null result means cn=pwdReset was not found", result);
    	}
    If there are attributes in this subnode that you need to examine, you can either do that directly in the ContextMapper or add the attributes to a Map and do it afterwards, like here:

    Code:
    	@Test
    	public void testLookupPwdResetAsSubNodeAndExamineAttributes() {
    		SimpleLdapTemplate simpleLdapTemplate = new SimpleLdapTemplate(tested);
    		ParameterizedContextMapper<Map<String, String>> mapper = new ParameterizedContextMapper<Map<String, String>>() {
    			public Map<String, String> mapFromContext(Object ctx) {
    				DirContextAdapter adapter = (DirContextAdapter) ctx;
    				HashMap<String, String> map = new HashMap<String, String>();
    				map.put("description", adapter.getStringAttribute("description"));
    				map.put("l", adapter.getStringAttribute("l"));
    				return map;
    			}
    		};
    		Map<String, String> result = null;
    		try {
    			result = simpleLdapTemplate.lookup("cn=pwdReset,cn=Some Person,ou=company1,c=Sweden",
    					mapper);
    		}
    		catch (NameNotFoundException e) {
    			// do nothing, which should leave result as null
    		}
    		assertNotNull("null result means cn=pwdReset was not found", result);
    		assertEquals("This user has successfully reset his/her password", result.get("description"));
    		assertEquals("Whad did the 'l' attribute mean again?", result.get("l"));
    	}
    You can also search for all pwdReset subnodes, in order to find all users that have reset their password:

    Code:
    	@Test
    	public void testSearchForAllPwdResetSubNodes() {
    		List list = tested.search("", "(cn=pwdReset)", new AbstractContextMapper() {
    			@Override
    			protected Object doMapFromContext(DirContextOperations ctx) {
    				return ctx.getDn();
    			}
    		});
    		assertEquals(1, list.size());
    		DistinguishedName dn = (DistinguishedName) list.get(0);
    		dn.removeLast();
    		assertEquals("cn=Some Person,ou=company1,c=Sweden", dn.toString());
    	}
    Note that you need to remove the leaf from the DN in order to get the user's DN. I simply assert the DN is correct. You might want to perform another lookup on the user DN to get the user attributes.

    This subnode business seems a bit odd, though. Isn't there already a password policy in Active Directory, implemented as operational attributes?

    Comment


    • #3
      Thanks for the info Ulsa. I will try your suggestions first with WebSphere's PUMA interface, and if I cannot get them to work, I will try using Spring's LDAP.

      - Sean

      Comment


      • #4
        Well, WebSphere still sucks, but I digress....

        Thanks for the info Ulsa, I got it to work perfectly using Spring after many hours lost trying to access this "leaf node" via WebSphere's PUMA SPI.

        I must now integrate Spring into my portlets, so I can access the power of Spring. I needed to integrate it anyway, so now is as good a time as ever.

        Thanks,
        Sean

        Comment


        • #5
          If you have a Java project, of basically any size really, I think you should have Spring in there. The benefits are significant, regardless of how much of the framework you use. It'll probably improve the programming style of the project, but also affect how you yourself write and think of code in the future. Big words? I don't think so. I've seen it so many times now.

          Good luck.

          Comment

          Working...
          X