use of io.milton.resource.LdapContact in project lobcder by skoulouzis.
the class SearchRunnable method contactFind.
/**
* Search users in contacts folder
*
* @param condition search filter
* @param returningAttributes requested attributes
* @param maxCount maximum item count
* @return List of users
* @throws IOException on error
*/
public Set<LdapContact> contactFind(Condition condition, Set<String> returningAttributes, int maxCount) throws IOException {
Set<LdapContact> results = new HashSet<LdapContact>();
List<LdapContact> contacts = user.searchContacts(condition, maxCount);
LogUtils.trace(log, "contactFind: contacts size:", contacts.size());
for (LdapContact contact : contacts) {
results.add(contact);
}
return results;
}
use of io.milton.resource.LdapContact in project lobcder by skoulouzis.
the class CompoundLdapFilter method findInGAL.
/**
* Find persons in Exchange GAL matching filter.
* Iterate over child filters to build results.
*
* @param user Exchange session
* @return persons map
* @throws IOException on error
*/
@Override
public List<LdapContact> findInGAL(LdapPrincipal user, Set<String> returningAttributes, int sizeLimit) throws IOException, NotAuthorizedException, BadRequestException {
List<LdapContact> persons = null;
for (LdapFilter child : criteria) {
int currentSizeLimit = sizeLimit;
if (persons != null) {
currentSizeLimit -= persons.size();
}
List<LdapContact> childFind = child.findInGAL(user, returningAttributes, currentSizeLimit);
if (childFind != null) {
if (persons == null) {
persons = childFind;
} else if (type == Ldap.LDAP_FILTER_OR) {
// Create the union of the existing results and the child found results
persons.addAll(childFind);
} else if (type == Ldap.LDAP_FILTER_AND) {
// all filters.
for (LdapContact result : childFind) {
if (isMatch(result)) {
// This item from the child result set matches all sub-criteria, add it
persons.add(result);
}
}
}
}
}
if ((persons == null) && !isFullSearch()) {
// return an empty map (indicating no results were found)
return new ArrayList<LdapContact>();
}
return persons;
}
use of io.milton.resource.LdapContact in project lobcder by skoulouzis.
the class SearchRunnable method sendPersons.
private void sendPersons(int currentMessageId, String baseContext, Set<LdapContact> persons, Set<String> returningAttributes) throws IOException, NotAuthorizedException, BadRequestException {
LogUtils.debug(log, "sendPersons", baseContext, "size:", persons.size());
boolean needObjectClasses = returningAttributes.contains("objectclass") || returningAttributes.isEmpty();
boolean returnAllAttributes = returningAttributes.isEmpty();
if (persons.isEmpty()) {
log.warn("No contacts to send! -------------------");
}
for (LdapContact person : persons) {
if (abandon) {
log.warn("Abandon flag is set, so exiting send!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
break;
}
Map<String, Object> response = new HashMap<String, Object>();
Set<LdapMappedProp> props = propertyMapper.mapProperties(returnAllAttributes, returningAttributes, person);
response.put("uid", person.getName());
for (LdapMappedProp prop : props) {
ValueAndType vt;
try {
vt = propertyMapper.getProperty(prop.mappedName, person);
} catch (NotAuthorizedException ex) {
vt = null;
}
if (vt == null) {
LogUtils.trace(log, "sendPersons: property not found: ldap property: ", prop.ldapName, " - dav prop: ", prop.mappedName, "resource: ", person.getClass());
} else {
if (vt.getValue() != null) {
response.put(prop.ldapName, vt.getValue());
}
}
}
// Process all attributes which have static mappings
for (Map.Entry<String, String> entry : Ldap.STATIC_ATTRIBUTE_MAP.entrySet()) {
String ldapAttribute = entry.getKey();
String value = entry.getValue();
if (value != null && (returnAllAttributes || returningAttributes.contains(ldapAttribute))) {
response.put(ldapAttribute, value);
}
}
if (needObjectClasses) {
response.put("objectClass", Ldap.PERSON_OBJECT_CLASSES);
}
// iCal: copy email to apple-generateduid, encode @
if (returnAllAttributes || returningAttributes.contains("apple-generateduid")) {
String mail = (String) response.get("mail");
if (mail != null) {
response.put("apple-generateduid", mail.replaceAll("@", "__AT__"));
} else {
// failover, should not happen
// failover, should not happen
response.put("apple-generateduid", response.get("uid"));
}
}
// iCal: replace current user alias with login name
if (user.getName().equals(response.get("uid"))) {
if (returningAttributes.contains("uidnumber")) {
response.put("uidnumber", user.getName());
}
}
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_SEND_PERSON", currentMessageId, response.get("uid"), baseContext, response);
responseHandler.sendEntry(currentMessageId, "uid=" + response.get("uid") + baseContext, response);
}
}
use of io.milton.resource.LdapContact in project lobcder by skoulouzis.
the class SearchRunnable method run.
@Override
public void run() {
try {
int size = 0;
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH", currentMessageId, dn, scope, sizeLimit, timelimit, ldapFilter.toString(), returningAttributes);
if (scope == Ldap.SCOPE_BASE_OBJECT) {
log.debug("Check type of search... scope is BASE OBJECT");
if ("".equals(dn)) {
size = 1;
log.info("send root DSE");
responseHandler.sendRootDSE(currentMessageId);
} else if (Ldap.BASE_CONTEXT.equals(dn)) {
size = 1;
// root
// root
log.info("send base context");
responseHandler.sendBaseContext(currentMessageId);
} else if (dn.startsWith("uid=") && dn.indexOf(',') > 0) {
if (user != null) {
// single user request
// single user request
String uid = dn.substring("uid=".length(), dn.indexOf(','));
Set<LdapContact> persons = null;
// first search in contact
try {
// check if this is a contact uid
Integer.parseInt(uid);
persons = contactFind(conditions.isEqualTo("imapUid", uid), returningAttributes, sizeLimit);
} catch (NumberFormatException e) {
// ignore, this is not a contact uid
}
// then in GAL
if (persons == null || persons.isEmpty()) {
List<LdapContact> galContacts = null;
try {
log.info("do GAL search: " + uid);
galContacts = userFactory.galFind(conditions.isEqualTo("imapUid", uid), sizeLimit);
} catch (NotAuthorizedException ex) {
log.error("not auth", ex);
} catch (BadRequestException ex) {
log.error("bad req", ex);
}
if (galContacts != null && galContacts.size() > 0) {
LdapContact person = galContacts.get(0);
if (persons == null) {
persons = new HashSet<LdapContact>();
}
persons.add(person);
}
}
size = persons == null ? 0 : persons.size();
try {
sendPersons(currentMessageId, dn.substring(dn.indexOf(',')), persons, returningAttributes);
} catch (NotAuthorizedException ex) {
log.error("Not authorised", ex);
} catch (BadRequestException ex) {
log.error("bad req", ex);
}
} else {
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_ANONYMOUS_ACCESS_FORBIDDEN", currentMessageId, dn);
}
} else {
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_INVALID_DN (1)", currentMessageId, dn);
}
} else if (Ldap.COMPUTER_CONTEXT.equals(dn) || Ldap.COMPUTER_CONTEXT_LION.equals(dn)) {
size = 1;
// computer context for iCal
log.info("send computer context");
responseHandler.sendComputerContext(currentMessageId, returningAttributes);
} else if ((// Outlook 2010 by default sends no DN
dn.equals("") || Ldap.BASE_CONTEXT.equalsIgnoreCase(dn) || Ldap.OD_USER_CONTEXT.equalsIgnoreCase(dn)) || Ldap.MSLIVE_BASE_CONTEXT.equals(dn) || Ldap.OD_USER_CONTEXT_LION.equalsIgnoreCase(dn)) {
log.info("not a weird search... check for normal conditions");
if (user != null) {
log.debug("we have a user...");
Set<LdapContact> persons = new HashSet<LdapContact>();
if (ldapFilter.isFullSearch()) {
// append personal contacts first
log.info("do personcal contact search");
Set<LdapContact> contacts = contactFind(null, returningAttributes, sizeLimit);
LogUtils.debug(log, "fullSearch: results:", contacts.size());
for (LdapContact person : contacts) {
persons.add(person);
if (persons.size() == sizeLimit) {
break;
}
}
// full search
for (char c = 'A'; c <= 'Z'; c++) {
if (!abandon && persons.size() < sizeLimit) {
Condition startsWith = conditions.startsWith("cn", String.valueOf(c));
Collection<LdapContact> galContacts = null;
try {
log.info("now do GAL search");
galContacts = userFactory.galFind(startsWith, sizeLimit);
} catch (NotAuthorizedException ex) {
log.error("not auth", ex);
} catch (BadRequestException ex) {
log.error("bad req", ex);
}
if (galContacts != null) {
LogUtils.debug(log, "doSearch: results:", contacts.size());
for (LdapContact person : galContacts) {
persons.add(person);
if (persons.size() == sizeLimit) {
break;
}
}
}
}
if (persons.size() == sizeLimit) {
break;
}
}
} else {
// append only personal contacts
log.info("do personcal contact search only");
Condition filter = ldapFilter.getContactSearchFilter();
LogUtils.debug(log, "not full search:", filter);
// ignored all attribute filters => return empty results
if (ldapFilter.isFullSearch() || filter != null) {
Set<LdapContact> contacts = contactFind(filter, returningAttributes, sizeLimit);
for (LdapContact person : contacts) {
persons.add(person);
if (persons.size() == sizeLimit) {
log.debug("EXceeded size limit1");
break;
}
}
LogUtils.trace(log, "local contacts result size: ", persons.size());
if (!abandon && persons.size() < sizeLimit) {
List<LdapContact> galContacts = null;
try {
galContacts = ldapFilter.findInGAL(user, returningAttributes, sizeLimit - persons.size());
} catch (NotAuthorizedException ex) {
log.error("not auth", ex);
} catch (BadRequestException ex) {
log.error("bad req", ex);
}
if (galContacts != null) {
LogUtils.trace(log, "gal contacts result size: ", galContacts.size());
for (LdapContact person : galContacts) {
if (persons.size() >= sizeLimit) {
log.debug("EXceeded size limit2");
break;
}
LogUtils.trace(log, "add contact to results: ", person.getName());
persons.add(person);
}
}
}
}
}
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_FOUND_RESULTS", currentMessageId, persons.size());
try {
sendPersons(currentMessageId, ", " + dn, persons, returningAttributes);
} catch (NotAuthorizedException ex) {
log.error("not auth", ex);
} catch (BadRequestException ex) {
log.error("bad req", ex);
}
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_END", currentMessageId);
} else {
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_ANONYMOUS_ACCESS_FORBIDDEN", currentMessageId, dn);
}
} else if (dn != null && dn.length() > 0 && !Ldap.OD_CONFIG_CONTEXT.equals(dn) && !Ldap.OD_GROUP_CONTEXT.equals(dn)) {
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_INVALID_DN (2)", currentMessageId, dn);
log.debug("DN is not equal to: " + Ldap.OD_CONFIG_CONTEXT + " or " + Ldap.OD_GROUP_CONTEXT + " or any other valid pattern. Is: " + dn);
} else {
log.warn("Search criteria didnt match any of the expected patterns. Perhaps the user name is missing a context? DN=" + dn + ", expected something like: " + Ldap.OD_USER_CONTEXT);
}
// iCal: do not send LDAP_SIZE_LIMIT_EXCEEDED on apple-computer search by cn with sizelimit 1
if (size > 1 && size == sizeLimit) {
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_SIZE_LIMIT_EXCEEDED", currentMessageId);
responseHandler.sendClient(currentMessageId, Ldap.LDAP_REP_RESULT, Ldap.LDAP_SIZE_LIMIT_EXCEEDED, "");
} else {
log.debug("No search results");
LogUtils.debug(log, "LOG_LDAP_REQ_SEARCH_SUCCESS", currentMessageId);
responseHandler.sendClient(currentMessageId, Ldap.LDAP_REP_RESULT, Ldap.LDAP_SUCCESS, "");
}
} catch (SocketException e) {
log.warn("closed connection", e);
} catch (IOException e) {
log.error("", e);
try {
responseHandler.sendErr(currentMessageId, Ldap.LDAP_REP_RESULT, e);
} catch (IOException e2) {
LogUtils.debug(log, "LOG_EXCEPTION_SENDING_ERROR_TO_CLIENT", e2);
}
} finally {
log.debug("search complete");
searchManager.searchComplete(uuid, currentMessageId);
}
}
Aggregations