[CalendarServer-changes] [9153] CalendarServer/branches/users/gaya/ldapdirectorybacker

source_changes at macosforge.org source_changes at macosforge.org
Thu Apr 19 13:20:48 PDT 2012


Revision: 9153
          http://trac.macosforge.org/projects/calendarserver/changeset/9153
Author:   gaya at apple.com
Date:     2012-04-19 13:20:48 -0700 (Thu, 19 Apr 2012)
Log Message:
-----------
support ab queries on KIND 

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest.plist
    CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest2.plist
    CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-odtest.plist
    CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/ldapdirectorybacker.py
    CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/opendirectorybacker.py
    CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/xmldirectorybacker.py

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest.plist
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest.plist	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest.plist	2012-04-19 20:20:48 UTC (rev 9153)
@@ -1018,102 +1018,6 @@
     <dict>
         <key>Enabled</key>
         <true/>
-        <!-- twistedcaldav.directory.opendirectorybacker.OpenDirectoryBackingService ->
-        <key>type</key>
-        <string>twistedcaldav.directory.opendirectorybacker.OpenDirectoryBackingService</string>
-        <key>params</key>
-        <dict>
-     	  <!- - Search for people records ->
-          <key>queryPeopleRecords</key>
-          <true/>
-     	  <!- Search for people records in this directory service node ->
-          <key>peopleNode</key>
-          <string>/Search/Contacts</string>
-     	  <!- Search for user records ->
-          <key>queryUserRecords</key>
-          <true/>
-          <key>userNode</key>
-     	  <!- Search for user records in this directory service node ->
-          <string>/Search</string>
-      	  <!- query in directory service local node ->
-          <key>queryDSLocal</key>
-          <false/>
-      	  <!- minutes to keep directory service local node in memory before refresh ->
-          <key>dsLocalCacheTimeout</key>
-          <integer>30</integer>
-     	  <!- approx. maximum number of records returned from a directory service query ->
-          <key>maxDSQueryRecords</key>
-          <integer>0</integer> <!- use 0 to have server calculate the maximum based on MaxAddressBookQueryResults, MaxAddressBookMultigetHrefs keys ->
-     	  <!- ignore system records like "root" when creating vCards ->
-          <key>ignoreSystemRecords</key>
-          <true/>
-       	  <!- fake the eTag.  If false all directory service attributes are used to calculate the eTag ->
-          <key>fakeETag</key>
-          <true/>
-          <key>generateSimpleUIDs</key>
-          <true/>
-          <key>appleInternalServer</key>
-          <false/>
-          <key>addDSAttrXProperties</key>
-          <false/>
-          <!- add this key to use additional directory service attributes in queries.  Needed for some queries with directory service templates.
-          <key>additionalAttributes</key>
-          <array>
-            <string>dsAttrTypeNative:appleAIMPreferred</string>
-            <string>dsAttrTypeNative:appleManager</string>
-          </array>
-          ->
-          <!- add this key to limit directory service attributes used to make vCard properties
-          		When using directory service templates, list should include only mapped attributes.
-          <key>allowedAttributes</key>
-          <array>
-            <string>dsAttrTypeStandard:AddressLine1</string>
-            <string>dsAttrTypeStandard:AddressLine2</string>
-            <string>dsAttrTypeStandard:AddressLine3</string>
-            <string>dsAttrTypeStandard:Birthday</string>
-            <string>dsAttrTypeStandard:Building</string>
-            <string>dsAttrTypeStandard:City</string>
-            <string>dsAttrTypeStandard:Comment</string>
-            <string>dsAttrTypeStandard:Country</string>
-            <string>dsAttrTypeStandard:CreationTimestamp</string>
-            <string>dsAttrTypeStandard:Department</string>
-            <string>dsAttrTypeStandard:EMailAddress</string>
-            <string>dsAttrTypeStandard:EMailContacts</string>
-            <string>dsAttrTypeStandard:FirstName</string>
-            <string>dsAttrTypeStandard:HomePhoneNumber</string>
-            <string>dsAttrTypeStandard:IMHandle</string>
-            <string>dsAttrTypeStandard:JPEGPhoto</string>
-            <string>dsAttrTypeStandard:JobTitle</string>
-            <string>dsAttrTypeStandard:LastName</string>
-            <string>dsAttrTypeStandard:MapCoordinates</string>
-            <string>dsAttrTypeStandard:MiddleName</string>
-            <string>dsAttrTypeStandard:MobileNumber</string>
-            <string>dsAttrTypeStandard:ModificationTimestamp</string>
-            <string>dsAttrTypeStandard:NamePrefix</string>
-            <string>dsAttrTypeStandard:NameSuffix</string>
-            <string>dsAttrTypeStandard:NickName</string>
-            <string>dsAttrTypeStandard:Note</string>
-            <string>dsAttrTypeStandard:OrganizationInfo</string>
-            <string>dsAttrTypeStandard:OrganizationName</string>
-            <string>dsAttrTypeStandard:PGPPublicKey</string>
-            <string>dsAttrTypeStandard:PagerNumber</string>
-            <string>dsAttrTypeStandard:PhoneContacts</string>
-            <string>dsAttrTypeStandard:PhoneNumber</string>
-            <string>dsAttrTypeStandard:PostalAddress</string>
-            <string>dsAttrTypeStandard:PostalAddressContacts</string>
-            <string>dsAttrTypeStandard:PostalCode</string>
-            <string>dsAttrTypeStandard:Relationships</string>
-            <string>dsAttrTypeStandard:State</string>
-            <string>dsAttrTypeStandard:Street</string>
-            <string>dsAttrTypeStandard:URL</string>
-            <string>dsAttrTypeStandard:UserCertificate</string>
-            <string>dsAttrTypeStandard:UserPKCS12Data</string>
-            <string>dsAttrTypeStandard:UserSMIMECertificate</string>
-            <string>dsAttrTypeStandard:WeblogURI</string>
-          </array>
-          ->
-        </dict>
-        -->
         <!-- twistedcaldav.directory.opendirectorybacker.OpenDirectoryBackingService -->
  		<key>type</key>
 		<string>twistedcaldav.directory.ldapdirectorybacker.LdapDirectoryBackingService</string>
@@ -1154,12 +1058,9 @@
                         <!-- map from ab query to indexed ldap attribute.  If unindexed, too slow.  -->
                         <key>vcardPropToLdapAttrMap</key>
                         <dict>
-                            <key>FN</key>
-                            <string>cn</string>
-                            <key>EMAIL</key>
-                            <string>mail</string>
-                            <key>TEL</key>
-                            <string>telephoneNumber</string>
+                            <key>FN</key>       <string>cn</string>
+                            <key>EMAIL</key>    <string>mail</string>
+                            <key>TEL</key>      <string>telephoneNumber</string>
                             <key>ADR</key>
                             <array>
                                 <string>buildingName</string>
@@ -1168,105 +1069,69 @@
                                 <string>l</string>
                                 <string>st</string>
                             </array>
-                            <key>ORG</key>
-                            <string>ou</string>
-                            <key>UID</key>
-                            <string>appleDSID</string>
+                            <key>ORG</key>  <string>ou</string>
+                            <key>UID</key>  <string>appleDSID</string>
                         </dict>
                         <!-- map ldap attributes to ds attribute types.  -->
     					<key>ldapAttrToDSAttrMap</key>
     					<dict>
-    						<key>givenName</key>
-    						<string>FirstName</string>
-    						<key>sn</key>
-    						<string>LastName</string>
-    						<key>cn</key>
-    						<string>RealName</string>
+    						<key>givenName</key>    <string>FirstName</string>
+    						<key>sn</key>           <string>LastName</string>
+    						<key>cn</key>           <string>RealName</string>
                             <!-- PHOTO  -->
-    						<key>applePhotoPreferred-jpeg</key>
-    						<string>JPEGPhoto</string>
+    						<key>applePhotoPreferred-jpeg</key>    <string>JPEGPhoto</string>
                             <!-- ADR  -->
-    						<key>buildingName</key>
-    						<string>Building</string>
-    						<key>destinationIndicator</key>
-    						<string>Building</string>
-    						<key>street</key>
-    						<string>Street</string>
-    						<key>l</key>
-    						<string>City</string>
-    						<key>st</key>
-    						<string>State</string>
-    						<key>postalCode</key>
-    						<string>PostalCode</string>
-    						<key>co</key>
-    						<string>Country</string>
+    						<key>buildingName</key>         <string>Building</string>
+    						<key>destinationIndicator</key> <string>Building</string>
+    						<key>street</key>               <string>Street</string>
+    						<key>l</key>                    <string>City</string>
+    						<key>st</key>                   <string>State</string>
+    						<key>postalCode</key>           <string>PostalCode</string>
+    						<key>co</key>                   <string>Country</string>
                             <!-- TEL  -->
-   						    <key>telephoneNumber</key>
-    						<string>PhoneNumber</string>
-    						<key>appleSecondaryPhone</key>
-    						<string>PhoneNumber</string>
-    						<key>facsimileTelephoneNumber</key>
-    						<string>FaxNumber</string>
-    						<key>pager</key>
-    						<string>PagerNumber</string>
-    						<key>mobile</key>
-    						<string>MobileNumber</string>
+   						    <key>telephoneNumber</key>          <string>PhoneNumber</string>
+    						<key>appleSecondaryPhone</key>      <string>PhoneNumber</string>
+    						<key>facsimileTelephoneNumber</key> <string>FaxNumber</string>
+    						<key>pager</key>                    <string>PagerNumber</string>
+    						<key>mobile</key>                   <string>MobileNumber</string>
                             <!-- EMAIL  -->
-    						<key>mail</key>
-    						<string>EMailAddress</string>
-    						<key>applePreferredEmail</key>
-    						<string>EMailAddress</string>
-    						<key>appleNotificationEmail</key>
-    						<string>EMailAddress</string>
+    						<key>mail</key>                     <string>EMailAddress</string>
+    						<key>applePreferredEmail</key>      <string>EMailAddress</string>
+    						<key>appleNotificationEmail</key>   <string>EMailAddress</string>
                             <!-- UID  -->
-    						<key>appleDSID</key>
-    						<string>GeneratedUID</string>
+    						<key>appleDSID</key>    <string>GeneratedUID</string>
                             <!-- ORG  -->
-    						<key>o</key>
-    						<string>OrganizationName</string>
-    						<key>ou</key>
-    						<string>Department</string>
+    						<key>o</key>            <string>OrganizationName</string>
+    						<key>ou</key>           <string>Department</string>
                             <!-- IMPP  -->
-    						<key>appleAIMPreferred</key>
-    						<string>IMHandle</string>
-    						<key>appleAIMOfficial</key>
-    						<string>IMHandle</string>
-    						<key>appleManager</key>
-    						<string>dsAttrTypeNative:appleManager</string>
+    						<key>appleAIMPreferred</key>    <string>IMHandle</string>
+    						<key>appleAIMOfficial</key>     <string>IMHandle</string>
+    						<key>appleManager</key>         <string>dsAttrTypeNative:appleManager</string>
     					</dict>
     				</dict>
                     <!-- mailing list vCards.  Should mark as company-->
     				<dict>
-    					<key>rdn</key>
-    					<string>ou=groups</string>
-    					<key>filter</key>
-    					<string>(objectClass=appleGroup)</string>
-    					<key>getAllAttributes</key>
-    					<false/>
+    					<key>rdn</key>                  <string>ou=groups</string>
+    					<key>kind</key>                  <string>org</string>
+    					<key>filter</key>               <string>(objectClass=appleGroup)</string>
+    					<key>getAllAttributes</key>     <false/>
     					<key>vcardPropToLdapAttrMap</key>
     					<dict>
-    						<key>EMAIL</key>
-    						<string>appleGroupEmail</string>
-    						<key>FN</key>
-    						<string>description</string>
-    						<key>UID</key>
-    						<string>appleDSID</string>
+    						<key>EMAIL</key>    <string>appleGroupEmail</string>
+    						<key>FN</key>       <string>description</string>
+    						<key>UID</key>      <string>appleDSID</string>
     					</dict>
     					<key>ldapAttrToDSAttrMap</key>
     					<dict>
-    						<key>cn</key>
-    						<string>RecordName</string>
+    						<key>cn</key>    <string>RecordName</string>
     						<key>description</key>
     						<array>
     							<string>RealName</string>
     							<string>OrganizationName</string>
     						</array>
-    						<key>appleDSID</key>
-    						<string>GeneratedUID</string>
-    						<key>appleGroupContact</key>
-    						<string>dsAttrTypeNative:appleManager</string>
-    						<key>appleGroupEmail</key>
-    						<string>EMailAddress</string>
+    						<key>appleDSID</key>            <string>GeneratedUID</string>
+    						<key>appleGroupContact</key>    <string>dsAttrTypeNative:appleManager</string>
+    						<key>appleGroupEmail</key>      <string>EMailAddress</string>
     					</dict>
                     </dict>
                 </array>

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest2.plist
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest2.plist	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-ldaptest2.plist	2012-04-19 20:20:48 UTC (rev 9153)
@@ -1050,13 +1050,13 @@
                 <array>
                     <!-- people vCards -->
                     <dict>
-                        <key>rdn</key>  <string>ou=People</string>
+                        <key>rdn</key>      <string>ou=People</string>
+                        <key>kind</key>      <string>individual</string>
                         <key>filter</key>   <string></string>
                         <!-- map from ab query to indexed ldap attribute.  If unindexed, too slow.  -->
                          <key>additionalVCardProps</key>
                             <dict>
-                                <key>KIND</key>         <string>individual</string>
-                                <key>NOTE</key>         <string>individual</string>
+                                <key>NOTE</key>         <string>KIND: individual</string>
                             </dict>
                         <key>ldapAttrToDSAttrMap</key>
                         <dict>
@@ -1073,14 +1073,11 @@
                             <key>UID</key>      <string>uid</string>
                         </dict>
                     </dict>
-                    <!-- distribution list (group) vCards shown by 10.6-7 clients as persons. Members are in NOTE. Does not hide groups below because UID different -->
+                    <!-- distribution list (group) vCards shown by 10.6-7 clients as a company. Does not hide groups below because UIDs are different -->
                     <dict>
                         <key>rdn</key>      <string>ou=Groups</string>
+                        <key>kind</key>     <string>org</string>
                         <key>filter</key>   <string>(|(mail=*)(uniqueMember=*))</string> <!-- add a filter to skip uninteresting groups -->
-                        <key>additionalVCardProps</key>
-                            <dict>
-                                <key>KIND</key>         <string>group</string>
-                            </dict>
                         <key>ldapAttrToDSAttrMap</key>
                         <dict>
                             <key>givenName</key>    <string>FirstName</string>
@@ -1088,7 +1085,7 @@
                             <key>description</key>  <string>RealName</string>
                             <key>cn</key>           <string>RecordName</string>
                             <key>mail</key>         <string>EMailAddress</string>
-                            <key>uniqueMember</key> <string>Comment</string>
+                            <key>uniqueMember</key> <string>Comment</string>            <!-- debug only -->
                         </dict>
                         <key>vcardPropToLdapAttrMap</key>
                         <dict>
@@ -1100,12 +1097,8 @@
                     <!-- group vCards NOT shown 10.6-7 clients. Hopefully, future client will show these. Client can expand members with exact query on group member UID -->
                     <dict>
                         <key>rdn</key>      <string>ou=Groups</string>
+                        <key>kind</key>     <string>group</string>
                         <key>filter</key>   <string>(|(mail=*)(uniqueMember=*))</string> <!-- add a filter to skip uninteresting groups -->
-                        <key>additionalVCardProps</key>
-                         <dict>
-                            <key>X-ADDRESSBOOKSERVER-KIND</key> <string>group</string>
-                            <key>KIND</key>                     <string>group</string>
-                       </dict>
                         <key>ldapAttrTransforms</key>
                         <dict>
                             <key>uniqueMember</key>
@@ -1133,12 +1126,12 @@
                     <!-- group vCards shown by 10.6-7 clients as persons.  Future client should show as location.  Need to add Map URL or GEO -->
                     <dict>
                         <key>rdn</key>      <string>ou=places</string>
+                        <key>kind</key>     <string>location</string>
                         <key>filter</key>   <string>(objectClass=apple-resource)</string>
                         <!-- map from ab query to indexed ldap attribute.  If unindexed, too slow.  -->
                          <key>additionalVCardProps</key>
                             <dict>
-                                <key>KIND</key> <string>location</string>
-                                <key>NOTE</key> <string>location</string>
+                                <key>NOTE</key> <string>KIND:location</string>
                             </dict>
                         <key>ldapAttrToDSAttrMap</key>
                         <dict>
@@ -1156,11 +1149,11 @@
                     <!-- calendarresource vCards shown by 10.6-7 clients as persons.  Just for testing only, at this point in time -->
                     <dict>
                         <key>rdn</key>      <string>ou=resources</string>
+                        <key>kind</key>     <string>calendarresource</string>
                         <key>filter</key>   <string>(objectClass=apple-resource)</string>
                          <key>additionalVCardProps</key>
                             <dict>
-                                <key>KIND</key> <string>calendarresource</string>
-                                <key>NOTE</key> <string>location</string>
+                                <key>NOTE</key> <string>KIND: calendarresource</string>
                             </dict>
                         <key>ldapAttrToDSAttrMap</key>
                         <dict>

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-odtest.plist
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-odtest.plist	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/conf/carddav-odtest.plist	2012-04-19 20:20:48 UTC (rev 9153)
@@ -1139,188 +1139,6 @@
            </array>
           -->
         </dict>
-        <!-- twistedcaldav.directory.opendirectorybacker.OpenDirectoryBackingService ->
- 		<key>type</key>
-		<string>twistedcaldav.directory.ldapdirectorybacker.LdapDirectoryBackingService</string>
-		<key>params</key>
-		<dict>
-			<key>warningThresholdSeconds</key>
-			<integer>1</integer>
-			<key>appleInternalServer</key>
-			<true/>
-            <!- fake uri, fill in.  ->
-			<key>uri</key>
-			<string>ldap://example.com/</string>
-            <!- fill in auth info, if needed.  ->
-			<key>tls</key>
-			<false/>
-			<key>tlsCACertFile</key>
-			<string></string>
-			<key>tlsCACertDir</key>
-			<string></string>
-			<key>tlsRequireCert</key>
-			<string>never</string>
-			<key>credentials</key>
-			<dict/>
-			<key>authMethod</key>
-			<string>LDAP</string>
-			<key>rdnSchema</key>
-			<dict>
-				<key>base</key>
-				<string>o=apple</string>
-				<key>queryTypes</key>
-				<array>
-					<string>people</string>
-					<string>distribution list</string>
-				</array>
-                <!- user vCards  ->
-				<key>people</key>
-				<dict>
-                    <key>rdn</key>
-                    <string>ou=people</string>
-                    <key>filter</key>
-                    <string></string>
-                    <!- map from ab query to indexed ldap attribute.  If unindexed, too slow.  ->
-                    <key>vcardPropToLdapAttrMap</key>
-                    <dict>
-                        <key>FN</key>
-                        <string>cn</string>
-                        <key>EMAIL</key>
-                        <string>mail</string>
-                        <key>TEL</key>
-                        <string>telephoneNumber</string>
-                        <key>UID</key>
-                        <string>appleDSID</string>
-                    </dict>
-                    <!- map ldap attributes to ds attribute types.  ->
-					<key>ldapAttrToDSAttrMap</key>
-					<dict>
-						<key>givenName</key>
-						<string>FirstName</string>
-						<key>sn</key>
-						<string>LastName</string>
-						<key>cn</key>
-						<array>
-							<string>RealName</string>
-							<string>RecordName</string>
-						</array>
-						<key>applePhotoPreferred-jpeg</key>
-						<string>JPEGPhoto</string>
-						<key>buildingName</key>
-						<string>Building</string>
-						<key>destinationIndicator</key>
-						<string>Building</string>
-						<key>street</key>
-						<string>Street</string>
-						<key>l</key>
-						<string>City</string>
-						<key>st</key>
-						<string>State</string>
-						<key>postalCode</key>
-						<string>PostalCode</string>
-						<key>co</key>
-						<string>Country</string>
-						<key>telephoneNumber</key>
-						<string>PhoneNumber</string>
-						<key>appleSecondaryPhone</key>
-						<string>PhoneNumber</string>
-						<key>facsimileTelephoneNumber</key>
-						<string>FaxNumber</string>
-						<key>pager</key>
-						<string>PagerNumber</string>
-						<key>mobile</key>
-						<string>MobileNumber</string>
-						<key>mail</key>
-						<string>EMailAddress</string>
-						<key>applePreferredEmail</key>
-						<string>EMailAddress</string>
-						<key>appleNotificationEmail</key>
-						<string>EMailAddress</string>
-						<key>appleDSID</key>
-						<string>GeneratedUID</string>
-						<key>o</key>
-						<string>OrganizationName</string>
-						<key>ou</key>
-						<string>Department</string>
-						<key>appleAIMPreferred</key>
-						<string>IMHandle</string>
-						<key>appleAIMOfficial</key>
-						<string>IMHandle</string>
-						<key>appleManager</key>
-						<string>dsAttrTypeNative:appleManager</string>
-					</dict>
-				</dict>
-                <!- mailing list vCards.  Should mark as "company" or use vCard 4.0 types  ->
-				<key>distribution list</key>
-				<dict>
-					<key>rdn</key>
-					<string>ou=groups</string>
-					<key>filter</key>
-					<string>(objectClass=appleGroup)</string>
-					<key>getAllAttributes</key>
-					<false/>
-					<key>vcardPropToLdapAttrMap</key>
-					<dict>
-						<key>EMAIL</key>
-						<string>appleGroupEmail</string>
-						<key>FN</key>
-						<string>description</string>
-						<key>UID</key>
-						<string>appleDSID</string>
-					</dict>
-					<key>ldapAttrToDSAttrMap</key>
-					<dict>
-						<key>cn</key>
-						<string>RecordName</string>
-						<key>description</key>
-						<array>
-							<string>RealName</string>
-							<string>OrganizationName</string>
-						</array>
-						<key>appleDSID</key>
-						<string>GeneratedUID</string>
-						<key>appleGroupContact</key>
-						<string>dsAttrTypeNative:appleManager</string>
-						<key>appleGroupEmail</key>
-						<string>EMailAddress</string>
-					</dict>
-				</dict>
-                <!- people vCards for another server.  Unused
-                <key>people - 2</key>
-                <dict>
-                    <key>ldapAttrToDSAttrMap</key>
-                    <dict>
-                        <key>givenName</key>
-                        <string>FirstName</string>
-                        <key>sn</key>
-                        <string>LastName</string>
-                        <key>cn</key>
-                        <array>
-                            <string>RealName</string>
-                            <string>RecordName</string>
-                        </array>
-                        <key>mail</key>
-                        <string>EMailAddress</string>
-                        <key>uid</key>
-                        <string>GeneratedUID</string>
-                    </dict>
-                    <key>rdn</key>
-                    <string>ou=People</string>
-                    <key>filter</key>
-                    <string></string>
-                    <key>vcardPropToLdapAttrMap</key>
-                    <dict>
-                        <key>FN</key>
-                        <string>cn</string>
-                        <key>EMAIL</key>
-                        <string>mail</string>
-                        <key>UID</key>
-                        <string>uid</string>
-                    </dict>
-                </dict>
-			</dict>
-		</dict>
-        -->
    </dict>
   </dict>
 </plist>

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/ldapdirectorybacker.py
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/ldapdirectorybacker.py	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/ldapdirectorybacker.py	2012-04-19 20:20:48 UTC (rev 9153)
@@ -164,7 +164,7 @@
 
  
     @inlineCallbacks
-    def _getLdapQueryResults(self, base, queryStr, attributes=None, maxResults=0, ldapAttrToDSAttrMap=None, ldapAttrTransforms=None, additionalVCardProps=None ):
+    def _getLdapQueryResults(self, base, queryStr, attributes=None, maxResults=0, ldapAttrToDSAttrMap=None, ldapAttrTransforms=None, additionalVCardProps=None, kind=None ):
         """
         Get a list of ABDirectoryQueryResult for the given query with the given attributes.
         query == None gets all records. attribute == None gets ABDirectoryQueryResult.allDSQueryAttributes
@@ -253,7 +253,7 @@
                                 self.log_debug("doAddressBookQuery: dsRecordAttributes[%s] = %s" % (dsAttributeName, dsRecordAttributes[dsAttributeName],))
 
                 # get a record for dsRecordAttributes 
-                result = ABDirectoryQueryResult(self.directoryBackedAddressBook, dsRecordAttributes, additionalVCardProps=additionalVCardProps, appleInternalServer=self.appleInternalServer)
+                result = ABDirectoryQueryResult(self.directoryBackedAddressBook, dsRecordAttributes, kind=kind, additionalVCardProps=additionalVCardProps, appleInternalServer=self.appleInternalServer)
             except:
                 traceback.print_exc()
                 self.log_info("Could not get vcard for %s" % (dn,))
@@ -287,8 +287,18 @@
             ldapAttrToDSAttrMap = queryMap["ldapAttrToDSAttrMap"]
             additionalVCardProps = queryMap.get("additionalVCardProps")
             ldapAttrTransforms = queryMap.get("ldapAttrTransforms")
+            kind = queryMap.get("kind", "individual")
+            
+            # add constants and KIND
+            constantProperties = ABDirectoryQueryResult.constantProperties.copy()
+            if additionalVCardProps:
+                for key, value in additionalVCardProps.iteritems():
+                    if key not in constantProperties:
+                        constantProperties[key] = value
+            constantProperties["KIND"] = kind
+            
 
-            allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, vcardPropToLdapAttrMap );
+            allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, vcardPropToLdapAttrMap, constantProperties=constantProperties );
             self.log_debug("doAddressBookQuery: rdn=%s LDAP allRecords=%s, filterAttributes=%s, query=%s" % (rdn, allRecords, filterAttributes, "None" if dsFilter is None else dsFilter.generate(),))
     
             
@@ -329,6 +339,7 @@
                                                                                                     queryStr=queryStr, 
                                                                                                     attributes=attributes, 
                                                                                                     maxResults=maxLdapResults, 
+                                                                                                    kind=kind, 
                                                                                                     ldapAttrToDSAttrMap=ldapAttrToDSAttrMap, 
                                                                                                     ldapAttrTransforms=ldapAttrTransforms, 
                                                                                                     additionalVCardProps=additionalVCardProps))

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/opendirectorybacker.py
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/opendirectorybacker.py	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/opendirectorybacker.py	2012-04-19 20:20:48 UTC (rev 9153)
@@ -184,14 +184,24 @@
         self.log_debug("self.searchAttributes=%s" % (searchAttributes, ))
         
         # calculate search map
-        vCardPropToSearchableDSAttrMap = {}
+        vcardPropToSearchableDSAttrMap = {}
         for prop, dsAttributeList in ABDirectoryQueryResult.vcardPropToDSAttrMap.iteritems():
             dsIndexedAttributeList = [attr for attr in dsAttributeList if attr in searchAttributes]
             if len(dsIndexedAttributeList):
-                vCardPropToSearchableDSAttrMap[prop] = dsIndexedAttributeList
+                vcardPropToSearchableDSAttrMap[prop] = dsIndexedAttributeList
         
-        self.vCardPropToSearchableDSAttrMap = vCardPropToSearchableDSAttrMap
-        self.log_debug("self.vCardPropToSearchableDSAttrMap=%s" % (self.vCardPropToSearchableDSAttrMap, ))
+        self.vcardPropToSearchableDSAttrMap = vcardPropToSearchableDSAttrMap
+        self.log_debug("self.vcardPropToSearchableDSAttrMap=%s" % (self.vcardPropToSearchableDSAttrMap, ))
+ 
+        # calculate unsearch map - a map of the binary attributes.  
+        vCardPropToUnsearchableDSAttrMap = {}
+        for prop, dsAttributeList in ABDirectoryQueryResult.vcardPropToDSAttrMap.iteritems():
+            for attr in dsAttributeList:
+                if isinstance(attr, tuple):
+                    vCardPropToUnsearchableDSAttrMap[prop] = dsAttributeList
+                    
+        self.vCardPropToUnsearchableDSAttrMap = vCardPropToUnsearchableDSAttrMap
+        self.log_debug("self.vCardPropToUnsearchableDSAttrMap=%s" % (self.vCardPropToUnsearchableDSAttrMap, ))
         
         
         #get attributes required for needed for valid vCard
@@ -479,7 +489,7 @@
         else:
             queryAttributes = self.requiredAttributes
             for prop in propertyNames:
-                attributes = self.vCardPropToSearchableDSAttrMap.get(prop)
+                attributes = self.vcardPropToSearchableDSAttrMap.get(prop)
                 if attributes:
                     queryAttributes += attributes
                     
@@ -493,7 +503,8 @@
         Get vCards for a given addressBookFilter and addressBookQuery
         """
     
-        allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, vcardPropToDSAttrMap=self.vCardPropToSearchableDSAttrMap );
+        allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, self.vcardPropToSearchableDSAttrMap,
+                                                                                 constantProperties=ABDirectoryQueryResult.constantProperties );
         self.log_debug("allRecords = %s, query = %s" % (allRecords, "None" if dsFilter is None else dsFilter.generate(),))
 
         # testing:
@@ -595,13 +606,18 @@
     return (etagRequested, propertyNames if len(propertyNames) else None)
 
 
-def dsFilterFromAddressBookFilter(addressBookFilter, vcardPropToDSAttrMap):
+def dsFilterFromAddressBookFilter(addressBookFilter, vcardPropToSearchableAttrMap, vcardPropToUnsearchableAttrMap={}, constantProperties={}):
     """
     Convert the supplied addressbook-query into a ds expression tree.
 
     @param filter: the L{Filter} for the addressbook-query to convert.
-    @return: (needsAllRecords, espressionAttributes, expression) tuple
+    @return: (needsAllRecords, expressionAttributes, expression) tuple
     """
+    #TODO:  1. get rid of needsAllRecords: instead should be: expression==None means list all results, expression==False means no results
+    #       2. expressionAttributes returned is incorrect in many cases for "return (xxx, [], [])" below
+    #       3. vcardPropToUnsearchableAttrMap is unused by callers. In the past, vcardPropToUnsearchableAttrMap was that part of vCardProp map
+    #            containing binary attributes.
+    #
     def propFilterListQuery(filterAllOf, propFilters):
 
         def propFilterExpression(filterAllOf, propFilter):
@@ -610,16 +626,15 @@
             Create an expression for a single prop-filter element.
             
             @param propFilter: the L{PropertyFilter} element.
-            @return: (needsAllRecords, espressionAttributes, expressions) tuple
+            @return: (needsAllRecords, expressionAttributes, expressions) tuple
             """
             
-            def definedExpression( defined, allOf, filterName, constant, queryAttributes, allAttrStrings):
+            def definedExpression( defined, allOf, filterName, constant, queryAttributes, allAttrNames):
                 if constant or filterName in ("N" , "FN", "UID", "SOURCE",):
                     return (defined, [], [])     # all records have this property so no records do not have it
                 else:
-                    matchList = list(set([dsquery.match(attrName, "", dsattributes.eDSStartsWith) for attrName in allAttrStrings]))
+                    matchList = [dsquery.match(attrName, "", dsattributes.eDSStartsWith) for attrName in allAttrNames]
                     if defined:
-                        # TODO:  Investigate what happens when andOrExpresion() does not return an expression
                         return andOrExpression(allOf, queryAttributes, matchList)
                     else:
                         if len(matchList) > 1:
@@ -627,7 +642,7 @@
                         else:
                             expr = matchList[0]
                         return (False, queryAttributes, [dsquery.expression( dsquery.expression.NOT, expr),])
-                #end isNotDefinedExpression()
+                #end definedExpression()
 
 
             def andOrExpression(propFilterAllOf, queryAttributes, matchList):
@@ -739,10 +754,10 @@
 
                     matchStrings = getMatchStrings(propFilter, textMatchElement.text)
 
-                    if not len(matchStrings) or binaryAttrNames:
+                    if not len(matchStrings) or unsearchableAttributes:
                         # no searching text in binary ds attributes, so change to defined/not defined case
                         if textMatchElement.negate:
-                            return definedExpression(False, propFilterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrStrings)
+                            return definedExpression(False, propFilterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrNames)
                         # else fall through to attribute exists case below
                     else:
                         
@@ -769,8 +784,7 @@
                                                     )
                         
                         # use match_type where possible depending on property/attribute mapping
-                        # Note that case sensitive negate will not work
-                        #        Should return all records in that case
+                        # FIXME: case-sensitive negate will not work.  This should return all all records in that case
                         matchType = dsattributes.eDSContains
                         if propFilter.filter_name in ("NICKNAME" , "TITLE" , "NOTE" , "UID", "URL", "N", "ADR", "ORG", "REV",  "LABEL", ):
                             if textMatchElement.match_type == "equals":
@@ -782,7 +796,7 @@
                         
                         matchList = []
                         for matchString in matchStrings:
-                            matchList += [dsquery.match(attrName, matchString, matchType) for attrName in stringAttrNames]
+                            matchList += [dsquery.match(attrName, matchString, matchType) for attrName in searchableAttributes]
                         
                         matchList = list(set(matchList))
 
@@ -796,31 +810,37 @@
                             return andOrExpression(propFilterAllOf, queryAttributes, matchList)
 
                 # attribute exists search
-                return definedExpression(True, propFilterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrStrings)
+                return definedExpression(True, propFilterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrNames)
                 #end textMatchElementExpression()
                 
 
-            # get attribute strings
-            queryAttributes = vcardPropToDSAttrMap.get(propFilter.filter_name, [])
-            if isinstance(queryAttributes, str):
-                queryAttributes = [queryAttributes,]
+            # queryAttributes are attributes used by this query needed for building vCard and correct post-filtering
+            searchableAttributes = vcardPropToSearchableAttrMap.get(propFilter.filter_name, [])
+            if isinstance(searchableAttributes, str):
+                searchableAttributes = [searchableAttributes,]
+                
+            unsearchableAttributes = vcardPropToUnsearchableAttrMap.get(propFilter.filter_name, [])
+            if isinstance(unsearchableAttributes, str):
+                unsearchableAttributes = [unsearchableAttributes,]
             
-            binaryAttrNames = []
-            stringAttrNames = []
-            for attr in queryAttributes:
-                if isinstance(attr, tuple):
-                    binaryAttrNames.append(attr[0])
+            #log.debug("searchableAttributes=%s" % (searchableAttributes,))
+            #log.debug("unsearchableAttributes=%s" % (unsearchableAttributes,))
+            queryAttributes = list(searchableAttributes) + list(unsearchableAttributes)
+            if not queryAttributes:
+                # not allAttrNames means propFilter.filter_name is not mapped
+                # return None to try to match all items if this is the only property filter
+                return (None, [], [])
+            
+            allAttrNames = []
+            for attrName in queryAttributes:
+                if isinstance(attrName, tuple):
+                    allAttrNames.append(attrName[0])
                 else:
-                    stringAttrNames.append(attr)
-            allAttrStrings = stringAttrNames + binaryAttrNames
-            if not allAttrStrings:
-            	# not AllAttrStrings means propFilter.filter_name is not mapped
-            	# return None to try to match all items if this is the only property filter
-                return (None, [], [])
+                    allAttrNames.append(attrName)
                                     
-            constant = ABDirectoryQueryResult.constantProperties.get(propFilter.filter_name)
+            constant = constantProperties.get(propFilter.filter_name)
             if propFilter.qualifier and isinstance(propFilter.qualifier, addressbookqueryfilter.IsNotDefined):
-                return definedExpression(False, filterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrStrings)
+                return definedExpression(False, filterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrNames)
             
             paramFilterElements = [paramFilterElement for paramFilterElement in propFilter.filters if isinstance(paramFilterElement, addressbookqueryfilter.ParameterFilter)]
             textMatchElements = [textMatchElement for textMatchElement in propFilter.filters if isinstance(textMatchElement, addressbookqueryfilter.TextMatch)]
@@ -835,7 +855,7 @@
             if len(paramFilterElements) > 0:
                 if supportedParamter(propFilter.filter_name, paramFilterElements, propFilterAllOf ):
                     if len(textMatchElements) == 0:
-                        return definedExpression(True, filterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrStrings)
+                        return definedExpression(True, filterAllOf, propFilter.filter_name, constant, queryAttributes, allAttrNames)
                 else:
                     if propFilterAllOf:
                         return (False, [], [])
@@ -869,7 +889,7 @@
         
         @param filterAllOf: the C{True} if parent filter test is "allof"
         @param propFilters: the C{list} of L{ComponentFilter} elements.
-        @return: (needsAllRecords, espressionAttributes, expression) tuple
+        @return: (needsAllRecords, expressionAttributes, expression) tuple
         """
         needsAllRecords = None
         attributes = []
@@ -1050,7 +1070,12 @@
         }
 
     
-    def __init__(self, directoryBackedAddressBook, recordAttributes, additionalVCardProps=None, addDSAttrXProperties=False, appleInternalServer=False, ):
+    def __init__(self, directoryBackedAddressBook, recordAttributes, 
+                 kind=None, 
+                 additionalVCardProps=None, 
+                 addDSAttrXProperties=False, 
+                 appleInternalServer=False, 
+                 ):
 
         self.log_debug("directoryBackedAddressBook=%s, attributes=%s, additionalVCardProps=%s" % (directoryBackedAddressBook, recordAttributes, additionalVCardProps,))
         
@@ -1090,7 +1115,20 @@
             
             self.attributes[dsattributes.kDS1AttrGeneratedUID] = guid
         
-        #generate a vCard here.  May throw an exception
+        if not kind:
+            dsRecordTypeToKindMap = {
+                           #dsattributes.kDSStdRecordTypePeople:"individual",
+                           #dsattributes.kDSStdRecordTypeUsers:"individual",
+                           dsattributes.kDSStdRecordTypeGroups:"group",
+                           dsattributes.kDSStdRecordTypeLocations:"location",
+                           dsattributes.kDSStdRecordTypeResources:"device",
+                           }
+            recordType = self.firstValueForAttribute(dsattributes.kDSNAttrRecordType)
+            kind = dsRecordTypeToKindMap.get(recordType, "individual")
+        self.kind = kind.lower()
+
+
+       #generate a vCard here.  May throw an exception
         self.vCard()
         
 
@@ -1625,7 +1663,7 @@
             
  
             # add apple-defined group vcard properties if record type is group
-            if self.firstValueForAttribute(dsattributes.kDSNAttrRecordType) == dsattributes.kDSStdRecordTypeGroups:
+            if self.kind == "group":
                 vcard.addProperty(Property("X-ADDRESSBOOKSERVER-KIND", "group"))
             
             # add members
@@ -1653,9 +1691,12 @@
             
             """
             
-            # 2.1.4 SOURCE Type
+            # 2.1.4 SOURCE Type http://tools.ietf.org/html/rfc2426#section-2.1.4
             #    If the SOURCE type is present, then its value provides information
             #    how to find the source for the vCard.
+            
+            # add the source, so that if the SOURCE is copied out and preserved, the client can refresh information
+            # However, client should really do a ab-query report matching UID on /directory/ not a multiget.
             uri = joinURL(self._directoryBackedAddressBook.uri, vcard.propertyValue("UID") + ".vcf")
             
             # seems like this should be in some standard place.
@@ -1671,7 +1712,19 @@
                     source = "http://%s:%s%s" % (config.ServerHostName, config.HTTPPort, uri)
             vcard.addProperty(Property("SOURCE", source))
                        
-            # debug, create x attributes for all ds attributes
+            #  in 4.0 spec: 
+            # 6.1.4.  KIND http://tools.ietf.org/html/rfc6350#section-6.1.4
+            # 
+            # see also: http://www.iana.org/assignments/vcard-elements/vcard-elements.xml
+            #
+            vcard.addProperty(Property("KIND", self.kind))
+            
+            # one more X- related to kind
+            if self.kind == "org":
+                vcard.addProperty(Property("X-ABShowAs", "COMPANY"))
+
+
+            # debug, create X-attributes for all ds attributes
             if self.addDSAttrXProperties:
                 for attribute in self.originalAttributes:
                     for value in self.valuesForAttribute(attribute):

Modified: CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/xmldirectorybacker.py
===================================================================
--- CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/xmldirectorybacker.py	2012-04-19 17:41:39 UTC (rev 9152)
+++ CalendarServer/branches/users/gaya/ldapdirectorybacker/twistedcaldav/directory/xmldirectorybacker.py	2012-04-19 20:20:48 UTC (rev 9153)
@@ -130,8 +130,16 @@
             queryMap = self.rdnSchema[queryType]
             vcardPropToDirRecordAttrMap = queryMap["vcardPropToDirRecordAttrMap"]
             dirRecordAttrToDSAttrMap = queryMap["dirRecordAttrToDSAttrMap"]
+            
+            kind = {self.recordType_groups:"group",
+                    self.recordType_locations:"location",
+                    self.recordType_resources:"calendarresource",
+                    }.get(queryType, "individual")
+        
+            constantProperties = ABDirectoryQueryResult.constantProperties.copy()
+            constantProperties["KIND"] = kind
 
-            allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, vcardPropToDirRecordAttrMap );
+            allRecords, filterAttributes, dsFilter  = dsFilterFromAddressBookFilter( addressBookFilter, vcardPropToDirRecordAttrMap, constantProperties=constantProperties );
             self.log_debug("doAddressBookQuery: queryType=\"%s\" LDAP allRecords=%s, filterAttributes=%s, query=%s" % (queryType, allRecords, filterAttributes, "None" if dsFilter is None else dsFilter.generate(),))
     
             
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120419/57479c22/attachment-0001.html>


More information about the calendarserver-changes mailing list