From 2a3367a13b5e13bae3a69cd9032b5eb42e1a6110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Thu, 3 Dec 2015 15:18:31 +0100 Subject: [PATCH 1/5] oc-contacts: returning properly personal contacts We needed to return AddressBookProviderEmailList, AddressBookProviderArrayType and Email1OriginalEntryId to make it compatible with the standard. Besides a refactorization to return better EmailNFoobar properties --- OpenChange/MAPIStoreContactsMessage.m | 389 ++++++++++++++++++++------ 1 file changed, 298 insertions(+), 91 deletions(-) diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 0236f1817..62a03e9a4 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -34,11 +34,14 @@ #import #import #import +#import #import "MAPIStoreAttachment.h" #import "MAPIStoreContactsAttachment.h" #import "MAPIStoreContactsFolder.h" +#import "MAPIStoreContext.h" #import "MAPIStorePropertySelectors.h" +#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "NSArray+MAPIStore.h" #import "NSDate+MAPIStore.h" @@ -64,6 +67,15 @@ @end +enum { // [MS-OXOCNTC] 2.2.1.2.11 + AddressBookProviderEmailValueEmail1 = 0, + AddressBookProviderEmailValueEmail2, + AddressBookProviderEmailValueEmail3, + AddressBookProviderEmailValueBusinessFax, + AddressBookProviderEmailValueHomeFax, + AddressBookProviderEmailValuePrimaryFax +}; + @implementation MAPIStoreContactsMessage - (id) init @@ -258,39 +270,6 @@ return MAPISTORE_SUCCESS; } -- (int) getPidLidEmail1DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NGVCard *vCard; - NSString *fn, *email; - - vCard = [sogoObject vCard]; - fn = [vCard fn]; - email = [vCard preferredEMail]; - *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidEmail1OriginalDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail1EmailAddress: data - inMemCtx: memCtx]; -} - -- (int) getPidLidEmail1EmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] preferredEMail]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - - (int) getPidTagAccount: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -341,46 +320,6 @@ return [self getYes: data inMemCtx: memCtx]; } -- (int) getPidLidEmail2EmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSMutableArray *emails; - NSString *email, *stringValue; - NGVCard *card; - NSUInteger count, max; - - emails = [NSMutableArray array]; - stringValue = nil; - - card = [sogoObject vCard]; - [emails addObjectsFromArray: [card childrenWithTag: @"email"]]; - [emails removeObjectsInArray: [card childrenWithTag: @"email" - andAttribute: @"type" - havingValue: @"pref"]]; - - max = [emails count]; - for (count = 0; !stringValue && count < max; count++) - { - email = [[emails objectAtIndex: count] flattenedValuesForKey: @""]; - - if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame) - stringValue = email; - } - - if (!stringValue) - stringValue = @""; - - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidEmail2OriginalDisplayName: (void **) data // Other email - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail2EmailAddress: data inMemCtx: memCtx]; -} - - (int) getPidTagBody: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -396,6 +335,292 @@ return rc; } +// ------------------------------------------------------- +// Electronic Address Properties [MS-OXOCNTC 2.2.1.2] +// ------------------------------------------------------- + +/* + Fetch Email1, Email2 and Email3 values from the vcard. + Returns nil if not found +*/ +- (NSString *) _fetchEmailAddress: (NSUInteger) position +{ + NSMutableArray *emails; + NSString *email, *stringValue = nil; + NGVCard *card; + NSUInteger count, max; + + card = [sogoObject vCard]; + + if (position == 1) + // Predefined email + return [card preferredEMail]; + + emails = [NSMutableArray array]; + [emails addObjectsFromArray: [card childrenWithTag: @"email"]]; + [emails removeObjectsInArray: [card childrenWithTag: @"email" + andAttribute: @"type" + havingValue: @"pref"]]; + max = [emails count]; + for (count = 0; !stringValue && count < max; count++) + { + email = [[emails objectAtIndex: count] flattenedValuesForKey: @""]; + + if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame) + { + position--; + if (position == 1) + stringValue = email; + } + } + + return stringValue; +} + +- (NSArray *) _buildAddressBookProviderEmailList +{ + // [MS-OXOCNTC] 2.2.1.2.11 + // https://msdn.microsoft.com/en-us/library/ee158427%28v=exchg.80%29.aspx + NSMutableArray *list = [[NSMutableArray alloc] init]; + NSArray *elements; + + // Is there a fax number? + elements = [[[sogoObject vCard] childrenWithTag: @"tel"] + cardElementsWithAttribute: @"type" + havingValue: @"fax"]; + if ([elements count] > 0) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueBusinessFax]]; + + // How many different email addresses? + if ([self _fetchEmailAddress: 1]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail1]]; + else + return list; + if ([self _fetchEmailAddress: 2]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail2]]; + else + return list; + if ([self _fetchEmailAddress: 3]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail3]]; + + return list; +} + +- (int) getPidLidAddressBookProviderArrayType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + // [MS-OXOCNTC] 2.2.1.2.12 + // https://msdn.microsoft.com/en-us/library/ee218011%28v=exchg.80%29.aspx + uint32_t value = 0; + NSArray *emailList = [self _buildAddressBookProviderEmailList]; + + for (NSNumber *maskValue in emailList) + value |= 1 << [maskValue intValue]; + + *data = MAPILongValue (memCtx, value); + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidAddressBookProviderEmailList: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSArray *emailList = [self _buildAddressBookProviderEmailList]; + + *data = [emailList asMVLongInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +/* + Store on *data a string with the display name for the given email (position) + It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist +*/ +- (int) _getPidLidEmailDisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + atPosition: (NSUInteger) position +{ + NGVCard *vCard; + NSString *fn, *email; + + email = [self _fetchEmailAddress: position]; + if (!email) return MAPISTORE_ERR_NOT_FOUND; + + vCard = [sogoObject vCard]; + fn = [vCard fn]; + + *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] + asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidEmail1DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 1]; +} + +- (int) getPidLidEmail2DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 2]; +} + +- (int) getPidLidEmail3DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 3]; +} + +/* + Return an entry id (either one-off or addressbook entry) for the given email + It can return nil if the email doesn't exist +*/ +- (NSData *) _buildEntryIdForEmail: (NSUInteger) position +{ + NSString *email, *username; + NSData *data; + SOGoUserManager *mgr; + NSDictionary *contactInfos; + + email = [self _fetchEmailAddress: position]; + if (!email) return nil; + + // Try to figure out if this email is from local domain + mgr = [SOGoUserManager sharedUserManager]; + contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; + if (contactInfos) + { + username = [contactInfos objectForKey: @"sAMAccountName"]; + data = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); + } + else + data = MAPIStoreExternalEntryId ([[sogoObject vCard] fn], email); + + return data; +} + +/* + Store on *data an entryId for the given email (position) + It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist +*/ +- (int) _getPidLidEmailOriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + atPosition: (NSUInteger) position +{ + NSData *value; + + value = [self _buildEntryIdForEmail: position]; + if (!value) return MAPISTORE_ERR_NOT_FOUND; + + *data = [value asBinaryInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidEmail1OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 1]; +} + +- (int) getPidLidEmail2OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 2]; +} + +- (int) getPidLidEmail3OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 3]; +} + +/* + Store on *data the given email (position) + It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist +*/ +- (int) _getPidLidEmailAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + atPosition: (NSUInteger) position +{ + NSString *email; + + email = [self _fetchEmailAddress: position]; + if (!email) return MAPISTORE_ERR_NOT_FOUND; + + *data = [email asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidEmail1EmailAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 1]; +} + +- (int) getPidLidEmail2EmailAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 2]; +} + +- (int) getPidLidEmail3EmailAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 3]; +} + +- (int) getPidLidEmail1OriginalDisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidEmail1EmailAddress: data inMemCtx: memCtx]; +} + +- (int) getPidLidEmail2OriginalDisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidEmail2EmailAddress: data inMemCtx: memCtx]; +} + +- (int) getPidLidEmail3OriginalDisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidEmail3EmailAddress: data inMemCtx: memCtx]; +} + +- (int) getPidLidEmail1AddressType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + if (![self _fetchEmailAddress: 1]) return MAPISTORE_ERR_NOT_FOUND; + + return [self getSMTPAddrType: data inMemCtx: memCtx]; +} + +- (int) getPidLidEmail2AddressType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + if (![self _fetchEmailAddress: 2]) return MAPISTORE_ERR_NOT_FOUND; + + return [self getSMTPAddrType: data inMemCtx: memCtx]; +} + +- (int) getPidLidEmail3AddressType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + if (![self _fetchEmailAddress: 3]) return MAPISTORE_ERR_NOT_FOUND; + + return [self getSMTPAddrType: data inMemCtx: memCtx]; +} + - (int) _getElement: (NSString *) elementTag ofType: (NSString *) aType excluding: (NSString *) aTypeToExclude @@ -488,24 +713,6 @@ atPos: 0 inData: data inMemCtx: memCtx]; } -- (int) getPidLidEmail1AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (int) getPidLidEmail2AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (int) getPidLidEmail3AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - - (int) getPidLidInstantMessagingAddress: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { From 0ddbd79fadc2742c52cd583e9630fc9f575c38b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Thu, 3 Dec 2015 15:22:15 +0100 Subject: [PATCH 2/5] Remove commented code These methods don't make any sense here --- OpenChange/MAPIStoreContactsMessage.m | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 62a03e9a4..c2900a50f 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -152,25 +152,6 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return MAPISTORE_SUCCESS; } -// - (int) getPidTagOfflineAddressBookName: (void **) data -// inMemCtx: (TALLOC_CTX *) memCtx -// { -// *data = talloc_strdup (memCtx, "PR_OAB_NAME_UNICODE"); - -// return MAPISTORE_SUCCESS; -// } - -// - (int) getPidTagOfflineAddressBookLanguageId: (void **) data -// inMemCtx: (TALLOC_CTX *) memCtx -// { -// /* see http://msdn.microsoft.com/en-us/goglobal/bb895996.asxp */ -// /* English US */ -// *data = MAPILongValue (memCtx, 0x0409); - -// return MAPISTORE_SUCCESS; -// } - - - (int) getPidTagTitle: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { From bc5aa3cacb00b901808e4643e2d291126ee7e634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Thu, 3 Dec 2015 15:25:29 +0100 Subject: [PATCH 3/5] Whitespaces and indentation No real changes --- OpenChange/MAPIStoreContactsMessage.m | 174 +++++++++++++------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index c2900a50f..3a2492ad2 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -182,7 +182,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { CardElement *org; - + org = [[sogoObject vCard] org]; *data = [[org flattenedValueAtIndex: 0 forKey: @""] asUnicodeInMemCtx: memCtx]; @@ -194,7 +194,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { CardElement *org; - + org = [[sogoObject vCard] org]; *data = [[org flattenedValueAtIndex: 1 forKey: @""] asUnicodeInMemCtx: memCtx]; @@ -619,14 +619,14 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 vCard = [sogoObject vCard]; elements = [[vCard childrenWithTag: elementTag] - cardElementsWithAttribute: @"type" - havingValue: aType]; + cardElementsWithAttribute: @"type" + havingValue: aType]; max = [elements count]; for (count = 0; !stringValue && count < max; count++) { ce = [elements objectAtIndex: count]; if (!aTypeToExclude - || ![ce hasAttribute: @"type" havingValue: aTypeToExclude]) + || ![ce hasAttribute: @"type" havingValue: aTypeToExclude]) stringValue = [ce flattenedValueAtIndex: pos forKey: @""]; } @@ -718,8 +718,8 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 vCard = [sogoObject vCard]; elements = [[vCard childrenWithTag: @"adr"] - cardElementsWithAttribute: @"type" - havingValue: @"pref"]; + cardElementsWithAttribute: @"type" + havingValue: @"pref"]; if ([elements count] > 0) { element = [elements objectAtIndex: 0]; @@ -731,7 +731,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 longValue = 2; // The Work Address is the mailing address. } *data = MAPILongValue (memCtx, longValue); - + return MAPISTORE_SUCCESS; } @@ -792,7 +792,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 // home address getters // - (int) getPidLidHomeAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx + inMemCtx: (TALLOC_CTX *) memCtx { return [self _getElement: @"label" ofType: @"home" excluding: nil atPos: 0 inData: data inMemCtx: memCtx]; @@ -892,7 +892,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 } // -// +// personal and social getters // - (int) getPidTagNickname: (void **) data inMemCtx: (TALLOC_CTX *) memCtx @@ -922,7 +922,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 } else rc = MAPISTORE_ERR_NOT_FOUND; - + return rc; } @@ -954,7 +954,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 int rc = MAPISTORE_SUCCESS; stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-spouse"] - flattenedValuesForKey: @""]; + flattenedValuesForKey: @""]; if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else @@ -970,7 +970,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 int rc = MAPISTORE_SUCCESS; stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-manager"] - flattenedValuesForKey: @""]; + flattenedValuesForKey: @""]; if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else @@ -986,7 +986,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 int rc = MAPISTORE_SUCCESS; stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-assistant"] - flattenedValuesForKey: @""]; + flattenedValuesForKey: @""]; if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else @@ -1002,7 +1002,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 int rc = MAPISTORE_SUCCESS; stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-office"] - flattenedValuesForKey: @""]; + flattenedValuesForKey: @""]; if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else @@ -1018,7 +1018,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 int rc = MAPISTORE_SUCCESS; stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"fburl"] - flattenedValuesForKey: @""]; + flattenedValuesForKey: @""]; if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else @@ -1032,9 +1032,9 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 // - (int) getPidTagSurname: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ +{ NSString *stringValue; - + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] flattenedValueAtIndex: 0 forKey: @""]; @@ -1047,7 +1047,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; - + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] flattenedValueAtIndex: 1 forKey: @""]; @@ -1060,12 +1060,12 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; - + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] flattenedValueAtIndex: 2 forKey: @""]; *data = [stringValue asUnicodeInMemCtx: memCtx]; - + return MAPISTORE_SUCCESS; } @@ -1073,12 +1073,12 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; - + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] flattenedValueAtIndex: 3 forKey: @""]; *data = [stringValue asUnicodeInMemCtx: memCtx]; - + return MAPISTORE_SUCCESS; } @@ -1086,12 +1086,12 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; - + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] flattenedValueAtIndex: 4 forKey: @""]; *data = [stringValue asUnicodeInMemCtx: memCtx]; - + return MAPISTORE_SUCCESS; } @@ -1156,7 +1156,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 } - (void) _updatePhotoInVCard: (NGVCard *) card -fromProperties: (NSDictionary *) attachmentProps + fromProperties: (NSDictionary *) attachmentProps { NSString *photoExt, *photoType, *content; CardElement *photo; @@ -1233,7 +1233,7 @@ fromProperties: (NSDictionary *) attachmentProps [newCard setVersion: @"3.0"]; [newCard setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"]; [newCard setProfile: @"vCard"]; - + // Decomposed fullname [newCard setNWithFamily: [properties objectForKey: MAPIPropertyKey(PR_SURNAME_UNICODE)] given: [properties objectForKey: MAPIPropertyKey(PR_GIVEN_NAME_UNICODE)] @@ -1256,26 +1256,26 @@ fromProperties: (NSDictionary *) attachmentProps if (value) { if ([elements count] > 0) - [[elements objectAtIndex: 0] setSingleValue: value forKey: @""]; + [[elements objectAtIndex: 0] setSingleValue: value forKey: @""]; else - [newCard addEmail: value - types: [NSArray arrayWithObject: @"pref"]]; + [newCard addEmail: value + types: [NSArray arrayWithObject: @"pref"]]; } value = [properties objectForKey: MAPIPropertyKey (PidLidEmail2EmailAddress)]; if (value) { if ([elements count] > 1) - [[elements objectAtIndex: 1] setSingleValue: value forKey: @""]; + [[elements objectAtIndex: 1] setSingleValue: value forKey: @""]; else - [newCard addEmail: value types: nil]; + [newCard addEmail: value types: nil]; } value = [properties objectForKey: MAPIPropertyKey (PidLidEmail3EmailAddress)]; if (value) { if ([elements count] > 2) - [[elements objectAtIndex: 2] setSingleValue: value forKey: @""]; + [[elements objectAtIndex: 2] setSingleValue: value forKey: @""]; else - [newCard addEmail: value types: nil]; + [newCard addEmail: value types: nil]; } // @@ -1286,39 +1286,39 @@ fromProperties: (NSDictionary *) attachmentProps // 0x00000000 - No address is selected as the Mailing Address. // 0x00000001 - The Home Address is the Mailing Address. // 0x00000002 - The Work Address is the Mailing Address - // 0x00000003 - The Other Address is the Mailing Address. + // 0x00000003 - The Other Address is the Mailing Address. // // postalAddressId = [[properties objectForKey: MAPIPropertyKey (PidLidPostalAddressId)] - intValue]; - + intValue]; + value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddress)]; if ([value length]) { elements = [newCard childrenWithTag: @"label" - andAttribute: @"type" - havingValue: @"work"]; + andAttribute: @"type" + havingValue: @"work"]; if ([elements count] > 0) - element = [elements objectAtIndex: 0]; + element = [elements objectAtIndex: 0]; else - { - element = [CardElement elementWithTag: @"label"]; - [element addAttribute: @"type" value: @"work"]; - [newCard addChild: element]; - } + { + element = [CardElement elementWithTag: @"label"]; + [element addAttribute: @"type" value: @"work"]; + [newCard addChild: element]; + } if (postalAddressId == 2) - { - [element removeValue: @"pref" - fromAttribute: @"type"]; - [element addAttribute: @"type" - value: @"pref"]; - } + { + [element removeValue: @"pref" + fromAttribute: @"type"]; + [element addAttribute: @"type" + value: @"pref"]; + } [element setSingleValue: value forKey: @""]; } elements = [newCard childrenWithTag: @"adr" - andAttribute: @"type" - havingValue: @"work"]; + andAttribute: @"type" + havingValue: @"work"]; if ([elements count] > 0) element = [elements objectAtIndex: 0]; else @@ -1347,7 +1347,7 @@ fromProperties: (NSDictionary *) attachmentProps value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCountry)]; if (value) [element setSingleValue: value atIndex: 6 forKey: @""]; - + // // home postal addresses handling // @@ -1355,29 +1355,29 @@ fromProperties: (NSDictionary *) attachmentProps if ([value length]) { elements = [newCard childrenWithTag: @"label" - andAttribute: @"type" - havingValue: @"home"]; + andAttribute: @"type" + havingValue: @"home"]; if ([elements count] > 0) - element = [elements objectAtIndex: 0]; + element = [elements objectAtIndex: 0]; else - { - element = [CardElement elementWithTag: @"label"]; - [element addAttribute: @"type" value: @"home"]; - [newCard addChild: element]; - } + { + element = [CardElement elementWithTag: @"label"]; + [element addAttribute: @"type" value: @"home"]; + [newCard addChild: element]; + } if (postalAddressId == 1) - { - [element removeValue: @"pref" - fromAttribute: @"type"]; - [element addAttribute: @"type" - value: @"pref"]; - } + { + [element removeValue: @"pref" + fromAttribute: @"type"]; + [element addAttribute: @"type" + value: @"pref"]; + } [element setSingleValue: value forKey: @""]; } - + elements = [newCard childrenWithTag: @"adr" - andAttribute: @"type" - havingValue: @"home"]; + andAttribute: @"type" + havingValue: @"home"]; if ([elements count] > 0) element = [elements objectAtIndex: 0]; else @@ -1412,27 +1412,27 @@ fromProperties: (NSDictionary *) attachmentProps // // telephone numbers: work, home, fax, pager and mobile // - element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard]; + element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard]; value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_TELEPHONE_NUMBER_UNICODE)]; if (value) [element setSingleValue: value forKey: @""]; - element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard]; + element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard]; value = [properties objectForKey: MAPIPropertyKey(PR_HOME_TELEPHONE_NUMBER_UNICODE)]; if (value) [element setSingleValue: value forKey: @""]; - element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard]; + element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard]; value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_FAX_NUMBER_UNICODE)]; if (value) [element setSingleValue: value forKey: @""]; - - element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard]; + + element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard]; value = [properties objectForKey: MAPIPropertyKey(PR_PAGER_TELEPHONE_NUMBER_UNICODE)]; if (value) [element setSingleValue: value forKey: @""]; - element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard]; + element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard]; value = [properties objectForKey: MAPIPropertyKey(PR_MOBILE_TELEPHONE_NUMBER_UNICODE)]; if (value) [element setSingleValue: value forKey: @""]; @@ -1454,7 +1454,7 @@ fromProperties: (NSDictionary *) attachmentProps value = [properties objectForKey: MAPIPropertyKey(PR_NICKNAME_UNICODE)]; if (value) [newCard setNickname: value]; - + value = [properties objectForKey: MAPIPropertyKey(PR_DEPARTMENT_NAME_UNICODE)]; if (value) units = [NSArray arrayWithObject: value]; @@ -1464,19 +1464,19 @@ fromProperties: (NSDictionary *) attachmentProps value = [properties objectForKey: MAPIPropertyKey(PR_COMPANY_NAME_UNICODE)]; if (value) [newCard setOrg: value units: units]; - + value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_HOME_PAGE_UNICODE)]; if (value) { [[self _elementWithTag: @"url" ofType: @"work" forCard: newCard] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PidLidInstantMessagingAddress)]; if (value) { [[newCard uniqueChildWithTag: @"x-aim"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PR_BIRTHDAY)]; @@ -1500,35 +1500,35 @@ fromProperties: (NSDictionary *) attachmentProps if (value) { [[newCard uniqueChildWithTag: @"x-ms-spouse"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PR_MANAGER_NAME_UNICODE)]; if (value) { [[newCard uniqueChildWithTag: @"x-ms-manager"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PR_ASSISTANT_UNICODE)]; if (value) { [[newCard uniqueChildWithTag: @"x-ms-assistant"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_LOCATION_UNICODE)]; if (value) { [[newCard uniqueChildWithTag: @"x-ms-office"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } value = [properties objectForKey: MAPIPropertyKey(PidLidFreeBusyLocation)]; if (value) { [[newCard uniqueChildWithTag: @"fburl"] - setSingleValue: value forKey: @""]; + setSingleValue: value forKey: @""]; } /* photo */ @@ -1569,7 +1569,7 @@ fromProperties: (NSDictionary *) attachmentProps if ([messageClass isEqualToString: @"IPM.DistList"]) [self saveDistList: memCtx]; else - [self saveContact: memCtx]; + [self saveContact: memCtx]; } From a9fe80c36775636ddfed29705afca15774a8fad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Thu, 3 Dec 2015 15:29:07 +0100 Subject: [PATCH 4/5] oc-contacts: don't return empty values If the property has an empty string, return not found --- OpenChange/MAPIStoreContactsMessage.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 3a2492ad2..9fcbe6933 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -911,9 +911,9 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 NSCalendarDate *dateValue; NSString *stringValue; int rc = MAPISTORE_SUCCESS; - + stringValue = [[sogoObject vCard] bday]; - if (stringValue) + if ([stringValue length] != 0) { dateValue = [NSCalendarDate dateWithString: stringValue calendarFormat: @"%Y-%m-%d"]; @@ -935,7 +935,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-anniversary"] flattenedValuesForKey: @""]; - if (stringValue && ! [stringValue isEqualToString: @""]) + if ([stringValue length] != 0) { dateValue = [NSCalendarDate dateWithString: stringValue calendarFormat: @"%Y-%m-%d"]; @@ -955,7 +955,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-spouse"] flattenedValuesForKey: @""]; - if (stringValue) + if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; @@ -971,7 +971,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-manager"] flattenedValuesForKey: @""]; - if (stringValue) + if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; @@ -987,7 +987,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-assistant"] flattenedValuesForKey: @""]; - if (stringValue) + if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; @@ -1003,7 +1003,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-office"] flattenedValuesForKey: @""]; - if (stringValue) + if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; @@ -1019,7 +1019,7 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"fburl"] flattenedValuesForKey: @""]; - if (stringValue) + if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; From 25dbce42cdee7c472fc740491bbba8ee4aceeff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Thu, 3 Dec 2015 16:31:44 +0100 Subject: [PATCH 5/5] Reorganize methods according to MS-OXOCNTC Nothing has been change but this way is much more readable --- OpenChange/MAPIStoreContactsMessage.m | 987 +++++++++++++------------- 1 file changed, 503 insertions(+), 484 deletions(-) diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 9fcbe6933..b183d445e 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -67,15 +67,6 @@ @end -enum { // [MS-OXOCNTC] 2.2.1.2.11 - AddressBookProviderEmailValueEmail1 = 0, - AddressBookProviderEmailValueEmail2, - AddressBookProviderEmailValueEmail3, - AddressBookProviderEmailValueBusinessFax, - AddressBookProviderEmailValueHomeFax, - AddressBookProviderEmailValuePrimaryFax -}; - @implementation MAPIStoreContactsMessage - (id) init @@ -152,56 +143,6 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return MAPISTORE_SUCCESS; } -- (int) getPidTagTitle: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] title]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagProfession: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - int rc = MAPISTORE_SUCCESS; - - stringValue = [[sogoObject vCard] role]; - if (stringValue) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (int) getPidTagCompanyName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - CardElement *org; - - org = [[sogoObject vCard] org]; - *data = [[org flattenedValueAtIndex: 0 forKey: @""] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagDepartmentName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - CardElement *org; - - org = [[sogoObject vCard] org]; - *data = [[org flattenedValueAtIndex: 1 forKey: @""] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - - (int) getPidTagSendInternetEncoding: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -316,10 +257,105 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return rc; } +- (int) getPidTagSensitivity: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getLongZero: data inMemCtx: memCtx]; +} + +// --------------------------------------------------------- +// Contact Name Properties [MS-OXOCNTC 2.2.1.1] +// --------------------------------------------------------- + +- (int) getPidTagNickname: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[sogoObject vCard] nickname]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagGeneration: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] + flattenedValueAtIndex: 4 + forKey: @""]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagSurname: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] + flattenedValueAtIndex: 0 + forKey: @""]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagMiddleName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] + flattenedValueAtIndex: 2 + forKey: @""]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagGivenName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] + flattenedValueAtIndex: 1 + forKey: @""]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagDisplayNamePrefix: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] + flattenedValueAtIndex: 3 + forKey: @""]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + // ------------------------------------------------------- // Electronic Address Properties [MS-OXOCNTC 2.2.1.2] // ------------------------------------------------------- +enum { // [MS-OXOCNTC] 2.2.1.2.11 + AddressBookProviderEmailValueEmail1 = 0, + AddressBookProviderEmailValueEmail2, + AddressBookProviderEmailValueEmail3, + AddressBookProviderEmailValueBusinessFax, + AddressBookProviderEmailValueHomeFax, + AddressBookProviderEmailValuePrimaryFax +}; + /* Fetch Email1, Email2 and Email3 values from the vcard. Returns nil if not found @@ -358,172 +394,6 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return stringValue; } -- (NSArray *) _buildAddressBookProviderEmailList -{ - // [MS-OXOCNTC] 2.2.1.2.11 - // https://msdn.microsoft.com/en-us/library/ee158427%28v=exchg.80%29.aspx - NSMutableArray *list = [[NSMutableArray alloc] init]; - NSArray *elements; - - // Is there a fax number? - elements = [[[sogoObject vCard] childrenWithTag: @"tel"] - cardElementsWithAttribute: @"type" - havingValue: @"fax"]; - if ([elements count] > 0) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueBusinessFax]]; - - // How many different email addresses? - if ([self _fetchEmailAddress: 1]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail1]]; - else - return list; - if ([self _fetchEmailAddress: 2]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail2]]; - else - return list; - if ([self _fetchEmailAddress: 3]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail3]]; - - return list; -} - -- (int) getPidLidAddressBookProviderArrayType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - // [MS-OXOCNTC] 2.2.1.2.12 - // https://msdn.microsoft.com/en-us/library/ee218011%28v=exchg.80%29.aspx - uint32_t value = 0; - NSArray *emailList = [self _buildAddressBookProviderEmailList]; - - for (NSNumber *maskValue in emailList) - value |= 1 << [maskValue intValue]; - - *data = MAPILongValue (memCtx, value); - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidAddressBookProviderEmailList: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSArray *emailList = [self _buildAddressBookProviderEmailList]; - - *data = [emailList asMVLongInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -/* - Store on *data a string with the display name for the given email (position) - It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist -*/ -- (int) _getPidLidEmailDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - atPosition: (NSUInteger) position -{ - NGVCard *vCard; - NSString *fn, *email; - - email = [self _fetchEmailAddress: position]; - if (!email) return MAPISTORE_ERR_NOT_FOUND; - - vCard = [sogoObject vCard]; - fn = [vCard fn]; - - *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidEmail1DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 1]; -} - -- (int) getPidLidEmail2DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 2]; -} - -- (int) getPidLidEmail3DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 3]; -} - -/* - Return an entry id (either one-off or addressbook entry) for the given email - It can return nil if the email doesn't exist -*/ -- (NSData *) _buildEntryIdForEmail: (NSUInteger) position -{ - NSString *email, *username; - NSData *data; - SOGoUserManager *mgr; - NSDictionary *contactInfos; - - email = [self _fetchEmailAddress: position]; - if (!email) return nil; - - // Try to figure out if this email is from local domain - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - data = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); - } - else - data = MAPIStoreExternalEntryId ([[sogoObject vCard] fn], email); - - return data; -} - -/* - Store on *data an entryId for the given email (position) - It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist -*/ -- (int) _getPidLidEmailOriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - atPosition: (NSUInteger) position -{ - NSData *value; - - value = [self _buildEntryIdForEmail: position]; - if (!value) return MAPISTORE_ERR_NOT_FOUND; - - *data = [value asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidEmail1OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 1]; -} - -- (int) getPidLidEmail2OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 2]; -} - -- (int) getPidLidEmail3OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 3]; -} - /* Store on *data the given email (position) It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist @@ -602,6 +472,116 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return [self getSMTPAddrType: data inMemCtx: memCtx]; } +/* + Store on *data a string with the display name for the given email (position) + It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist +*/ +- (int) _getPidLidEmailDisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + atPosition: (NSUInteger) position +{ + NGVCard *vCard; + NSString *fn, *email; + + email = [self _fetchEmailAddress: position]; + if (!email) return MAPISTORE_ERR_NOT_FOUND; + + vCard = [sogoObject vCard]; + fn = [vCard fn]; + + *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] + asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidEmail1DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 1]; +} + +- (int) getPidLidEmail2DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 2]; +} + +- (int) getPidLidEmail3DisplayName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 3]; +} + +/* + Return an entry id (either one-off or addressbook entry) for the given email + It can return nil if the email doesn't exist +*/ +- (NSData *) _buildEntryIdForEmail: (NSUInteger) position +{ + NSString *email, *username; + NSData *data; + SOGoUserManager *mgr; + NSDictionary *contactInfos; + + email = [self _fetchEmailAddress: position]; + if (!email) return nil; + + // Try to figure out if this email is from local domain + mgr = [SOGoUserManager sharedUserManager]; + contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; + if (contactInfos) + { + username = [contactInfos objectForKey: @"sAMAccountName"]; + data = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); + } + else + data = MAPIStoreExternalEntryId ([[sogoObject vCard] fn], email); + + return data; +} +/* + Store on *data an entryId for the given email (position) + It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist +*/ +- (int) _getPidLidEmailOriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + atPosition: (NSUInteger) position +{ + NSData *value; + + value = [self _buildEntryIdForEmail: position]; + if (!value) return MAPISTORE_ERR_NOT_FOUND; + + *data = [value asBinaryInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidEmail1OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 1]; +} + +- (int) getPidLidEmail2OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 2]; +} + +- (int) getPidLidEmail3OriginalEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getPidLidEmailOriginalEntryId: data + inMemCtx: memCtx + atPosition: 3]; +} + - (int) _getElement: (NSString *) elementTag ofType: (NSString *) aType excluding: (NSString *) aTypeToExclude @@ -638,41 +618,6 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return MAPISTORE_SUCCESS; } -- (int) getPidTagBusinessTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"work" excluding: @"fax" - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagHomeTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"home" excluding: @"fax" - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagMobileTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"cell" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagPagerTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"pager" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagPrimaryTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - - (int) getPidTagBusinessFaxNumber: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -680,130 +625,68 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 atPos: 0 inData: data inMemCtx: memCtx]; } -- (int) getPidTagBusinessHomePage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"url" ofType: @"work" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagPersonalHomePage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"url" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidLidInstantMessagingAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"] - flattenedValuesForKey: @""]; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidLidPostalAddressId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx +/* + [MS-OXOCNTC] 2.2.1.2.11 + https://msdn.microsoft.com/en-us/library/ee158427%28v=exchg.80%29.aspx +*/ +- (NSArray *) _buildAddressBookProviderEmailList { + NSMutableArray *list = [[NSMutableArray alloc] init]; NSArray *elements; - CardElement *element; - uint32_t longValue = 0; - NGVCard *vCard; - vCard = [sogoObject vCard]; - elements = [[vCard childrenWithTag: @"adr"] + // Is there a fax number? + elements = [[[sogoObject vCard] childrenWithTag: @"tel"] cardElementsWithAttribute: @"type" - havingValue: @"pref"]; + havingValue: @"fax"]; if ([elements count] > 0) - { - element = [elements objectAtIndex: 0]; - if ([element hasAttribute: @"type" - havingValue: @"home"]) - longValue = 1; // The Home Address is the mailing address. - else if ([element hasAttribute: @"type" - havingValue: @"work"]) - longValue = 2; // The Work Address is the mailing address. - } - *data = MAPILongValue (memCtx, longValue); + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueBusinessFax]]; + + // How many different email addresses? + if ([self _fetchEmailAddress: 1]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail1]]; + else + return list; + if ([self _fetchEmailAddress: 2]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail2]]; + else + return list; + if ([self _fetchEmailAddress: 3]) + [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail3]]; + + return list; +} + +- (int) getPidLidAddressBookProviderArrayType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + // [MS-OXOCNTC] 2.2.1.2.12 + // https://msdn.microsoft.com/en-us/library/ee218011%28v=exchg.80%29.aspx + uint32_t value = 0; + NSArray *emailList = [self _buildAddressBookProviderEmailList]; + + for (NSNumber *maskValue in emailList) + value |= 1 << [maskValue intValue]; + + *data = MAPILongValue (memCtx, value); return MAPISTORE_SUCCESS; } - -// -// getters when no address is selected as the Mailing Address -// -- (int) getPidTagPostalAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx +- (int) getPidLidAddressBookProviderEmailList: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx { - return [self _getElement: @"label" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; + NSArray *emailList = [self _buildAddressBookProviderEmailList]; + + *data = [emailList asMVLongInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; } -- (int) getPidTagPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} +// --------------------------------------------------------- +// Physical Address Properties [MS-OXOCNTC 2.2.1.3] +// --------------------------------------------------------- -- (int) getPidTagStreetAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 2 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagLocality: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 3 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagStateOrProvince: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 4 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagPostalCode: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 5 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagCountry: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 6 inData: data inMemCtx: memCtx]; -} - -// -// home address getters -// -- (int) getPidLidHomeAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"label" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (int) getPidTagHomeAddressPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} +// Home Address - (int) getPidTagHomeAddressStreet: (void **) data inMemCtx: (TALLOC_CTX *) memCtx @@ -839,23 +722,22 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 atPos: 6 inData: data inMemCtx: memCtx]; } -// -// Work addresss -// -- (int) getPidLidWorkAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx +- (int) getPidTagHomeAddressPostOfficeBox: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx { - return [self _getElement: @"label" ofType: @"work" excluding: nil + return [self _getElement: @"adr" ofType: @"home" excluding: nil atPos: 0 inData: data inMemCtx: memCtx]; } -- (int) getPidLidWorkAddressPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx +- (int) getPidLidHomeAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx { - return [self _getElement: @"adr" ofType: @"work" excluding: nil + return [self _getElement: @"label" ofType: @"home" excluding: nil atPos: 0 inData: data inMemCtx: memCtx]; } +// Work Address + - (int) getPidLidWorkAddressStreet: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -891,20 +773,141 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 atPos: 6 inData: data inMemCtx: memCtx]; } -// -// personal and social getters -// -- (int) getPidTagNickname: (void **) data +- (int) getPidLidWorkAddressPostOfficeBox: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"work" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidLidWorkAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"label" ofType: @"work" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +// Mailing Address + +- (int) getPidTagStreetAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 2 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagLocality: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - NSString *stringValue; + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 3 inData: data inMemCtx: memCtx]; +} - stringValue = [[sogoObject vCard] nickname]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; +- (int) getPidTagStateOrProvince: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 4 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagPostalCode: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 5 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagCountry: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 6 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagPostOfficeBox: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"adr" ofType: @"pref" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagPostalAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"label" ofType: @"pref" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidLidPostalAddressId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSArray *elements; + CardElement *element; + uint32_t longValue = 0; + NGVCard *vCard; + + vCard = [sogoObject vCard]; + elements = [[vCard childrenWithTag: @"adr"] + cardElementsWithAttribute: @"type" + havingValue: @"pref"]; + if ([elements count] > 0) + { + element = [elements objectAtIndex: 0]; + if ([element hasAttribute: @"type" + havingValue: @"home"]) + longValue = 1; // The Home Address is the mailing address. + else if ([element hasAttribute: @"type" + havingValue: @"work"]) + longValue = 2; // The Work Address is the mailing address. + } + *data = MAPILongValue (memCtx, longValue); return MAPISTORE_SUCCESS; } +// ------------------------------------------------------- +// Telephone Properties [MS-OXOCNTC 2.2.1.4] +// ------------------------------------------------------- + +- (int) getPidTagPagerTelephoneNumber: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"tel" ofType: @"pager" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagBusinessTelephoneNumber: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"tel" ofType: @"work" excluding: @"fax" + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagHomeTelephoneNumber: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"tel" ofType: @"home" excluding: @"fax" + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagPrimaryTelephoneNumber: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"tel" ofType: @"pref" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagMobileTelephoneNumber: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"tel" ofType: @"cell" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +// --------------------------------------------------------- +// Event Properties [MS-OXOCNTC 2.2.1.5] +// --------------------------------------------------------- + - (int) getPidTagBirthday: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -947,13 +950,52 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return rc; } -- (int) getPidTagSpouseName: (void **) data +// --------------------------------------------------------- +// Professional Properties [MS-OXOCNTC 2.2.1.6] +// --------------------------------------------------------- + +- (int) getPidTagTitle: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[sogoObject vCard] title]; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagCompanyName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + CardElement *org; + + org = [[sogoObject vCard] org]; + *data = [[org flattenedValueAtIndex: 0 forKey: @""] + asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagDepartmentName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + CardElement *org; + + org = [[sogoObject vCard] org]; + *data = [[org flattenedValueAtIndex: 1 forKey: @""] + asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagOfficeLocation: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; int rc = MAPISTORE_SUCCESS; - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-spouse"] + stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-office"] flattenedValuesForKey: @""]; if ([stringValue length] != 0) *data = [stringValue asUnicodeInMemCtx: memCtx]; @@ -995,15 +1037,14 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return rc; } -- (int) getPidTagOfficeLocation: (void **) data +- (int) getPidTagProfession: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { NSString *stringValue; int rc = MAPISTORE_SUCCESS; - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-office"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) + stringValue = [[sogoObject vCard] role]; + if (stringValue) *data = [stringValue asUnicodeInMemCtx: memCtx]; else rc = MAPISTORE_ERR_NOT_FOUND; @@ -1011,97 +1052,10 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 return rc; } -- (int) getPidLidFreeBusyLocation: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - int rc = MAPISTORE_SUCCESS; +// --------------------------------------------------------- +// Contact Photo Properties [MS-OXOCNTC 2.2.1.8] +// --------------------------------------------------------- - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"fburl"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// -// Decomposed fullname getters -// -- (int) getPidTagSurname: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 0 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagGivenName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 1 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagMiddleName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 2 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagDisplayNamePrefix: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 3 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagGeneration: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 4 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (int) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -/* attachments (photos) */ - (void) _fetchAttachmentParts { NGVCardPhoto *photo; @@ -1196,6 +1150,72 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 } } +// --------------------------------------------------------- +// Other Properties [MS-OXOCNTC 2.2.1.10] +// --------------------------------------------------------- + +- (int) getPidTagSpouseName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + int rc = MAPISTORE_SUCCESS; + + stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-spouse"] + flattenedValuesForKey: @""]; + if ([stringValue length] != 0) + *data = [stringValue asUnicodeInMemCtx: memCtx]; + else + rc = MAPISTORE_ERR_NOT_FOUND; + + return rc; +} + +- (int) getPidLidInstantMessagingAddress: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + + stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"] + flattenedValuesForKey: @""]; + if (!stringValue) + stringValue = @""; + *data = [stringValue asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidFreeBusyLocation: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + NSString *stringValue; + int rc = MAPISTORE_SUCCESS; + + stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"fburl"] + flattenedValuesForKey: @""]; + if ([stringValue length] != 0) + *data = [stringValue asUnicodeInMemCtx: memCtx]; + else + rc = MAPISTORE_ERR_NOT_FOUND; + + return rc; +} + +- (int) getPidTagPersonalHomePage: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"url" ofType: @"home" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +- (int) getPidTagBusinessHomePage: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getElement: @"url" ofType: @"work" excluding: nil + atPos: 0 inData: data inMemCtx: memCtx]; +} + +// --------------------------------------------------------- + - (BOOL) subscriberCanReadMessage { return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; @@ -1572,5 +1592,4 @@ enum { // [MS-OXOCNTC] 2.2.1.2.11 [self saveContact: memCtx]; } - @end