Commit 2f63beb7 authored by Manfred Kutas's avatar Manfred Kutas

ZP-718 Re-factor resolving recipients in gal and contacts.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 835c7f1d
...@@ -924,15 +924,17 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -924,15 +924,17 @@ class BackendZarafa implements IBackend, ISearchProvider {
$resolveRecipients->status = SYNC_RESOLVERECIPSSTATUS_SUCCESS; $resolveRecipients->status = SYNC_RESOLVERECIPSSTATUS_SUCCESS;
$resolveRecipients->response = array(); $resolveRecipients->response = array();
$resolveRecipientsOptions = new SyncResolveRecipientsOptions(); $resolveRecipientsOptions = new SyncResolveRecipientsOptions();
$maxAmbiguousRecipients = self::MAXAMBIGUOUSRECIPIENTS;
if (isset($resolveRecipients->options)) { if (isset($resolveRecipients->options)) {
$resolveRecipientsOptions = $resolveRecipients->options; $resolveRecipientsOptions = $resolveRecipients->options;
// only limit ambiguous recipients if the client requests it. // only limit ambiguous recipients if the client requests it.
$maxAmbiguousRecipients = self::MAXAMBIGUOUSRECIPIENTS;
if (isset($resolveRecipientsOptions->maxambiguousrecipients) && if (isset($resolveRecipientsOptions->maxambiguousrecipients) &&
$resolveRecipientsOptions->maxambiguousrecipients >= 0 && $resolveRecipientsOptions->maxambiguousrecipients >= 0 &&
$resolveRecipientsOptions->maxambiguousrecipients <= self::MAXAMBIGUOUSRECIPIENTS) { $resolveRecipientsOptions->maxambiguousrecipients <= self::MAXAMBIGUOUSRECIPIENTS) {
$maxAmbiguousRecipients = $resolveRecipientsOptions->maxambiguousrecipients; $maxAmbiguousRecipients = $resolveRecipientsOptions->maxambiguousrecipients;
ZLog::Write(LOGLEVEL_DEBUG, sprintf("The client requested %d max ambigous recipients to resolve.", $maxAmbiguousRecipients));
} }
} }
...@@ -1715,23 +1717,30 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1715,23 +1717,30 @@ class BackendZarafa implements IBackend, ISearchProvider {
$querycnt = mapi_table_getrowcount($table); $querycnt = mapi_table_getrowcount($table);
if ($querycnt > 0) { if ($querycnt > 0) {
$recipientGal = array(); $recipientGal = array();
// TODO multiple recipients possible if $to is a group or list // get the certificate every time because caching the certificate is less expensive than opening addressbook entry again
$abentries = mapi_table_queryrows($table, array(PR_DISPLAY_NAME, PR_EMS_AB_TAGGED_X509_CERT), 0, 1); $abentries = mapi_table_queryrows($table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_EMS_AB_TAGGED_X509_CERT, PR_OBJECT_TYPE), 0, $maxAmbiguousRecipients);
$certificates = for ($i = 0, $nrEntries = count($abentries); $i < $nrEntries; $i++) {
// check if there are any certificates available if ($abentries[$i][PR_OBJECT_TYPE] == MAPI_DISTLIST) {
(isset($abentries[0][PR_EMS_AB_TAGGED_X509_CERT]) && is_array($abentries[0][PR_EMS_AB_TAGGED_X509_CERT]) && count($abentries[0][PR_EMS_AB_TAGGED_X509_CERT])) ? // dist lists must be expanded into their members
$this->getCertificates($abentries[0][PR_EMS_AB_TAGGED_X509_CERT], $querycnt) : false; ZLog::Write(LOGLEVEL_DEBUG, sprintf("'%s' is a dist list. Expand it to members.", $to));
if ($certificates === false) { $distList = mapi_ab_openentry($addrbook, $abentries[$i][PR_ENTRYID]);
// the recipient does not have a valid certificate, set the appropriate status $distListContent = mapi_folder_getcontentstable($distList);
ZLog::Write(LOGLEVEL_INFO, sprintf("No certificates found for '%s'", $to)); $distListMembers = mapi_table_queryallrows($distListContent, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_EMS_AB_TAGGED_X509_CERT));
$certificates = $this->getCertificates(false); for ($j = 0, $nrDistListMembers = mapi_table_getrowcount($distListContent); $j < $nrDistListMembers; $j++) {
ZLog::Write(LOGLEVEL_WBXML, sprintf("distlist's '%s' member", $to, $distListMembers[$j][PR_DISPLAY_NAME]));
$recipientGal[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_GAL, $to, $distListMembers[$j], $nrDistListMembers);
}
}
elseif ($abentries[$i][PR_OBJECT_TYPE] == MAPI_MAILUSER) {
$recipientGal[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_GAL, $to, $abentries[$i]);
}
} }
$recipientGal[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_GAL, w2u($abentries[0][PR_DISPLAY_NAME]), $to, $certificates);
ZLog::Write(LOGLEVEL_WBXML, "Found a recipient in GAL"); ZLog::Write(LOGLEVEL_WBXML, "Found a recipient in GAL");
return $recipientGal; return $recipientGal;
} }
else { else {
ZLog::Write(LOGLEVEL_WARN, sprintf("No recipient found for: '%s'", $to)); ZLog::Write(LOGLEVEL_WARN, sprintf("No recipient found for: '%s' in GAL", $to));
return SYNC_RESOLVERECIPSSTATUS_RESPONSE_UNRESOLVEDRECIP; return SYNC_RESOLVERECIPSSTATUS_RESPONSE_UNRESOLVEDRECIP;
} }
return false; return false;
...@@ -1758,19 +1767,10 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1758,19 +1767,10 @@ class BackendZarafa implements IBackend, ISearchProvider {
$recipients = array(); $recipients = array();
if ($contacts !== false) { if ($contacts !== false) {
ZLog::Write(LOGLEVEL_WBXML, "Found contacts"); ZLog::Write(LOGLEVEL_WBXML, sprintf("Found %d contacts in main contacts folder.", count($contacts)));
// create resolve recipient object // create resolve recipient object
foreach ($contacts as $contact) { foreach ($contacts as $contact) {
$certificates = $recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, $to, $contact);
// check if there are any certificates available
(isset($contact[PR_USER_X509_CERTIFICATE]) && is_array($contact[PR_USER_X509_CERTIFICATE]) && count($contact[PR_USER_X509_CERTIFICATE])) ?
$this->getCertificates($contact[PR_USER_X509_CERTIFICATE], 1) : false;
if ($certificates !== false) {
$recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, u2w($contact[PR_DISPLAY_NAME]), $to, $certificates);
ZLog::Write(LOGLEVEL_WBXML, "Found a recipient in main contacts folder");
return $recipients;
}
} }
} }
...@@ -1780,17 +1780,9 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1780,17 +1780,9 @@ class BackendZarafa implements IBackend, ISearchProvider {
foreach($subfolders as $folder) { foreach($subfolders as $folder) {
$contacts = $this->getContactsFromFolder($this->defaultstore, $folder[PR_ENTRYID], $to); $contacts = $this->getContactsFromFolder($this->defaultstore, $folder[PR_ENTRYID], $to);
if ($contacts !== false) { if ($contacts !== false) {
ZLog::Write(LOGLEVEL_WBXML, sprintf("Found %d contacts in contacts' subfolder.", count($contacts)));
foreach ($contacts as $contact) { foreach ($contacts as $contact) {
$certificates = $recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, $to, $contact);
// check if there are any certificates available
(isset($contact[PR_USER_X509_CERTIFICATE]) && is_array($contact[PR_USER_X509_CERTIFICATE]) && count($contact[PR_USER_X509_CERTIFICATE])) ?
$this->getCertificates($contact[PR_USER_X509_CERTIFICATE], 1) : false;
if ($certificates !== false) {
$recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, u2w($contact[PR_DISPLAY_NAME]), $to, $certificates);
ZLog::Write(LOGLEVEL_WBXML, "Found a recipient in a contacts subfolder");
return $recipients;
}
} }
} }
} }
...@@ -1813,17 +1805,9 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1813,17 +1805,9 @@ class BackendZarafa implements IBackend, ISearchProvider {
foreach($subfolders as $folder) { foreach($subfolders as $folder) {
$contacts = $this->getContactsFromFolder($publicstore, $folder[PR_ENTRYID], $to); $contacts = $this->getContactsFromFolder($publicstore, $folder[PR_ENTRYID], $to);
if ($contacts !== false) { if ($contacts !== false) {
ZLog::Write(LOGLEVEL_WBXML, sprintf("Found %d contacts in public contacts folder.", count($contacts)));
foreach ($contacts as $contact) { foreach ($contacts as $contact) {
$certificates = $recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, $to, $contact);
// check if there are any certificates available
(isset($contact[PR_USER_X509_CERTIFICATE]) && is_array($contact[PR_USER_X509_CERTIFICATE]) && count($contact[PR_USER_X509_CERTIFICATE])) ?
$this->getCertificates($contact[PR_USER_X509_CERTIFICATE], 1) : false;
if ($certificates !== false) {
$recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, u2w($contact[PR_DISPLAY_NAME]), $to, $certificates);
ZLog::Write(LOGLEVEL_WBXML, "Found a recipient in a public folder");
return $recipients;
}
} }
} }
} }
...@@ -1836,8 +1820,13 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1836,8 +1820,13 @@ class BackendZarafa implements IBackend, ISearchProvider {
ZLog::Write(LOGLEVEL_WARN, sprintf("Unable to open public store: 0x%X", $result)); ZLog::Write(LOGLEVEL_WARN, sprintf("Unable to open public store: 0x%X", $result));
} }
$certificates = $this->getCertificates(false); if (empty($recipients)) {
$recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, $to, $to, $certificates); $contactProperties = array();
$contactProperties[PR_DISPLAY_NAME] = $to;
$contactProperties[PR_USER_X509_CERTIFICATE] = false;
$recipients[] = $this->createResolveRecipient(SYNC_RESOLVERECIPIENTS_TYPE_CONTACT, $to, $contactProperties);
}
return $recipients; return $recipients;
} }
...@@ -1866,27 +1855,38 @@ class BackendZarafa implements IBackend, ISearchProvider { ...@@ -1866,27 +1855,38 @@ class BackendZarafa implements IBackend, ISearchProvider {
} }
/** /**
* * Creates SyncResolveRecipient object for ResolveRecipientsResponse.
* @param int $type * @param int $type
* @param string $displayname
* @param string $email * @param string $email
* @param array $certificates * @param array $recipientProperties
* @param int $recipientCount
* *
* @return SyncResolveRecipient * @return SyncResolveRecipient
*/ */
private function createResolveRecipient($type, $displayname, $email, $certificates) { private function createResolveRecipient($type, $email, $recipientProperties, $recipientCount = 0) {
$recipient = new SyncResolveRecipient(); $recipient = new SyncResolveRecipient();
$recipient->type = $type; $recipient->type = $type;
$recipient->displayname = $displayname; $recipient->displayname = u2w($recipientProperties[PR_DISPLAY_NAME]);
$recipient->emailaddress = $email; $recipient->emailaddress = $email;
$recipient->certificates = $certificates;
if ($recipient->certificates === false) { if ($type == SYNC_RESOLVERECIPIENTS_TYPE_GAL) {
// the recipient does not have a valid certificate, set the appropriate status $certificateProp = PR_EMS_AB_TAGGED_X509_CERT;
ZLog::Write(LOGLEVEL_INFO, sprintf("No certificates found for '%s'", $email)); }
$cert = new SyncResolveRecipientsCertificates(); elseif ($type == SYNC_RESOLVERECIPIENTS_TYPE_CONTACT) {
$cert->status = SYNC_RESOLVERECIPSSTATUS_CERTIFICATES_NOVALIDCERT; $certificateProp = PR_USER_X509_CERTIFICATE;
$recipient->certificates = $cert; }
else {
$certificateProp = null;
} }
if (isset($recipientProperties[$certificateProp]) && is_array($recipientProperties[$certificateProp]) && !empty($recipientProperties[$certificateProp])) {
$certificates = $this->getCertificates($recipientProperties[$certificateProp], $recipientCount);
}
else {
$certificates = $this->getCertificates(false);
ZLog::Write(LOGLEVEL_INFO, sprintf("No certificate found for '%s' (requested email address: '%s')", $recipientProperties[PR_DISPLAY_NAME], $email));
}
$recipient->certificates = $certificates;
return $recipient; return $recipient;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment