{
user = getUserModule().findUserById(user.getId());
}
catch(NoSuchUserException e)
{
throw new IdentityException("Illegal state - cached user doesn't exist in identity store: ", e);
}
}
LDAPUserImpl ldapUser = null;
if (user instanceof LDAPUserImpl)
{
ldapUser = (LDAPUserImpl)user;
}
else
{
throw new IllegalArgumentException("UserMembershipModuleImpl supports only LDAPUserImpl objects");
}
//First build a list of roles DNs to add
List roleDNsToAdd = new LinkedList();
for (Iterator iterator = roles.iterator(); iterator.hasNext();)
{
try
{
LDAPRoleImpl role = (LDAPRoleImpl)iterator.next();
roleDNsToAdd.add(role.getDn());
}
catch(ClassCastException e)
{
throw new IdentityException("Only can add LDAPRoleImpl objects", e);
}
}
String memberName=null;
//Find all the roles that currently contain user as member (need to remove user from some of them)
if (isUidAttributeIsDN())
{
memberName = ldapUser.getDn();
}
else
{
//memberName = ldapUser.getId().toString();
memberName = ldapUser.getUserName();
}
LdapContext ldapContext = getConnectionContext().createInitialContext();
try
{
String filter = getMemberAttributeID().concat("=").concat(memberName);
log.debug("Search filter: " + filter);
List sr = getRoleModule().searchRoles(filter, null);
//iterate over roles that contain a user
for (Iterator iterator = sr.iterator(); iterator.hasNext();)
{
SearchResult res = (SearchResult)iterator.next();
DirContext ctx = (DirContext)res.getObject();
String roleDN = ctx.getNameInNamespace();
ctx.close();
//if role is one which we want to add
if (roleDNsToAdd.contains(roleDN))
{
//we do nothing but mark this role as added
roleDNsToAdd.remove(roleDN);
continue;
}
//if it's not on the list we need to remove user from it
else
{
//obtain Role entry attributes from directory
Attributes attrs = ldapContext.getAttributes(roleDN, new String[] {getMemberAttributeID()});
//log.debug("Role attributes: " + attrs);
if (attrs == null)
{
throw new IdentityException("Cannot find Role with DN: " + roleDN);
}
Attribute attr = attrs.get(getMemberAttributeID());
//can't remove the last member (if the attribute is required by schema)
//TODO: workaround this somehow.... (adding goofy user or admin instead?)
if (!(attr.size() == 1 && isMembershipAttributeRequired()))
{
//remove user name from the member list
attr.remove(memberName);
//and replace attributes
Attributes newAttrs = new BasicAttributes(true);
//newAttrs.put(getMemberAttributeID(), attr);
newAttrs.put(attr);
ldapContext.modifyAttributes(roleDN, DirContext.REPLACE_ATTRIBUTE, newAttrs);
}
else
{
log.error("Couldn't remove user from role as it was the last member - possibly required field in ldap");
}
//and mark this role as done
roleDNsToAdd.remove(roleDN);
}
}
//now iterate over roles that left to process
for (Iterator iterator = roleDNsToAdd.iterator(); iterator.hasNext();)
{
String roleDN = (String)iterator.next();
//changes to make
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
new BasicAttribute(getMemberAttributeID(), memberName));
// Perform the requested modifications on the named object
ldapContext.modifyAttributes(roleDN, mods);
}
fireMembershipChangedEvent(user, roles);
//and that should be all...
}
catch (NamingException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
finally
{
try
{
ldapContext.close();
}
catch (NamingException e)
{
throw new IdentityException("Failed to close LDAP connection", e);
}
}