try {
final LdapContext ctx = getContext(invokingUser);
final SearchResult ldapUser = findAccountByAccountName(ctx, account.getName());
if(ldapUser == null) {
throw new AuthenticationException(AuthenticationException.ACCOUNT_NOT_FOUND, "Could not find the account in the LDAP");
}
return executeAsSystemUser(ctx, new Unit<Account>(){
@Override
public Account execute(LdapContext ctx, DBBroker broker) throws EXistException, PermissionDeniedException, NamingException {
int update = UPDATE_NONE;
//1) get the ldap group membership
final List<Group> memberOf_groups = getGroupMembershipForLdapUser(ctx, ldapUser);
//2) get the ldap primary group
final String primaryGroup = findGroupBySID(ctx, getPrimaryGroupSID(ldapUser));
//append the ldap primaryGroup to the head of the ldap group list, and compare
//to the account group list
memberOf_groups.add(0, getGroup(ctx, primaryGroup));
final String accountGroups[] = account.getGroups();
if(!accountGroups[0].equals(ensureCase(primaryGroup))) {
update |= UPDATE_GROUP;
} else {
if(accountGroups.length != memberOf_groups.size()) {
update |= UPDATE_GROUP;
} else {
for(int i = 0; i < accountGroups.length; i++) {
boolean found = false;
for(Group memberOf_group : memberOf_groups) {
if(accountGroups[i].equals(ensureCase(memberOf_group.getName()))) {
found = true;
break;
}
}
if(!found) {
update |= UPDATE_GROUP;
break;
}
}
}
}
//3) check metadata
final List<SimpleEntry<AXSchemaType, String>> ldapMetadatas = getMetadataForLdapUser(ldapUser);
final Set<SchemaType> accountMetadataKeys = account.getMetadataKeys();
if(accountMetadataKeys.size() != ldapMetadatas.size()) {
update |= UPDATE_METADATA;
} else {
for(SchemaType accountMetadataKey : accountMetadataKeys) {
final String accountMetadataValue = account.getMetadataValue(accountMetadataKey);
boolean found = false;
for(SimpleEntry<AXSchemaType, String> ldapMetadata : ldapMetadatas) {
if(accountMetadataKey.equals(ldapMetadata.getKey()) && accountMetadataValue.equals(ldapMetadata.getValue())) {
found = true;
break;
}
}
if(!found) {
update |= UPDATE_METADATA;
break;
}
}
}
//update the groups?
if((update & UPDATE_GROUP) == UPDATE_GROUP) {
try {
Field fld = account.getClass().getSuperclass().getDeclaredField("groups");
fld.setAccessible(true);
fld.set(account, memberOf_groups);
} catch(NoSuchFieldException nsfe) {
throw new EXistException(nsfe.getMessage(), nsfe);
} catch(IllegalAccessException iae) {
throw new EXistException(iae.getMessage(), iae);
}
}
//update the metdata?
if((update & UPDATE_METADATA) == UPDATE_METADATA) {
account.clearMetadata();
for(SimpleEntry<AXSchemaType, String> ldapMetadata : ldapMetadatas) {
account.setMetadataValue(ldapMetadata.getKey(), ldapMetadata.getValue());
}
}
if(update != UPDATE_NONE) {
boolean updated = getSecurityManager().updateAccount(account);
if(!updated) {
LOG.error("Could not update account");
}
}
return account;
}
});
} catch(final NamingException ne) {
throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, ne.getMessage(), ne);
} catch(final EXistException ee) {
throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, ee.getMessage(), ee);
}
}