mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 03:02:22 -05:00
LDAP: move galLookup to DavExchangeSession
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1333 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
905870f7da
commit
3d98a34328
@ -118,7 +118,6 @@ public abstract class ExchangeSession {
|
||||
|
||||
private final String userName;
|
||||
|
||||
private boolean disableGalLookup;
|
||||
protected static final String YYYY_MM_DD_HH_MM_SS = "yyyy/MM/dd HH:mm:ss";
|
||||
private static final String YYYYMMDD_T_HHMMSS_Z = "yyyyMMdd'T'HHmmss'Z'";
|
||||
protected static final String YYYY_MM_DD_T_HHMMSS_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
@ -2816,7 +2815,7 @@ public abstract class ExchangeSession {
|
||||
return results;
|
||||
}
|
||||
|
||||
public abstract Map<String, Contact> galFind(Condition condition) throws IOException;
|
||||
public abstract Map<String, Contact> galFind(Condition condition, Set<String> returningAttributes, int sizeLimit) throws IOException;
|
||||
|
||||
/**
|
||||
* Full Contact attribute list
|
||||
@ -2890,39 +2889,6 @@ public abstract class ExchangeSession {
|
||||
CONTACT_ATTRIBUTES.add("fburl");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extended address book information for person with gallookup.
|
||||
* Does not work with Exchange 2007
|
||||
*
|
||||
* @param person person attributes map
|
||||
*/
|
||||
public void galLookup(Map<String, String> person) {
|
||||
if (!disableGalLookup) {
|
||||
GetMethod getMethod = null;
|
||||
try {
|
||||
getMethod = new GetMethod(URIUtil.encodePathQuery(getCmdBasePath() + "?Cmd=gallookup&ADDR=" + person.get("EM")));
|
||||
DavGatewayHttpClientFacade.executeGetMethod(httpClient, getMethod, true);
|
||||
Map<String, Map<String, String>> results = XMLStreamUtil.getElementContentsAsMap(getMethod.getResponseBodyAsStream(), "person", "alias");
|
||||
// add detailed information
|
||||
if (!results.isEmpty()) {
|
||||
Map<String, String> fullperson = results.get(person.get("AN").toLowerCase());
|
||||
if (fullperson != null) {
|
||||
for (Map.Entry<String, String> entry : fullperson.entrySet()) {
|
||||
person.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Unable to gallookup person: " + person + ", disable GalLookup");
|
||||
disableGalLookup = true;
|
||||
} finally {
|
||||
if (getMethod != null) {
|
||||
getMethod.releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get freebusy data string from Exchange.
|
||||
*
|
||||
|
@ -198,6 +198,20 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
GALFIND_CRITERIA_MAP.put("apple-group-realname", "DP");
|
||||
}
|
||||
|
||||
static final HashSet<String> GALLOOKUP_ATTRIBUTES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
GALLOOKUP_ATTRIBUTES.add("givenname");
|
||||
GALLOOKUP_ATTRIBUTES.add("initials");
|
||||
GALLOOKUP_ATTRIBUTES.add("sn");
|
||||
GALLOOKUP_ATTRIBUTES.add("street");
|
||||
GALLOOKUP_ATTRIBUTES.add("st");
|
||||
GALLOOKUP_ATTRIBUTES.add("postalcode");
|
||||
GALLOOKUP_ATTRIBUTES.add("c");
|
||||
GALLOOKUP_ATTRIBUTES.add("departement");
|
||||
GALLOOKUP_ATTRIBUTES.add("mobile");
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange to LDAP attribute map
|
||||
*/
|
||||
@ -225,7 +239,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ExchangeSession.Contact> galFind(Condition condition) throws IOException {
|
||||
public Map<String, ExchangeSession.Contact> galFind(Condition condition, Set<String> returningAttributes, int sizeLimit) throws IOException {
|
||||
Map<String, ExchangeSession.Contact> contacts = new HashMap<String, ExchangeSession.Contact>();
|
||||
if (condition instanceof MultiCondition) {
|
||||
// TODO
|
||||
@ -242,9 +256,15 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
getMethod.releaseConnection();
|
||||
}
|
||||
LOGGER.debug("galfind " + searchAttribute + '=' + searchValue + ": " + results.size() + " result(s)");
|
||||
for (Map<String, String> result:results.values()) {
|
||||
Contact contact = buildGalfindContact(result);
|
||||
for (Map<String, String> result : results.values()) {
|
||||
Contact contact = new Contact();
|
||||
contact.setName(result.get("AN"));
|
||||
contact.put("uid", result.get("AN"));
|
||||
buildGalfindContact(contact, result);
|
||||
if (condition.isMatch(contact)) {
|
||||
if (needGalLookup(returningAttributes)) {
|
||||
galLookup(contact);
|
||||
}
|
||||
contacts.put(contact.getName().toLowerCase(), contact);
|
||||
}
|
||||
}
|
||||
@ -254,17 +274,63 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
protected Contact buildGalfindContact(Map<String, String> response) {
|
||||
Contact contact = new Contact();
|
||||
contact.setName(response.get("AN"));
|
||||
contact.put("uid", response.get("AN"));
|
||||
protected boolean needGalLookup(Set<String> returningAttributes) {
|
||||
// iCal search, do not call gallookup
|
||||
if (returningAttributes.contains("apple-serviceslocator")) {
|
||||
return false;
|
||||
// return all attributes => call gallookup
|
||||
} else if (returningAttributes.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String attributeName : GALLOOKUP_ATTRIBUTES) {
|
||||
if (returningAttributes.contains(attributeName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean disableGalLookup;
|
||||
|
||||
/**
|
||||
* Get extended address book information for person with gallookup.
|
||||
* Does not work with Exchange 2007
|
||||
*
|
||||
* @param contact galfind contact
|
||||
*/
|
||||
public void galLookup(Contact contact) {
|
||||
if (!disableGalLookup) {
|
||||
GetMethod getMethod = null;
|
||||
try {
|
||||
getMethod = new GetMethod(URIUtil.encodePathQuery(getCmdBasePath() + "?Cmd=gallookup&ADDR=" + contact.get("smtpemail1")));
|
||||
DavGatewayHttpClientFacade.executeGetMethod(httpClient, getMethod, true);
|
||||
Map<String, Map<String, String>> results = XMLStreamUtil.getElementContentsAsMap(getMethod.getResponseBodyAsStream(), "person", "alias");
|
||||
// add detailed information
|
||||
if (!results.isEmpty()) {
|
||||
Map<String, String> personGalLookupDetails = results.get(contact.get("uid").toLowerCase());
|
||||
if (personGalLookupDetails != null) {
|
||||
buildGalfindContact(contact, personGalLookupDetails);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Unable to gallookup person: " + contact + ", disable GalLookup");
|
||||
disableGalLookup = true;
|
||||
} finally {
|
||||
if (getMethod != null) {
|
||||
getMethod.releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void buildGalfindContact(Contact contact, Map<String, String> response) {
|
||||
for (Map.Entry<String, String> entry : GALFIND_ATTRIBUTE_MAP.entrySet()) {
|
||||
String attributeValue = response.get(entry.getValue());
|
||||
if (attributeValue != null) {
|
||||
contact.put(entry.getKey(), attributeValue);
|
||||
}
|
||||
}
|
||||
return contact;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -528,6 +594,15 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
}
|
||||
if ("urlcompname".equals(field.alias)) {
|
||||
buffer.append(StringUtil.encodeUrlcompname(value));
|
||||
} else if (field.isIntValue()) {
|
||||
// check value
|
||||
try {
|
||||
Integer.parseInt(value);
|
||||
buffer.append(value);
|
||||
} catch (NumberFormatException e) {
|
||||
// invalid value, replace with 0
|
||||
buffer.append('0');
|
||||
}
|
||||
} else {
|
||||
buffer.append(value);
|
||||
}
|
||||
|
@ -1280,17 +1280,17 @@ public class EwsExchangeSession extends ExchangeSession {
|
||||
return contact;
|
||||
}
|
||||
|
||||
public Map<String, ExchangeSession.Contact> galFind(Condition condition) throws IOException {
|
||||
public Map<String, ExchangeSession.Contact> galFind(Condition condition, Set<String> returningAttributes, int sizeLimit) throws IOException {
|
||||
Map<String, ExchangeSession.Contact> contacts = new HashMap<String, ExchangeSession.Contact>();
|
||||
if (condition instanceof MultiCondition) {
|
||||
List<Condition> conditions = ((MultiCondition) condition).getConditions();
|
||||
Operator operator = ((MultiCondition) condition).getOperator();
|
||||
if (operator == Operator.Or) {
|
||||
for (Condition innerCondition : conditions) {
|
||||
contacts.putAll(galFind(innerCondition));
|
||||
contacts.putAll(galFind(innerCondition, returningAttributes, sizeLimit));
|
||||
}
|
||||
} else if (operator == Operator.And && !conditions.isEmpty()) {
|
||||
Map<String, ExchangeSession.Contact> innerContacts = galFind(conditions.get(0));
|
||||
Map<String, ExchangeSession.Contact> innerContacts = galFind(conditions.get(0), returningAttributes, sizeLimit);
|
||||
for (ExchangeSession.Contact contact : innerContacts.values()) {
|
||||
if (condition.isMatch(contact)) {
|
||||
contacts.put(contact.getName().toLowerCase(), contact);
|
||||
|
@ -186,20 +186,6 @@ public class LdapConnection extends AbstractConnection {
|
||||
STATIC_ATTRIBUTE_MAP.put("apple-serviceslocator", COMPUTER_GUID + ':' + VIRTUALHOST_GUID + ":calendar");
|
||||
}
|
||||
|
||||
static final HashSet<String> EXTENDED_ATTRIBUTES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
EXTENDED_ATTRIBUTES.add("givenname");
|
||||
EXTENDED_ATTRIBUTES.add("initials");
|
||||
EXTENDED_ATTRIBUTES.add("sn");
|
||||
EXTENDED_ATTRIBUTES.add("street");
|
||||
EXTENDED_ATTRIBUTES.add("st");
|
||||
EXTENDED_ATTRIBUTES.add("postalcode");
|
||||
EXTENDED_ATTRIBUTES.add("c");
|
||||
EXTENDED_ATTRIBUTES.add("departement");
|
||||
EXTENDED_ATTRIBUTES.add("mobile");
|
||||
}
|
||||
|
||||
/**
|
||||
* LDAP to Exchange Criteria Map
|
||||
*/
|
||||
@ -846,7 +832,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
static interface LdapFilter {
|
||||
ExchangeSession.Condition getContactSearchFilter();
|
||||
|
||||
Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session) throws IOException;
|
||||
Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session, Set<String> returningAttributes, int sizeLimit) throws IOException;
|
||||
|
||||
void add(LdapFilter filter);
|
||||
|
||||
@ -973,11 +959,11 @@ public class LdapConnection extends AbstractConnection {
|
||||
* @return persons map
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session) throws IOException {
|
||||
public Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session, Set<String> returningAttributes, int sizeLimit) throws IOException {
|
||||
Map<String, ExchangeSession.Contact> persons = null;
|
||||
|
||||
for (LdapFilter child : criteria) {
|
||||
Map<String, ExchangeSession.Contact> childFind = child.findInGAL(session);
|
||||
Map<String, ExchangeSession.Contact> childFind = child.findInGAL(session, returningAttributes, sizeLimit);
|
||||
|
||||
if (childFind != null) {
|
||||
if (persons == null) {
|
||||
@ -1091,15 +1077,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
ExchangeSession.Condition condition = null;
|
||||
|
||||
if (operator == LDAP_FILTER_EQUALITY) {
|
||||
try {
|
||||
// check imapUid value
|
||||
if ("imapUid".equals(contactAttributeName)) {
|
||||
Integer.parseInt(value);
|
||||
}
|
||||
condition = session.isEqualTo(contactAttributeName, value);
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore condition
|
||||
}
|
||||
condition = session.isEqualTo(contactAttributeName, value);
|
||||
} else if ("*".equals(value)) {
|
||||
condition = session.not(session.isNull(contactAttributeName));
|
||||
// do not allow substring search on integer field imapUid
|
||||
@ -1120,7 +1098,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
return true;
|
||||
}
|
||||
|
||||
String personAttributeValue = person.get(getGalFindAttributeName());
|
||||
String personAttributeValue = person.get(attributeName);
|
||||
|
||||
if (personAttributeValue == null) {
|
||||
// No value to allow for filter match
|
||||
@ -1139,7 +1117,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session) throws IOException {
|
||||
public Map<String, ExchangeSession.Contact> findInGAL(ExchangeSession session, Set<String> returningAttributes, int sizeLimit) throws IOException {
|
||||
if (canIgnore) {
|
||||
return null;
|
||||
}
|
||||
@ -1148,7 +1126,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
|
||||
if (galFindAttributeName != null) {
|
||||
// quick fix for cn=* filter
|
||||
Map<String, ExchangeSession.Contact> galPersons = session.galFind(session.startsWith(attributeName, "*".equals(value) ? "A" : value));
|
||||
Map<String, ExchangeSession.Contact> galPersons = session.galFind(session.startsWith(attributeName, "*".equals(value) ? "A" : value), returningAttributes, sizeLimit);
|
||||
|
||||
if (operator == LDAP_FILTER_EQUALITY) {
|
||||
// Make sure only exact matches are returned
|
||||
@ -1278,7 +1256,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
|
||||
// then in GAL
|
||||
if (persons == null || persons.isEmpty()) {
|
||||
persons = session.galFind(session.isEqualTo("uid", uid));
|
||||
persons = session.galFind(session.isEqualTo("uid", uid), returningAttributes, sizeLimit);
|
||||
|
||||
ExchangeSession.Contact person = persons.get(uid.toLowerCase());
|
||||
// filter out non exact results
|
||||
@ -1315,7 +1293,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
// full search
|
||||
for (char c = 'A'; c < 'Z'; c++) {
|
||||
if (!abandon && persons.size() < sizeLimit) {
|
||||
for (ExchangeSession.Contact person : session.galFind(session.startsWith("uid", String.valueOf(c))).values()) {
|
||||
for (ExchangeSession.Contact person : session.galFind(session.startsWith("uid", String.valueOf(c)), returningAttributes, sizeLimit).values()) {
|
||||
persons.put(person.get("uid"), person);
|
||||
if (persons.size() == sizeLimit) {
|
||||
break;
|
||||
@ -1341,7 +1319,7 @@ public class LdapConnection extends AbstractConnection {
|
||||
}
|
||||
}
|
||||
if (!abandon && persons.size() < sizeLimit) {
|
||||
for (ExchangeSession.Contact person : ldapFilter.findInGAL(session).values()) {
|
||||
for (ExchangeSession.Contact person : ldapFilter.findInGAL(session, returningAttributes, sizeLimit).values()) {
|
||||
if (persons.size() == sizeLimit) {
|
||||
break;
|
||||
}
|
||||
@ -1446,19 +1424,6 @@ public class LdapConnection extends AbstractConnection {
|
||||
boolean needObjectClasses = returningAttributes.contains("objectclass") || returningAttributes.isEmpty();
|
||||
boolean iCalSearch = returningAttributes.contains("apple-serviceslocator");
|
||||
boolean returnAllAttributes = returningAttributes.isEmpty();
|
||||
boolean needDetails = returnAllAttributes;
|
||||
if (!needDetails) {
|
||||
for (String attributeName : EXTENDED_ATTRIBUTES) {
|
||||
if (returningAttributes.contains(attributeName)) {
|
||||
needDetails = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// iCal search, do not lookup details
|
||||
if (iCalSearch) {
|
||||
needDetails = false;
|
||||
}
|
||||
|
||||
for (ExchangeSession.Contact person : persons.values()) {
|
||||
if (abandon) {
|
||||
|
@ -48,20 +48,20 @@ public class TestEwsExchangeSession extends AbstractExchangeSessionTestCase {
|
||||
|
||||
public void testGalFind() throws IOException {
|
||||
// find a set of contacts
|
||||
Map<String, ExchangeSession.Contact> contacts = ewsSession.galFind(ewsSession.startsWith("cn", "a"));
|
||||
Map<String, ExchangeSession.Contact> contacts = ewsSession.galFind(ewsSession.startsWith("cn", "a"), null, 100);
|
||||
for (ExchangeSession.Contact contact : contacts.values()) {
|
||||
System.out.println(contact);
|
||||
}
|
||||
if (!contacts.isEmpty()) {
|
||||
ExchangeSession.Contact testContact = contacts.values().iterator().next();
|
||||
contacts = ewsSession.galFind(ewsSession.isEqualTo("cn", testContact.get("cn")));
|
||||
contacts = ewsSession.galFind(ewsSession.isEqualTo("cn", testContact.get("cn")), null, 100);
|
||||
assertEquals(1, contacts.size());
|
||||
contacts = ewsSession.galFind(ewsSession.isEqualTo("email1", testContact.get("email1")));
|
||||
contacts = ewsSession.galFind(ewsSession.isEqualTo("email1", testContact.get("email1")), null, 100);
|
||||
assertEquals(1, contacts.size());
|
||||
contacts = ewsSession.galFind(ewsSession.startsWith("email1", testContact.get("email1")));
|
||||
contacts = ewsSession.galFind(ewsSession.startsWith("email1", testContact.get("email1")), null, 100);
|
||||
assertEquals(1, contacts.size());
|
||||
contacts = ewsSession.galFind(ewsSession.and(ewsSession.isEqualTo("cn", testContact.get("cn")),
|
||||
ewsSession.startsWith("email1", testContact.get("email1"))));
|
||||
ewsSession.startsWith("email1", testContact.get("email1"))), null, 100);
|
||||
assertEquals(1, contacts.size());
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,15 @@
|
||||
*/
|
||||
package davmail.ldap;
|
||||
|
||||
import davmail.AbstractDavMailTestCase;
|
||||
import davmail.DavGateway;
|
||||
import davmail.Settings;
|
||||
import davmail.exchange.AbstractExchangeSessionTestCase;
|
||||
import davmail.exchange.ExchangeSessionFactory;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
@ -34,7 +36,7 @@ import java.util.Hashtable;
|
||||
/**
|
||||
* Test LDAP.
|
||||
*/
|
||||
public class TestLdap extends AbstractDavMailTestCase {
|
||||
public class TestLdap extends AbstractExchangeSessionTestCase {
|
||||
InitialLdapContext ldapContext;
|
||||
|
||||
@Override
|
||||
@ -83,4 +85,17 @@ public class TestLdap extends AbstractDavMailTestCase {
|
||||
searchControls.setReturningAttributes(new String[]{"custom1", "mozillausehtmlmail", "postalcode", "custom2", "custom3", "custom4", "street", "surname", "telephonenumber", "mozillahomelocalityname", "orgunit", "mozillaworkstreet2", "xmozillanickname", "mozillahomestreet", "description", "cellphone", "homeurl", "mozillahomepostalcode", "departmentnumber", "postofficebox", "st", "objectclass", "sn", "ou", "fax", "mozillahomeurl", "mozillahomecountryname", "streetaddress", "cn", "company", "mozillaworkurl", "mobile", "region", "birthmonth", "birthday", "labeleduri", "carphone", "department", "xmozillausehtmlmail", "givenname", "nsaimid", "workurl", "facsimiletelephonenumber", "mozillanickname", "title", "nscpaimscreenname", "xmozillasecondemail", "mozillacustom3", "countryname", "mozillacustom4", "mozillacustom1", "mozillacustom2", "homephone", "mozillasecondemail", "pager", "zip", "mail", "c", "mozillahomestate", "o", "l", "birthyear", "modifytimestamp", "locality", "commonname", "notes", "pagerphone", "mozillahomestreet2"});
|
||||
NamingEnumeration<SearchResult> searchResults = ldapContext.search("ou=people", "(objectclass=*)", searchControls);
|
||||
}
|
||||
|
||||
public void testGalfind() throws NamingException {
|
||||
SearchControls searchControls = new SearchControls();
|
||||
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
|
||||
// searchControls.setReturningAttributes(new String[]{"uid"});
|
||||
NamingEnumeration<SearchResult> searchResults = ldapContext.search("ou=people", "(uid="+session.getAlias()+ ')', searchControls);
|
||||
assertTrue(searchResults.hasMore());
|
||||
SearchResult searchResult = searchResults.next();
|
||||
Attributes attributes = searchResult.getAttributes();
|
||||
Attribute attribute = attributes.get("uid");
|
||||
assertEquals(session.getAlias(), attribute.get());
|
||||
assertNotNull(attributes.get("givenName"));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user