diff --git a/ChangeLog b/ChangeLog index aa4ac5b72..3be7dbf50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,36 @@ 2012-01-29 Wolfgang Sourdeau + * OpenChange/MAPIStoreMailContext.[hm]: removed + "MAPIStoreInboxContext", "MAPIStoreSentItemsContext", + and child folders."MAPIStoreDraftsContext" and + "MAPIStoreOutboxContext" which have made obsolete by the new + provisioning and instantiation mechanisms. + + * OpenChange/MAPIStoreContext.m (-woContext:, -mapping) + (-authenticator): those methods are now part of + MAPIStoreUserContext. + (-setupBaseFolder:): removed method, obsoleted by those below. + (-getRootFolder:withFID:): the "root folder" is now instantiated + by lookups from the root folder provided by the user context and + the chain of folders listed in the context url path. + (-MAPIStoreFolderClass): new method returning the Class object + representing the context's class of objects. + (-rootSOGoFolder): new method that returns the proper root folder + depending on the context's class of objects. + + * OpenChange/MAPIStoreFolder.m (-initWithURL:inContext:): all + folders are now instantiated the same way since root objects are + now stored in the MAPIStoreUserContext instancesB. + (-setContext:): new setter to provide a reference to the folder's + mapistore context instance from the topmost parent. + (-setupVersionsMessage:): new helper method invoked during the + folder instantiations, from the moment its parent context has been + made available, which does not occur at the same moment for parent + and child folders... + + * OpenChange/MAPIApplication.m (-init): removed the "mapiContext" + but added the "userContext" ivars. + * SoObjects/SOGo/SOGoFolder.m (-outlookFolderClass): removed useless method. diff --git a/OpenChange/MAPIApplication.h b/OpenChange/MAPIApplication.h index 83e02fe6b..2b30e692c 100644 --- a/OpenChange/MAPIApplication.h +++ b/OpenChange/MAPIApplication.h @@ -25,16 +25,16 @@ #import -@class MAPIStoreContext; +@class MAPIStoreUserContext; @interface MAPIApplication : SoApplication { - MAPIStoreContext *mapiContext; + MAPIStoreUserContext *userContext; } - (id) authenticatorInContext: (id) context; -- (void) setMAPIStoreContext: (MAPIStoreContext *) newMAPIStoreContext; +- (void) setUserContext: (MAPIStoreUserContext *) newContext; @end diff --git a/OpenChange/MAPIApplication.m b/OpenChange/MAPIApplication.m index d3002940e..ccdb59614 100644 --- a/OpenChange/MAPIApplication.m +++ b/OpenChange/MAPIApplication.m @@ -27,7 +27,7 @@ #import -#import "MAPIStoreContext.h" +#import "MAPIStoreUserContext.h" #import "MAPIApplication.h" @@ -69,18 +69,18 @@ MAPIApplication *MAPIApp = nil; - (void) dealloc { - [mapiContext release]; + [userContext release]; [super dealloc]; } -- (void) setMAPIStoreContext: (MAPIStoreContext *) newMAPIStoreContext +- (void) setUserContext: (MAPIStoreUserContext *) newContext { - ASSIGN (mapiContext, newMAPIStoreContext); + ASSIGN (userContext, newContext); } - (id) authenticatorInContext: (id) context { - return [mapiContext authenticator]; + return [userContext authenticator]; } @end diff --git a/OpenChange/MAPIStoreAttachment.m b/OpenChange/MAPIStoreAttachment.m index 483944a1c..ca9076ad0 100644 --- a/OpenChange/MAPIStoreAttachment.m +++ b/OpenChange/MAPIStoreAttachment.m @@ -100,7 +100,7 @@ mapistoreMsg = talloc_zero (memCtx, struct mapistore_message); - mapping = [[self context] mapping]; + mapping = [self mapping]; attMessage = [self openEmbeddedMessage]; if (attMessage) diff --git a/OpenChange/MAPIStoreCalendarContext.m b/OpenChange/MAPIStoreCalendarContext.m index 8f05ceb17..7a6622b1d 100644 --- a/OpenChange/MAPIStoreCalendarContext.m +++ b/OpenChange/MAPIStoreCalendarContext.m @@ -21,29 +21,39 @@ */ #import +#import #import "MAPIStoreMapping.h" #import "MAPIStoreCalendarFolder.h" +#import "MAPIStoreUserContext.h" #import "MAPIStoreCalendarContext.h" #undef DEBUG #include +static Class MAPIStoreCalendarFolderK; + @implementation MAPIStoreCalendarContext ++ (void) initialize +{ + MAPIStoreCalendarFolderK = [MAPIStoreCalendarFolder class]; +} + + (NSString *) MAPIModuleName { return @"calendar"; } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *context; context = talloc_zero(memCtx, struct mapistore_contexts_list); - context->url = talloc_asprintf (context, "sogo://%s@calendar/", + context->url = talloc_asprintf (context, "sogo://%s@calendar/personal", [userName UTF8String]); // context->name = "Agenda personnel"; context->main_folder = true; @@ -54,11 +64,14 @@ return context; } -- (void) setupBaseFolder: (NSURL *) newURL +- (Class) MAPIStoreFolderClass { - baseFolder = [MAPIStoreCalendarFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; + return MAPIStoreCalendarFolderK; +} + +- (id) rootSOGoFolder +{ + return [userContext calendarRoot]; } @end diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index b7cdd5466..f2ec0a4dd 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -43,37 +43,6 @@ @implementation MAPIStoreCalendarFolder -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - SOGoUserFolder *userFolder; - SOGoAppointmentFolders *parentFolder; - WOContext *woContext; - - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - woContext = [newContext woContext]; - userFolder = [SOGoUserFolder objectWithName: [newURL user] - inContainer: MAPIApp]; - [parentContainersBag addObject: userFolder]; - [woContext setClientObject: userFolder]; - - parentFolder = [userFolder lookupName: @"Calendar" - inContext: woContext - acquire: NO]; - [parentContainersBag addObject: parentFolder]; - [woContext setClientObject: parentFolder]; - - sogoObject = [parentFolder lookupName: @"personal" - inContext: woContext - acquire: NO]; - [sogoObject retain]; - } - - return self; -} - - (MAPIStoreMessageTable *) messageTable { [self synchroniseCache]; diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index aa46a8962..a27ae244c 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -56,6 +56,7 @@ #import "MAPIStoreMapping.h" #import "MAPIStoreRecurrenceUtils.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSDate+MAPIStore.h" #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -106,14 +107,16 @@ { iCalEvent *event; MAPIStoreContext *context; + MAPIStoreUserContext *userContext; if (!appointmentWrapper) { event = [sogoObject component: NO secure: YES]; context = [self context]; + userContext = [self userContext]; ASSIGN (appointmentWrapper, [MAPIStoreAppointmentWrapper wrapperWithICalEvent: event - andUser: [context ownerUser] + andUser: [userContext sogoUser] andSenderEmail: nil inTimeZone: [self ownerTimeZone] withConnectionInfo: [context connectionInfo]]); @@ -551,7 +554,7 @@ existingCName = [[container sogoObject] resourceNameForEventUID: uid]; if (existingCName) { - mapping = [[self context] mapping]; + mapping = [self mapping]; /* dissociate the object url from the old object's id */ existingURL = [NSString stringWithFormat: @"%@%@", @@ -568,7 +571,7 @@ [mapping registerURL: existingURL withID: objectId]; /* reinstantiate the old sogo object and attach it to self */ - woContext = [[self context] woContext]; + woContext = [[self userContext] woContext]; existingObject = [[container sogoObject] lookupName: existingCName inContext: woContext acquire: NO]; @@ -686,7 +689,7 @@ vCalendar = [iCalCalendar parseSingleFromSource: content]; newEvent = [[vCalendar events] objectAtIndex: 0]; - ownerUser = [[self context] ownerUser]; + ownerUser = [[self userContext] sogoUser]; userPerson = [newEvent userAsAttendee: ownerUser]; [newEvent setTimeStampAsDate: now]; diff --git a/OpenChange/MAPIStoreContactsContext.m b/OpenChange/MAPIStoreContactsContext.m index 34b6257e8..7c4052055 100644 --- a/OpenChange/MAPIStoreContactsContext.m +++ b/OpenChange/MAPIStoreContactsContext.m @@ -22,28 +22,38 @@ #import +#import + #import "MAPIStoreContactsFolder.h" -#import "MAPIStoreMapping.h" +#import "MAPIStoreUserContext.h" #import "MAPIStoreContactsContext.h" #undef DEBUG #include +static Class MAPIStoreContactsFolderK; + @implementation MAPIStoreContactsContext ++ (void) initialize +{ + MAPIStoreContactsFolderK = [MAPIStoreContactsFolder class]; +} + + (NSString *) MAPIModuleName { return @"contacts"; } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *context; context = talloc_zero(memCtx, struct mapistore_contexts_list); - context->url = talloc_asprintf (context, "sogo://%s@contacts/", + context->url = talloc_asprintf (context, "sogo://%s@contacts/personal", [userName UTF8String]); // context->name = "Carnet d'adresses personnel"; context->main_folder = true; @@ -54,11 +64,14 @@ return context; } -- (void) setupBaseFolder: (NSURL *) newURL +- (Class) MAPIStoreFolderClass { - baseFolder = [MAPIStoreContactsFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; + return MAPIStoreContactsFolderK; +} + +- (id) rootSOGoFolder +{ + return [userContext contactsRoot]; } @end diff --git a/OpenChange/MAPIStoreContactsFolder.m b/OpenChange/MAPIStoreContactsFolder.m index ba3d36c6d..6485a3af8 100644 --- a/OpenChange/MAPIStoreContactsFolder.m +++ b/OpenChange/MAPIStoreContactsFolder.m @@ -39,37 +39,6 @@ @implementation MAPIStoreContactsFolder -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - SOGoUserFolder *userFolder; - SOGoContactFolders *parentFolder; - WOContext *woContext; - - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - woContext = [newContext woContext]; - userFolder = [SOGoUserFolder objectWithName: [newURL user] - inContainer: MAPIApp]; - [parentContainersBag addObject: userFolder]; - [woContext setClientObject: userFolder]; - - parentFolder = [userFolder lookupName: @"Contacts" - inContext: woContext - acquire: NO]; - [parentContainersBag addObject: parentFolder]; - [woContext setClientObject: parentFolder]; - - sogoObject = [parentFolder lookupName: @"personal" - inContext: woContext - acquire: NO]; - [sogoObject retain]; - } - - return self; -} - - (MAPIStoreMessageTable *) messageTable { [self synchroniseCache]; diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h index 88c902e42..1ff8dc609 100644 --- a/OpenChange/MAPIStoreContext.h +++ b/OpenChange/MAPIStoreContext.h @@ -47,31 +47,26 @@ @class MAPIStoreAttachment; @class MAPIStoreAttachmentTable; @class MAPIStoreFolder; -@class MAPIStoreMapping; @class MAPIStoreMessage; @class MAPIStoreTable; +@class MAPIStoreUserContext; @interface MAPIStoreContext : NSObject { - struct mapistore_context *mstoreCtx; struct mapistore_connection_info *connInfo; SOGoUser *activeUser; - SOGoUser *ownerUser; + + MAPIStoreUserContext *userContext; NSURL *contextUrl; - - MAPIStoreMapping *mapping; - - MAPIStoreAuthenticator *authenticator; - WOContext *woContext; - - MAPIStoreFolder *baseFolder; } + (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx; + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx; + (int) openContext: (MAPIStoreContext **) contextPtr @@ -83,20 +78,12 @@ withConnectionInfo: (struct mapistore_connection_info *) newConnInfo andTDBIndexing: (struct tdb_wrap *) indexingTdb; -- (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator; -- (MAPIStoreAuthenticator *) authenticator; - - (NSURL *) url; - (struct mapistore_connection_info *) connectionInfo; -- (WOContext *) woContext; -- (MAPIStoreMapping *) mapping; - -- (void) setupRequest; -- (void) tearDownRequest; +- (MAPIStoreUserContext *) userContext; - (SOGoUser *) activeUser; -- (SOGoUser *) ownerUser; // - (id) lookupObject: (NSString *) objectURLString; @@ -117,7 +104,11 @@ /* subclass methods */ + (NSString *) MAPIModuleName; -- (void) setupBaseFolder: (NSURL *) newURL; +- (Class) MAPIStoreFolderClass; + +/* the top-most parent of the context folder: SOGoMailAccount, + SOGoCalendarFolders, ... */ +- (id) rootSOGoFolder; @end diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 9b6a40b46..bc5e99729 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -25,9 +25,7 @@ #import #import -#import #import - #import #import @@ -35,10 +33,8 @@ #import "SOGoMAPIFSFolder.h" #import "SOGoMAPIFSMessage.h" -#import "MAPIApplication.h" #import "MAPIStoreAttachment.h" // #import "MAPIStoreAttachmentTable.h" -#import "MAPIStoreAuthenticator.h" #import "MAPIStoreFolder.h" #import "MAPIStoreFolderTable.h" #import "MAPIStoreMapping.h" @@ -47,6 +43,7 @@ #import "MAPIStoreFAIMessage.h" #import "MAPIStoreFAIMessageTable.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSArray+MAPIStore.h" #import "NSObject+MAPIStore.h" #import "NSString+MAPIStore.h" @@ -69,7 +66,7 @@ /* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */ -static Class NSDataK, NSStringK, MAPIStoreFAIMessageK; +static Class NSExceptionK; static NSMutableDictionary *contextClassMapping; @@ -80,9 +77,7 @@ static NSMutableDictionary *contextClassMapping; NSUInteger count, max; NSString *moduleName; - NSDataK = [NSData class]; - NSStringK = [NSString class]; - MAPIStoreFAIMessageK = [MAPIStoreFAIMessage class]; + NSExceptionK = [NSException class]; contextClassMapping = [NSMutableDictionary new]; classes = GSObjCAllSubclassesOfClass (self); @@ -101,15 +96,19 @@ static NSMutableDictionary *contextClassMapping; } } - + (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *list, *current; NSArray *classes; Class currentClass; NSUInteger count, max; + MAPIStoreUserContext *userContext; + userContext = [MAPIStoreUserContext userContextWithUsername: userName + andTDBIndexing: indexingTdb]; + [userContext activateWithUser: [userContext sogoUser]]; list = NULL; classes = GSObjCAllSubclassesOfClass (self); @@ -118,6 +117,7 @@ static NSMutableDictionary *contextClassMapping; { currentClass = [classes objectAtIndex: count]; current = [currentClass listContextsForUser: userName + withTDBIndexing: indexingTdb inMemCtx: memCtx]; if (current) { @@ -130,49 +130,24 @@ static NSMutableDictionary *contextClassMapping; } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { return NULL; } -static inline enum mapistore_error -_prepareContextClass (Class contextClass, - struct mapistore_connection_info *connInfo, - struct tdb_wrap *indexingTdb, NSURL *url, - MAPIStoreContext **contextP) +static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) { - MAPIStoreContext *context; - MAPIStoreAuthenticator *authenticator; - enum mapistore_error rc; + NSString *urlString; + NSURL *completeURL; - context = [[contextClass alloc] initFromURL: url - withConnectionInfo: connInfo - andTDBIndexing: indexingTdb]; - if (context) - { - [context autorelease]; + urlString = [NSString stringWithFormat: @"sogo://%@", + [NSString stringWithUTF8String: uri]]; + if (![urlString hasSuffix: @"/"]) + urlString = [urlString stringByAppendingString: @"/"]; + completeURL = [NSURL URLWithString: [urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - authenticator = [MAPIStoreAuthenticator new]; - [authenticator setUsername: [url user]]; - [authenticator setPassword: [url password]]; - [context setAuthenticator: authenticator]; - [authenticator release]; - - [context setupRequest]; - [context setupBaseFolder: url]; - [context tearDownRequest]; - if (context->baseFolder && [context->baseFolder sogoObject]) - { - *contextP = context; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_DENIED; - } - else - rc = MAPISTORE_ERROR; - - return rc; + return completeURL; } + (int) openContext: (MAPIStoreContext **) contextPtr @@ -182,7 +157,7 @@ _prepareContextClass (Class contextClass, { MAPIStoreContext *context; Class contextClass; - NSString *module, *completeURLString, *urlString; + NSString *module; NSURL *baseURL; int rc = MAPISTORE_ERR_NOT_FOUND; @@ -190,41 +165,31 @@ _prepareContextClass (Class contextClass, context = nil; - urlString = [NSString stringWithUTF8String: newUri]; - if (urlString) + baseURL = CompleteURLFromMapistoreURI (newUri); + if (baseURL) { - completeURLString = [@"sogo://" stringByAppendingString: urlString]; - if (![completeURLString hasSuffix: @"/"]) - completeURLString = [completeURLString stringByAppendingString: @"/"]; - baseURL = [NSURL URLWithString: [completeURLString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - if (baseURL) + module = [baseURL host]; + if (module) { - module = [baseURL host]; - if (module) + contextClass = [contextClassMapping objectForKey: module]; + if (contextClass) { - contextClass = [contextClassMapping objectForKey: module]; - if (contextClass) + context = [[contextClass alloc] initFromURL: baseURL + withConnectionInfo: newConnInfo + andTDBIndexing: indexingTdb]; + if (context) { - rc = _prepareContextClass (contextClass, - newConnInfo, indexingTdb, - baseURL, &context); - if (rc == MAPISTORE_SUCCESS) - { - *contextPtr = context; - mapistore_mgmt_backend_register_user (newConnInfo, - "SOGo", - [[[context authenticator] username] UTF8String]); - } + [context autorelease]; + rc = MAPISTORE_SUCCESS; + *contextPtr = context; } - else - NSLog (@"ERROR: unrecognized module name '%@'", module); } + else + NSLog (@"ERROR: unrecognized module name '%@'", module); } - else - NSLog (@"ERROR: url could not be parsed"); } else - NSLog (@"ERROR: url is an invalid UTF-8 string"); + NSLog (@"ERROR: url could not be parsed"); return rc; } @@ -233,9 +198,8 @@ _prepareContextClass (Class contextClass, { if ((self = [super init])) { - woContext = [WOContext contextWithRequest: nil]; - [woContext retain]; - baseFolder = nil; + activeUser = nil; + userContext = nil; contextUrl = nil; } @@ -250,6 +214,26 @@ _prepareContextClass (Class contextClass, if ((self = [self init])) { + ASSIGN (contextUrl, newUrl); + + username = [newUrl user]; + if ([username length] == 0) + { + [self errorWithFormat: + @"attempt to instantiate a context with an empty owner"]; + [self release]; + return nil; + } + + ASSIGN (userContext, + [MAPIStoreUserContext userContextWithUsername: username + andTDBIndexing: indexingTdb]); + + mapistore_mgmt_backend_register_user (newConnInfo, + "SOGo", + [username UTF8String]); + + connInfo = newConnInfo; username = [NSString stringWithUTF8String: newConnInfo->username]; ASSIGN (activeUser, [SOGoUser userWithLogin: username]); if (!activeUser) @@ -259,29 +243,6 @@ _prepareContextClass (Class contextClass, [self release]; return nil; } - [woContext setActiveUser: activeUser]; - username = [newUrl user]; - if ([username length] == 0) - { - [self errorWithFormat: - @"attempt to instantiate a context with an empty owner"]; - [self release]; - return nil; - } - ASSIGN (ownerUser, [SOGoUser userWithLogin: username]); - if (!ownerUser) - { - [self errorWithFormat: - @"attempt to instantiate a context without a valid owner"]; - [self release]; - return nil; - } - ASSIGN (mapping, [MAPIStoreMapping mappingForUsername: username - withIndexing: indexingTdb]); - [mapping increaseUseCount]; - ASSIGN (contextUrl, newUrl); - mstoreCtx = newConnInfo->mstore_ctx; - connInfo = newConnInfo; } return self; @@ -290,36 +251,17 @@ _prepareContextClass (Class contextClass, - (void) dealloc { mapistore_mgmt_backend_unregister_user ([self connectionInfo], "SOGo", - [[[self authenticator] username] + [[userContext username] UTF8String]); - [baseFolder release]; - [woContext release]; - [authenticator release]; - [mapping decreaseUseCount]; - [mapping release]; [contextUrl release]; + [userContext release]; [super dealloc]; } -- (WOContext *) woContext +- (MAPIStoreUserContext *) userContext { - return woContext; -} - -- (MAPIStoreMapping *) mapping -{ - return mapping; -} - -- (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator -{ - ASSIGN (authenticator, newAuthenticator); -} - -- (MAPIStoreAuthenticator *) authenticator -{ - return authenticator; + return userContext; } - (NSURL *) url @@ -332,34 +274,11 @@ _prepareContextClass (Class contextClass, return connInfo; } -- (void) setupRequest -{ - NSMutableDictionary *info; - - [MAPIApp setMAPIStoreContext: self]; - info = [[NSThread currentThread] threadDictionary]; - [info setObject: woContext forKey: @"WOContext"]; -} - -- (void) tearDownRequest -{ - NSMutableDictionary *info; - - info = [[NSThread currentThread] threadDictionary]; - [info removeObjectForKey: @"WOContext"]; - [MAPIApp setMAPIStoreContext: nil]; -} - - (SOGoUser *) activeUser { return activeUser; } -- (SOGoUser *) ownerUser -{ - return ownerUser; -} - // - (void) logRestriction: (struct mapi_SRestriction *) res // withState: (MAPIRestrictionState) state // { @@ -379,7 +298,7 @@ _prepareContextClass (Class contextClass, // TDB_DATA key, dbuf; url = [contextUrl absoluteString]; - objectURL = [mapping urlFromID: fmid]; + objectURL = [[userContext mapping] urlFromID: fmid]; if (objectURL) { if ([objectURL hasPrefix: url]) @@ -417,15 +336,64 @@ _prepareContextClass (Class contextClass, return rc; } +- (void) ensureContextFolder +{ +} + - (int) getRootFolder: (MAPIStoreFolder **) folderPtr withFID: (uint64_t) newFid { + enum mapistore_error rc; + MAPIStoreMapping *mapping; + MAPIStoreFolder *baseFolder; + SOGoFolder *currentFolder; + WOContext *woContext; + NSString *path; + NSArray *pathComponents; + NSUInteger count, max; + + mapping = [userContext mapping]; if (![mapping urlFromID: newFid]) [mapping registerURL: [contextUrl absoluteString] withID: newFid]; - *folderPtr = baseFolder; - return (baseFolder) ? MAPISTORE_SUCCESS: MAPISTORE_ERROR; + [userContext activateWithUser: activeUser]; + woContext = [userContext woContext]; + + [self ensureContextFolder]; + currentFolder = [self rootSOGoFolder]; + path = [contextUrl path]; + if ([path hasPrefix: @"/"]) + path = [path substringFromIndex: 1]; + if ([path hasSuffix: @"/"]) + path = [path substringToIndex: [path length] - 1]; + pathComponents = [path componentsSeparatedByString: @"/"]; + max = [pathComponents count]; + for (count = 0; currentFolder && count < max; count++) + { + [woContext setClientObject: currentFolder]; + currentFolder + = [currentFolder lookupName: [pathComponents objectAtIndex: count] + inContext: woContext + acquire: NO]; + if ([currentFolder isKindOfClass: NSExceptionK]) + currentFolder = nil; + } + + if (currentFolder) + { + baseFolder = [[self MAPIStoreFolderClass] + mapiStoreObjectWithSOGoObject: currentFolder + inContainer: nil]; + [baseFolder setContext: self]; + + *folderPtr = baseFolder; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERR_NOT_FOUND; + + return rc; } /* utils */ @@ -460,6 +428,7 @@ _prepareContextClass (Class contextClass, inFolderURL: (NSString *) folderURL { NSString *childURL, *owner; + MAPIStoreMapping *mapping; uint64_t mappingId; uint32_t contextId; void *rootObject; @@ -468,6 +437,7 @@ _prepareContextClass (Class contextClass, childURL = [NSString stringWithFormat: @"%@%@", folderURL, key]; else childURL = folderURL; + mapping = [userContext mapping]; mappingId = [mapping idFromURL: childURL]; if (mappingId == NSNotFound) { @@ -476,11 +446,10 @@ _prepareContextClass (Class contextClass, [mapping registerURL: childURL withID: mappingId]; contextId = 0; - // FIXME: + 7 to skip the BOM or what? - mapistore_search_context_by_uri (mstoreCtx, [folderURL UTF8String] + 7, + mapistore_search_context_by_uri (connInfo->mstore_ctx, [folderURL UTF8String] + 7, &contextId, &rootObject); - owner = [ownerUser login]; - mapistore_indexing_record_add_mid (mstoreCtx, contextId, + owner = [userContext username]; + mapistore_indexing_record_add_mid (connInfo->mstore_ctx, contextId, [owner UTF8String], mappingId); } @@ -507,9 +476,18 @@ _prepareContextClass (Class contextClass, return nil; } -- (void) setupBaseFolder: (NSURL *) newURL +- (Class) MAPIStoreFolderClass { [self subclassResponsibility: _cmd]; + + return nil; +} + +- (id) rootSOGoFolder +{ + [self subclassResponsibility: _cmd]; + + return nil; } @end diff --git a/OpenChange/MAPIStoreFAIMessage.m b/OpenChange/MAPIStoreFAIMessage.m index e0d5faeee..b8fe33988 100644 --- a/OpenChange/MAPIStoreFAIMessage.m +++ b/OpenChange/MAPIStoreFAIMessage.m @@ -22,6 +22,7 @@ #import "MAPIStoreActiveTables.h" #import "MAPIStoreContext.h" +#import "MAPIStoreUserContext.h" #import "NSObject+MAPIStore.h" #import "MAPIStoreFAIMessage.h" @@ -51,9 +52,11 @@ { enum mapistore_error rc; MAPIStoreContext *context; + SOGoUser *ownerUser; context = [self context]; - if ([[context activeUser] isEqual: [context ownerUser]]) + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser]) rc = [super saveMessage]; else rc = MAPISTORE_ERR_DENIED; diff --git a/OpenChange/MAPIStoreFSBaseContext.m b/OpenChange/MAPIStoreFSBaseContext.m index bb34b4795..a3e448082 100644 --- a/OpenChange/MAPIStoreFSBaseContext.m +++ b/OpenChange/MAPIStoreFSBaseContext.m @@ -30,10 +30,14 @@ #import "MAPIStoreFSFolder.h" #import "MAPIStoreMapping.h" +#import "MAPIStoreUserContext.h" #import "SOGoMAPIFSFolder.h" #import "MAPIStoreFSBaseContext.h" +#undef DEBUG +#include + static Class MAPIStoreFSFolderK; @implementation MAPIStoreFSBaseContext @@ -48,12 +52,28 @@ static Class MAPIStoreFSFolderK; return nil; } -- (void) setupBaseFolder: (NSURL *) newURL +- (Class) MAPIStoreFolderClass { - [self logWithFormat: @"invoked %s", __PRETTY_FUNCTION__]; - baseFolder = [MAPIStoreFSFolderK baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; + return MAPIStoreFSFolderK; +} + +- (void) ensureContextFolder +{ + SOGoMAPIFSFolder *contextFolder; + + contextFolder = [SOGoMAPIFSFolder folderWithURL: contextUrl + andTableType: MAPISTORE_MESSAGE_TABLE]; + [contextFolder ensureDirectory]; +} + +- (id) rootSOGoFolder +{ + NSString *urlString; + + urlString = [NSString stringWithFormat: @"sogo://%@@%@/", + [userContext username], [isa MAPIModuleName]]; + return [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: urlString] + andTableType: MAPISTORE_MESSAGE_TABLE]; } @end diff --git a/OpenChange/MAPIStoreFSFolder.m b/OpenChange/MAPIStoreFSFolder.m index 8e8ab1ef6..684ab5a7b 100644 --- a/OpenChange/MAPIStoreFSFolder.m +++ b/OpenChange/MAPIStoreFSFolder.m @@ -34,6 +34,7 @@ #import "MAPIStoreFSMessage.h" #import "MAPIStoreFSMessageTable.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "SOGoMAPIFSFolder.h" #import "SOGoMAPIFSMessage.h" @@ -64,20 +65,6 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; EOKeyValueQualifierK = [EOKeyValueQualifier class]; } -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - sogoObject = [SOGoMAPIFSFolder folderWithURL: newURL - andTableType: MAPISTORE_MESSAGE_TABLE]; - [sogoObject retain]; - } - - return self; -} - - (MAPIStoreMessageTable *) messageTable { return [MAPIStoreFSMessageTable tableForContainer: self]; @@ -126,8 +113,10 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; andSortOrderings: (NSArray *) sortOrderings { NSArray *keys; + SOGoUser *ownerUser; - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser] || [self subscriberCanReadMessages]) keys = [(SOGoMAPIFSFolder *) sogoObject toOneRelationshipKeysMatchingQualifier: qualifier diff --git a/OpenChange/MAPIStoreFallbackContext.m b/OpenChange/MAPIStoreFallbackContext.m index 8368671e3..23c6285b2 100644 --- a/OpenChange/MAPIStoreFallbackContext.m +++ b/OpenChange/MAPIStoreFallbackContext.m @@ -22,8 +22,6 @@ #import -#import "MAPIStoreFSFolder.h" - #import "MAPIStoreFallbackContext.h" #undef DEBUG @@ -37,6 +35,7 @@ } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *context; @@ -53,10 +52,4 @@ return context; } -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreFSFolder baseFolderWithURL: newURL inContext: self]; - [baseFolder retain]; -} - @end diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index 285c2bba3..48e6f5f29 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -28,7 +28,6 @@ @class NSArray; @class NSMutableArray; @class NSNumber; -@class NSURL; @class EOQualifier; @@ -46,7 +45,6 @@ @interface MAPIStoreFolder : MAPIStoreObject { - NSURL *folderURL; MAPIStoreContext *context; NSArray *messageKeys; NSArray *faiMessageKeys; @@ -57,10 +55,7 @@ SOGoMAPIFSMessage *propsMessage; } -+ (id) baseFolderWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext; -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext; +- (void) setContext: (MAPIStoreContext *) newContext; - (NSArray *) activeMessageTables; - (NSArray *) activeFAIMessageTables; @@ -168,6 +163,7 @@ - (BOOL) supportsSubFolders; /* capability */ /* subclass helpers */ +- (void) setupVersionsMessage; - (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids andMessageURLs: (NSArray *) oldMessageURLs andCount: (uint32_t) midCount diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index a8384bb5b..2f5279ba0 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -43,6 +43,7 @@ #import "MAPIStorePermissionsTable.h" #import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSDate+MAPIStore.h" #import "NSString+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -71,17 +72,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe MAPIStoreFolderTableK = [MAPIStoreFolderTable class]; } -+ (id) baseFolderWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - id newFolder; - - newFolder = [[self alloc] initWithURL: newURL inContext: newContext]; - [newFolder autorelease]; - - return newFolder; -} - - (id) init { if ((self = [super init])) @@ -90,7 +80,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe faiMessageKeys = nil; folderKeys = nil; faiFolder = nil; - folderURL = nil; context = nil; propsFolder = nil; @@ -100,54 +89,72 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe return self; } -/* from context */ -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - if ((self = [self init])) - { - context = newContext; - ASSIGN (folderURL, newURL); - ASSIGN (faiFolder, - [SOGoMAPIFSFolder folderWithURL: newURL - andTableType: MAPISTORE_FAI_TABLE]); - ASSIGN (propsFolder, - [SOGoMAPIFSFolder folderWithURL: newURL - andTableType: MAPISTORE_FOLDER_TABLE]); - ASSIGN (propsMessage, - [SOGoMAPIFSMessage objectWithName: @"properties.plist" - inContainer: propsFolder]); - } - - return self; -} - -/* from parent folder */ -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer +- (void) _setupAuxiliaryObjects { NSURL *propsURL; NSString *urlString; - if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer])) + urlString = [[self url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + propsURL = [NSURL URLWithString: urlString]; + [self logWithFormat: @"_setupAuxiliaryObjects: %@", propsURL]; + ASSIGN (faiFolder, + [SOGoMAPIFSFolder folderWithURL: propsURL + andTableType: MAPISTORE_FAI_TABLE]); + ASSIGN (propsFolder, + [SOGoMAPIFSFolder folderWithURL: propsURL + andTableType: MAPISTORE_FOLDER_TABLE]); + ASSIGN (propsMessage, + [SOGoMAPIFSMessage objectWithName: @"properties.plist" + inContainer: propsFolder]); + [self setupVersionsMessage]; +} + +- (id) initWithSOGoObject: (id) newSOGoObject + inContainer: (MAPIStoreObject *) newContainer +{ + /* The instantiation of auxiliary folders is postponed when newContainer is + nil since there is no way to deduce the parent url. When setContext: is + invoked, it becomes possible again. */ + if ((self = [super initWithSOGoObject: newSOGoObject + inContainer: newContainer]) + && newContainer) { - urlString = [[self url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - propsURL = [NSURL URLWithString: urlString]; - ASSIGN (faiFolder, - [SOGoMAPIFSFolder folderWithURL: propsURL - andTableType: MAPISTORE_FAI_TABLE]); - ASSIGN (propsFolder, - [SOGoMAPIFSFolder folderWithURL: propsURL - andTableType: MAPISTORE_FOLDER_TABLE]); - ASSIGN (propsMessage, - [SOGoMAPIFSMessage objectWithName: @"properties.plist" - inContainer: propsFolder]); + [self _setupAuxiliaryObjects]; } return self; } +- (void) setContext: (MAPIStoreContext *) newContext +{ + ASSIGN (context, newContext); + if (newContext) + [self _setupAuxiliaryObjects]; +} + +- (MAPIStoreContext *) context +{ + if (!context) + [self setContext: [container context]]; + + return context; +} + +- (void) dealloc +{ + [propsMessage release]; + [propsFolder release]; + [messageKeys release]; + [faiMessageKeys release]; + [folderKeys release]; + [faiFolder release]; + [context release]; + + [super dealloc]; +} + /* backend interface */ + - (SOGoMAPIFSMessage *) propertiesMessage { return propsMessage; @@ -185,7 +192,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe if ([[self folderKeys] containsObject: folderKey]) { - woContext = [[self context] woContext]; + woContext = [[self userContext] woContext]; sogoFolder = [sogoObject lookupName: folderKey inContext: woContext acquire: NO]; @@ -237,7 +244,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe acquire: NO]; if (msgObject && ![msgObject isKindOfClass: NSExceptionK]) { - [msgObject setContext: [[self context] woContext]]; + [msgObject setContext: [[self userContext] woContext]]; messageClass = [msgObject mapistoreMessageClass]; childMessage = [messageClass mapiStoreObjectWithSOGoObject: msgObject @@ -310,7 +317,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - mapping = [[self context] mapping]; + mapping = [self mapping]; childURL = [mapping urlFromID: fid]; if (childURL) { @@ -333,13 +340,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe MAPIStoreMapping *mapping; NSString *baseURL, *childURL, *folderKey; MAPIStoreFolder *childFolder; + SOGoUser *ownerUser; [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser] || [self subscriberCanCreateSubFolders]) { - mapping = [[self context] mapping]; + mapping = [self mapping]; childURL = [mapping urlFromID: fid]; if (childURL) rc = MAPISTORE_ERR_EXIST; @@ -415,16 +424,18 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe NSString *messageURL; MAPIStoreMapping *mapping; MAPIStoreMessage *message; + SOGoUser *ownerUser; int rc = MAPISTORE_ERR_NOT_FOUND; - mapping = [[self context] mapping]; + mapping = [self mapping]; messageURL = [mapping urlFromID: mid]; if (messageURL) { message = [self lookupMessageByURL: messageURL]; if (message) { - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser] || (readWrite && [message subscriberCanModifyMessage]) || (!readWrite && [message subscriberCanReadMessage])) { @@ -447,15 +458,18 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe MAPIStoreMessage *message; NSString *baseURL, *childURL; MAPIStoreMapping *mapping; + SOGoUser *ownerUser; [self logWithFormat: @"METHOD '%s' -- mid: 0x%.16llx associated: %d", __FUNCTION__, mid, isAssociated]; context = [self context]; - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + + if ([[context activeUser] isEqual: ownerUser] || (!isAssociated && [self subscriberCanCreateMessages])) { - mapping = [[self context] mapping]; + mapping = [self mapping]; if ([mapping urlFromID: mid]) rc = MAPISTORE_ERR_EXIST; else @@ -491,20 +505,23 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe NSArray *activeTables; NSUInteger count, max; id msgObject; + SOGoUser *ownerUser; struct mapistore_connection_info *connInfo; struct mapistore_object_notification_parameters *notif_parameters; int rc; [self logWithFormat: @"-deleteMessageWithMID: mid: 0x%.16llx flags: %d", mid, flags]; - mapping = [[self context] mapping]; + mapping = [self mapping]; childURL = [mapping urlFromID: mid]; if (childURL) { message = [self lookupMessageByURL: childURL]; if (message) { - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + + if ([[context activeUser] isEqual: ownerUser] || (![message isKindOfClass: MAPIStoreFAIMessageK] && [self subscriberCanDeleteMessages])) { @@ -685,16 +702,19 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe NSMutableArray *oldMessageURLs; NSString *oldMessageURL; MAPIStoreMapping *mapping; + SOGoUser *ownerUser; struct Binary_r *targetChangeKey; - if (wantCopy || [[context activeUser] isEqual: [context ownerUser]]) + ownerUser = [[self userContext] sogoUser]; + + if (wantCopy || [[context activeUser] isEqual: ownerUser]) { if ([sourceFolder isKindOfClass: isa] || [self isKindOfClass: [sourceFolder class]]) [self logWithFormat: @"%s: this class could probably implement" @" a specialized/optimized version", __FUNCTION__]; oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; - mapping = [[self context] mapping]; + mapping = [self mapping]; for (count = 0; rc == MAPISTORE_SUCCESS && count < midCount; count++) { oldMessageURL = [mapping urlFromID: srcMids[count]]; @@ -753,6 +773,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [aclFolder setRoles: roles forUser: user]; } +- (void) setupVersionsMessage +{ +} + - (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids andMessageURLs: (NSArray *) oldMessageURLs andCount: (uint32_t) midCount @@ -849,7 +873,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe talloc_free(notif_parameters); // table notification - mapping = [[self context] mapping]; + mapping = [self mapping]; for (count = 0; count < midCount; count++) { messageURL = [mapping urlFromID: targetMids[count]]; @@ -879,7 +903,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe inTableType: tableType]; if (keys) { - mapping = [[self context] mapping]; + mapping = [self mapping]; max = [keys count]; @@ -976,27 +1000,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [propsCopy release]; } -- (void) dealloc -{ - [propsMessage release]; - [propsFolder release]; - [folderURL release]; - [messageKeys release]; - [faiMessageKeys release]; - [folderKeys release]; - [faiFolder release]; - - [super dealloc]; -} - -- (MAPIStoreContext *) context -{ - if (!context) - context = [container context]; - - return context; -} - - (NSArray *) messageKeys { if (!messageKeys) @@ -1132,9 +1135,12 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe inMemCtx: (TALLOC_CTX *) memCtx { uint32_t access = 0; + SOGoUser *ownerUser; BOOL userIsOwner; - userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + ownerUser = [[self userContext] sogoUser]; + + userIsOwner = [[context activeUser] isEqual: ownerUser]; if (userIsOwner || [self subscriberCanModifyMessages]) access |= 0x01; if (userIsOwner || [self subscriberCanReadMessages]) @@ -1285,7 +1291,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe else newMessage = [self createMessage]; [newMessage setIsNew: YES]; - woContext = [[self context] woContext]; + woContext = [[self userContext] woContext]; [[newMessage sogoObject] setContext: woContext]; return newMessage; @@ -1305,10 +1311,14 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe { NSString *url; - if (folderURL) - url = [folderURL absoluteString]; - else + if (container) url = [NSString stringWithFormat: @"%@/", [super url]]; + else + { + url = [[context url] absoluteString]; + if (![url hasSuffix: @"/"]) + url = [NSString stringWithFormat: @"%@/", url]; + } return url; } @@ -1512,10 +1522,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe { uint64_t objectId; - if (folderURL) - objectId = [self idForObjectWithKey: nil]; - else + if (container) objectId = [super objectId]; + else + objectId = [self idForObjectWithKey: nil]; return objectId; } diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index 0a88a9a96..69f1d3d6c 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -34,6 +34,7 @@ #import "MAPIStoreContext.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSData+MAPIStore.h" #import "NSDate+MAPIStore.h" #import "NSString+MAPIStore.h" @@ -46,33 +47,22 @@ @implementation MAPIStoreGCSFolder -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext +- (id) initWithSOGoObject: (id) newSOGoObject + inContainer: (MAPIStoreObject *) newContainer { - if ((self = [super initWithURL: newURL - inContext: newContext])) + if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer])) { - ASSIGN (versionsMessage, - [SOGoMAPIFSMessage objectWithName: @"versions.plist" - inContainer: propsFolder]); activeUserRoles = nil; } return self; } -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer +- (void) setupVersionsMessage { - if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer])) - { - ASSIGN (versionsMessage, - [SOGoMAPIFSMessage objectWithName: @"versions.plist" - inContainer: propsFolder]); - activeUserRoles = nil; - } - - return self; + ASSIGN (versionsMessage, + [SOGoMAPIFSMessage objectWithName: @"versions.plist" + inContainer: propsFolder]); } - (void) dealloc @@ -86,6 +76,7 @@ andSortOrderings: (NSArray *) sortOrderings { static NSArray *fields = nil; + SOGoUser *ownerUser; NSArray *records; NSMutableArray *qualifierArray; EOQualifier *fetchQualifier, *aclQualifier; @@ -98,7 +89,8 @@ initWithObjects: @"c_name", @"c_version", nil]; qualifierArray = [NSMutableArray new]; - if (![[context activeUser] isEqual: [context ownerUser]]) + ownerUser = [[self userContext] sogoUser]; + if (![[context activeUser] isEqual: ownerUser]) { aclQualifier = [self aclQualifier]; if (aclQualifier) @@ -528,12 +520,14 @@ - (NSArray *) activeUserRoles { SOGoUser *activeUser; + WOContext *woContext; if (!activeUserRoles) { activeUser = [[self context] activeUser]; + woContext = [[self userContext] woContext]; activeUserRoles = [activeUser rolesForObject: sogoObject - inContext: [context woContext]]; + inContext: woContext]; [activeUserRoles retain]; } diff --git a/OpenChange/MAPIStoreGCSMessage.m b/OpenChange/MAPIStoreGCSMessage.m index c5e945583..bb636f02d 100644 --- a/OpenChange/MAPIStoreGCSMessage.m +++ b/OpenChange/MAPIStoreGCSMessage.m @@ -30,6 +30,7 @@ #import "MAPIStoreContext.h" #import "MAPIStoreGCSFolder.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSData+MAPIStore.h" #import "MAPIStoreGCSMessage.h" @@ -56,15 +57,17 @@ MAPIStoreContext *context; WOContext *woContext; SoSecurityManager *sm; + MAPIStoreUserContext *userContext; uint32_t access; context = [self context]; - if ([[context activeUser] isEqual: [context ownerUser]]) + userContext = [self userContext]; + if ([[context activeUser] isEqual: [userContext sogoUser]]) access = 0x03; else { sm = [SoSecurityManager sharedSecurityManager]; - woContext = [context woContext]; + woContext = [userContext woContext]; access = 0; if (![sm validatePermission: SoPerm_ChangeImagesAndFiles @@ -89,18 +92,19 @@ inMemCtx: (TALLOC_CTX *) memCtx { MAPIStoreContext *context; + MAPIStoreUserContext *userContext; WOContext *woContext; SoSecurityManager *sm; uint32_t accessLvl; context = [self context]; - if ([[context activeUser] isEqual: [context ownerUser]]) + userContext = [self userContext]; + if ([[context activeUser] isEqual: [userContext sogoUser]]) accessLvl = 1; else { sm = [SoSecurityManager sharedSecurityManager]; - woContext = [context woContext]; - + woContext = [userContext woContext]; if (![sm validatePermission: SoPerm_ChangeImagesAndFiles onObject: sogoObject inContext: woContext]) diff --git a/OpenChange/MAPIStoreMailContext.h b/OpenChange/MAPIStoreMailContext.h index 44778857c..ca67e1664 100644 --- a/OpenChange/MAPIStoreMailContext.h +++ b/OpenChange/MAPIStoreMailContext.h @@ -28,21 +28,9 @@ @interface MAPIStoreMailContext : MAPIStoreContext @end -@interface MAPIStoreInboxContext : MAPIStoreMailContext -@end - -@interface MAPIStoreSentItemsContext : MAPIStoreMailContext -@end - -@interface MAPIStoreDraftsContext : MAPIStoreMailContext -@end - #import "MAPIStoreFSBaseContext.h" @interface MAPIStoreDeletedItemsContext : MAPIStoreFSBaseContext @end -@interface MAPIStoreOutboxContext : MAPIStoreMailContext -@end - #endif /* MAPISTOREMAILCONTEXT_H */ diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m index f4885f10b..1e740fdfd 100644 --- a/OpenChange/MAPIStoreMailContext.m +++ b/OpenChange/MAPIStoreMailContext.m @@ -22,20 +22,90 @@ #import +#import +#import + #import "MAPIStoreMailFolder.h" -#import "MAPIStoreMapping.h" +#import "MAPIStoreUserContext.h" #import "NSString+MAPIStore.h" #import "MAPIStoreMailContext.h" +#include #undef DEBUG #include +static Class MAPIStoreMailFolderK; + @implementation MAPIStoreMailContext ++ (void) initialize +{ + MAPIStoreMailFolderK = [MAPIStoreMailFolder class]; +} + + (NSString *) MAPIModuleName { - return nil; + return @"mail"; +} + ++ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb + inMemCtx: (TALLOC_CTX *) memCtx +{ + struct mapistore_contexts_list *firstContext, *context; + NSString *urlBase, *stringData; + enum mapistore_context_role role[] = {MAPISTORE_MAIL_ROLE, + MAPISTORE_DRAFTS_ROLE, + MAPISTORE_SENTITEMS_ROLE, + MAPISTORE_OUTBOX_ROLE}; + NSString *folderName[4]; + NSUInteger count; + SOGoMailAccount *accountFolder; + MAPIStoreUserContext *userContext; + WOContext *woContext; + + firstContext = NULL; + + userContext = [MAPIStoreUserContext userContextWithUsername: userName + andTDBIndexing: indexingTdb]; + accountFolder = [userContext mailRoot]; + woContext = [userContext woContext]; + folderName[0] = @"folderINBOX"; + folderName[1] = [NSString stringWithFormat: @"folder%@", + [accountFolder draftsFolderNameInContext: woContext]]; + folderName[2] = [NSString stringWithFormat: @"folder%@", + [accountFolder sentFolderNameInContext: woContext]]; + folderName[3] = folderName[1]; + + urlBase = [NSString stringWithFormat: @"sogo://%@:%@@mail/", userName, userName]; + + for (count = 0; count < 4; count++) + { + context = talloc_zero (memCtx, struct mapistore_contexts_list); + stringData = [NSString stringWithFormat: @"%@%@", urlBase, + folderName[count]]; + context->url = [stringData asUnicodeInMemCtx: context]; + /* remove "folder" prefix */ + stringData = [folderName[count] substringFromIndex: 6]; + context->name = [stringData asUnicodeInMemCtx: context]; + context->main_folder = true; + context->role = role[count]; + context->tag = "tag"; + DLIST_ADD_END (firstContext, context, void); + } + + return firstContext; +} + +- (Class) MAPIStoreFolderClass +{ + return MAPIStoreMailFolderK; +} + +- (id) rootSOGoFolder +{ + return [userContext mailRoot]; } + (enum mapistore_context_role) contextRole @@ -45,82 +115,6 @@ @end -@implementation MAPIStoreInboxContext - -+ (NSString *) MAPIModuleName -{ - return @"inbox"; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *context; - NSString *url; - - context = talloc_zero(memCtx, struct mapistore_contexts_list); - url = [NSString stringWithFormat: @"sogo://%@:%@@%@/", userName, userName, [self MAPIModuleName]]; - context->url = [url asUnicodeInMemCtx: context]; - // context->name = "Inbox"; - context->main_folder = true; - context->role = [self contextRole]; - context->tag = "tag"; - context->prev = context; - - return context; -} - -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreInboxFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; -} - -@end - -@implementation MAPIStoreSentItemsContext - -+ (NSString *) MAPIModuleName -{ - return @"sent-items"; -} - -+ (enum mapistore_context_role) contextRole -{ - return MAPISTORE_SENTITEMS_ROLE; -} - -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreSentItemsFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; -} - -@end - -@implementation MAPIStoreDraftsContext - -+ (NSString *) MAPIModuleName -{ - return @"drafts"; -} - -+ (enum mapistore_context_role) contextRole -{ - return MAPISTORE_DRAFTS_ROLE; -} - -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreDraftsFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; -} - -@end - #import "MAPIStoreFSFolder.h" @implementation MAPIStoreDeletedItemsContext @@ -135,38 +129,4 @@ return MAPISTORE_DELETEDITEMS_ROLE; } -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreFSFolder baseFolderWithURL: newURL inContext: self]; - [baseFolder retain]; -} - -// - (void) setupBaseFolder: (NSURL *) newURL -// { -// baseFolder = [MAPIStoreDeletedItemsFolder baseFolderWithURL: newURL -// inContext: self]; -// [baseFolder retain]; -// } - -@end - -@implementation MAPIStoreOutboxContext - -+ (NSString *) MAPIModuleName -{ - return @"outbox"; -} - -+ (enum mapistore_context_role) contextRole -{ - return MAPISTORE_OUTBOX_ROLE; -} - -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreOutboxFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; -} - @end diff --git a/OpenChange/MAPIStoreMailFolder.h b/OpenChange/MAPIStoreMailFolder.h index 3d8bad3f2..300a5dc3a 100644 --- a/OpenChange/MAPIStoreMailFolder.h +++ b/OpenChange/MAPIStoreMailFolder.h @@ -37,13 +37,13 @@ @interface MAPIStoreMailFolder : MAPIStoreFolder { SOGoMAPIFSMessage *versionsMessage; + BOOL usesAltNameSpace; } /* subclasses */ - (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) account inContext: (WOContext *) woContext; - /* synchronisation & versioning */ - (BOOL) synchroniseCache; - (NSNumber *) modseqFromMessageChangeNumber: (NSNumber *) changeNum; @@ -56,23 +56,4 @@ @end -@interface MAPIStoreInboxFolder : MAPIStoreMailFolder -{ - BOOL usesAltNameSpace; -} - -@end - -@interface MAPIStoreSentItemsFolder : MAPIStoreMailFolder -@end - -@interface MAPIStoreDraftsFolder : MAPIStoreMailFolder -@end - -// @interface MAPIStoreDeletedItemsFolder : MAPIStoreFFolder -// @end - -@interface MAPIStoreOutboxFolder : MAPIStoreMailFolder -@end - #endif /* MAPISTOREMAILFOLDER_H */ diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 57fc1b348..c9391c3ff 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -77,57 +77,6 @@ static Class SOGoMailFolderK; [MAPIStoreAppointmentWrapper class]; } -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - SOGoUserFolder *userFolder; - SOGoMailAccounts *accountsFolder; - SOGoMailAccount *accountFolder; - SOGoFolder *currentContainer; - WOContext *woContext; - - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - woContext = [newContext woContext]; - userFolder = [SOGoUserFolder objectWithName: [newURL user] - inContainer: MAPIApp]; - [parentContainersBag addObject: userFolder]; - [woContext setClientObject: userFolder]; - - accountsFolder = [userFolder lookupName: @"Mail" - inContext: woContext - acquire: NO]; - [parentContainersBag addObject: accountsFolder]; - [woContext setClientObject: accountsFolder]; - - accountFolder = [accountsFolder lookupName: @"0" - inContext: woContext - acquire: NO]; - [[accountFolder imap4Connection] - enableExtension: @"QRESYNC"]; - - [parentContainersBag addObject: accountFolder]; - [woContext setClientObject: accountFolder]; - - sogoObject = [self specialFolderFromAccount: accountFolder - inContext: woContext]; - [sogoObject retain]; - currentContainer = [sogoObject container]; - while (currentContainer != (SOGoFolder *) accountFolder) - { - [parentContainersBag addObject: currentContainer]; - currentContainer = [currentContainer container]; - } - - ASSIGN (versionsMessage, - [SOGoMAPIFSMessage objectWithName: @"versions.plist" - inContainer: propsFolder]); - } - - return self; -} - - (id) initWithSOGoObject: (id) newSOGoObject inContainer: (MAPIStoreObject *) newContainer { @@ -135,15 +84,20 @@ static Class SOGoMailFolderK; if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer])) { + usesAltNameSpace = NO; // urlString = [[self url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - ASSIGN (versionsMessage, - [SOGoMAPIFSMessage objectWithName: @"versions.plist" - inContainer: propsFolder]); } return self; } +- (void) setupVersionsMessage +{ + ASSIGN (versionsMessage, + [SOGoMAPIFSMessage objectWithName: @"versions.plist" + inContainer: propsFolder]); +} + - (void) dealloc { [versionsMessage release]; @@ -166,7 +120,6 @@ static Class SOGoMailFolderK; - (NSString *) createFolder: (struct SRow *) aRow withFID: (uint64_t) newFID - inContainer: (id) subfolderParent { NSString *folderName, *nameInContainer; SOGoMailFolder *newFolder; @@ -188,7 +141,7 @@ static Class SOGoMailFolderK; nameInContainer = [NSString stringWithFormat: @"folder%@", [folderName asCSSIdentifier]]; newFolder = [SOGoMailFolderK objectWithName: nameInContainer - inContainer: subfolderParent]; + inContainer: sogoObject]; if (![newFolder create]) nameInContainer = nil; } @@ -196,13 +149,6 @@ static Class SOGoMailFolderK; return nameInContainer; } -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID -{ - return [self createFolder: aRow withFID: newFID - inContainer: sogoObject]; -} - - (int) getPrContentUnread: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -896,7 +842,7 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) wantCopy: wantCopy]; /* Conversion of mids to IMAP uids */ - mapping = [[self context] mapping]; + mapping = [self mapping]; uids = [NSMutableArray arrayWithCapacity: midCount]; oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; for (count = 0; count < midCount; count++) @@ -1060,172 +1006,3 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) } @end - -@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder - -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - NSDictionary *list, *response; - NGImap4Client *client; - - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - client = [[(SOGoMailFolder *) sogoObject imap4Connection] client]; - list = [client list: @"" pattern: @"INBOX"]; - response = [[list objectForKey: @"RawResponse"] objectForKey: @"list"]; - usesAltNameSpace = [[response objectForKey: @"flags"] containsObject: @"noinferiors"]; - } - - return self; -} - -- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder - inContext: (WOContext *) woContext -{ - return [accountFolder inboxFolderInContext: woContext]; -} - -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID -{ - id subfolderParent; - - if (usesAltNameSpace) - subfolderParent = [(SOGoMailFolder *) sogoObject mailAccountFolder]; - else - subfolderParent = sogoObject; - - return [self createFolder: aRow withFID: newFID - inContainer: subfolderParent]; -} - -- (NSMutableString *) _imapFolderNameRepresentation: (NSString *) subfolderName -{ - NSMutableString *representation; - - if (usesAltNameSpace) - { - /* with "altnamespace", the subfolders are NEVER subfolders of INBOX... */; - if (![subfolderName hasPrefix: @"folder"]) - abort (); - representation - = [NSMutableString stringWithString: - [subfolderName substringFromIndex: 6]]; - } - else - representation = [super _imapFolderNameRepresentation: subfolderName]; - - return representation; -} - -- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - NSMutableArray *subfolderKeys; - SOGoMailAccount *account; - - if (usesAltNameSpace) - { - if (qualifier) - [self errorWithFormat: @"qualifier is not used for folders"]; - if (sortOrderings) - [self errorWithFormat: @"sort orderings are not used for folders"]; - - account = [(SOGoMailFolder *) sogoObject mailAccountFolder]; - subfolderKeys - = [[account toManyRelationshipKeysWithNamespaces: NO] - mutableCopy]; - [subfolderKeys removeObject: @"folderINBOX"]; - - [self _cleanupSubfolderKeys: subfolderKeys]; - } - else - subfolderKeys = [[super folderKeysMatchingQualifier: qualifier - andSortOrderings: sortOrderings] - mutableCopy]; - - /* TODO: remove special folders */ - - [subfolderKeys autorelease]; - - return subfolderKeys; -} - -- (id) lookupFolder: (NSString *) childKey -{ - MAPIStoreMailFolder *childFolder = nil; - SOGoMailAccount *account; - SOGoMailFolder *sogoFolder; - WOContext *woContext; - - if (usesAltNameSpace) - { - if ([[self folderKeys] containsObject: childKey]) - { - woContext = [[self context] woContext]; - account = [(SOGoMailFolder *) sogoObject mailAccountFolder]; - sogoFolder = [account lookupName: childKey inContext: woContext - acquire: NO]; - [sogoFolder setContext: woContext]; - childFolder = [MAPIStoreMailFolder mapiStoreObjectWithSOGoObject: sogoFolder - inContainer: self]; - } - } - else - childFolder = [super lookupFolder: childKey]; - - return childFolder; -} - -- (BOOL) supportsSubFolders -{ - return !usesAltNameSpace; -} - -@end - -@implementation MAPIStoreSentItemsFolder : MAPIStoreMailFolder - -- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder - inContext: (WOContext *) woContext -{ - return [accountFolder sentFolderInContext: woContext]; -} - -@end - -@implementation MAPIStoreDraftsFolder : MAPIStoreMailFolder - -- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder - inContext: (WOContext *) woContext -{ - return [accountFolder draftsFolderInContext: woContext]; -} - -@end - -// @implementation MAPIStoreDeletedItemsFolder : MAPIStoreMailFolder - -// - (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder -// inContext: (WOContext *) woContext -// { -// return [accountFolder trashFolderInContext: woContext]; -// } - -// @end - - -// -// -// -@implementation MAPIStoreOutboxFolder : MAPIStoreMailFolder - -- (SOGoMailFolder *) specialFolderFromAccount: (SOGoMailAccount *) accountFolder - inContext: (WOContext *) woContext -{ - return [accountFolder draftsFolderInContext: woContext]; -} - -@end diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 8c165cc6e..00130d20c 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -62,7 +62,7 @@ @class iCalCalendar, iCalEvent; -static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK; +static Class NSExceptionK; @interface NSString (MAPIStoreMIME) @@ -105,8 +105,6 @@ static Class NSExceptionK, MAPIStoreSentItemsFolderK, MAPIStoreDraftsFolderK; + (void) initialize { NSExceptionK = [NSException class]; - MAPIStoreSentItemsFolderK = [MAPIStoreSentItemsFolder class]; - MAPIStoreDraftsFolderK = [MAPIStoreDraftsFolder class]; } - (id) init @@ -582,9 +580,9 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) coreInfos = [sogoObject fetchCoreInfos]; flags = [coreInfos objectForKey: @"flags"]; - if ([container isKindOfClass: MAPIStoreSentItemsFolderK] - || [container isKindOfClass: MAPIStoreDraftsFolderK]) - v |= MSGFLAG_FROMME; + // if ([container isKindOfClass: MAPIStoreSentItemsFolderK] + // || [container isKindOfClass: MAPIStoreDraftsFolderK]) + // v |= MSGFLAG_FROMME; if ([flags containsObject: @"seen"]) v |= MSGFLAG_READ; if ([[self attachmentKeys] diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index 5952eb405..a8e06b92c 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -813,7 +813,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, if (error) [self logWithFormat: @"an error occurred: '%@'", error]; - mapping = [[self context] mapping]; + mapping = [self mapping]; [mapping unregisterURLWithID: [self objectId]]; [self setIsNew: NO]; [properties removeAllObjects]; @@ -851,7 +851,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, newIdString = [[flag componentsSeparatedByString: @" "] objectAtIndex: 2]; mid = [self objectId]; - mapping = [[self context] mapping]; + mapping = [self mapping]; [mapping unregisterURLWithID: mid]; [sogoObject setNameInContainer: [NSString stringWithFormat: @"%@.eml", newIdString]]; [mapping registerURL: [self url] withID: mid]; diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index be25d9a18..7e7a61b2e 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -39,6 +39,7 @@ #import "MAPIStorePropertySelectors.h" #import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" #import "NSString+MAPIStore.h" @@ -286,10 +287,11 @@ rtf2html (NSData *compressedRTF) { enum mapistore_error rc; MAPIStoreContext *context; + SOGoUser *ownerUser; context = [self context]; - - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser] || [self subscriberCanModifyMessage]) rc = [super addPropertiesFromRow: aRow]; else @@ -432,9 +434,11 @@ rtf2html (NSData *compressedRTF) uint64_t folderId; struct mapistore_context *mstoreCtx; MAPIStoreContext *context; + SOGoUser *ownerUser; context = [self context]; - if ([[context activeUser] isEqual: [context ownerUser]] + ownerUser = [[self userContext] sogoUser]; + if ([[context activeUser] isEqual: ownerUser] || ((isNew && [(MAPIStoreFolder *) container subscriberCanCreateMessages]) || (!isNew && [self subscriberCanModifyMessage]))) @@ -560,9 +564,11 @@ rtf2html (NSData *compressedRTF) uint32_t access = 0; BOOL userIsOwner; MAPIStoreContext *context; + SOGoUser *ownerUser; context = [self context]; - userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + ownerUser = [[self userContext] sogoUser]; + userIsOwner = [[context activeUser] isEqual: ownerUser]; if (userIsOwner || [self subscriberCanModifyMessage]) access |= 0x01; if (userIsOwner || [self subscriberCanReadMessage]) @@ -587,9 +593,11 @@ rtf2html (NSData *compressedRTF) uint32_t access = 0; BOOL userIsOwner; MAPIStoreContext *context; + SOGoUser *ownerUser; context = [self context]; - userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + ownerUser = [[self userContext] sogoUser]; + userIsOwner = [[context activeUser] isEqual: ownerUser]; if (userIsOwner || [self subscriberCanModifyMessage]) access = 0x01; else @@ -862,14 +870,15 @@ rtf2html (NSData *compressedRTF) - (NSArray *) activeUserRoles { MAPIStoreContext *context; + MAPIStoreUserContext *userContext; if (!activeUserRoles) { context = [self context]; - + userContext = [self userContext]; activeUserRoles = [[context activeUser] rolesForObject: sogoObject - inContext: [context woContext]]; + inContext: [userContext woContext]]; [activeUserRoles retain]; } diff --git a/OpenChange/MAPIStoreNotesContext.m b/OpenChange/MAPIStoreNotesContext.m index b6ca62bc3..b73a4032a 100644 --- a/OpenChange/MAPIStoreNotesContext.m +++ b/OpenChange/MAPIStoreNotesContext.m @@ -38,6 +38,7 @@ } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *context; @@ -54,11 +55,4 @@ return context; } -- (void) setupBaseFolder: (NSURL *) newURL -{ - baseFolder = [MAPIStoreNotesFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; -} - @end diff --git a/OpenChange/MAPIStoreObject.h b/OpenChange/MAPIStoreObject.h index d3b10cfbe..773db8bd4 100644 --- a/OpenChange/MAPIStoreObject.h +++ b/OpenChange/MAPIStoreObject.h @@ -35,8 +35,11 @@ @class EOQualifier; +@class MAPIStoreContext; @class MAPIStoreFolder; +@class MAPIStoreMapping; @class MAPIStoreTable; +@class MAPIStoreUserContext; @interface MAPIStoreObject : NSObject { @@ -71,7 +74,9 @@ - (id) sogoObject; - (MAPIStoreObject *) container; -- (id) context; +- (MAPIStoreContext *) context; +- (MAPIStoreUserContext *) userContext; +- (MAPIStoreMapping *) mapping; - (void) cleanupCaches; diff --git a/OpenChange/MAPIStoreObject.m b/OpenChange/MAPIStoreObject.m index 6652940f1..d064aca30 100644 --- a/OpenChange/MAPIStoreObject.m +++ b/OpenChange/MAPIStoreObject.m @@ -30,6 +30,7 @@ #import "MAPIStoreFolder.h" #import "MAPIStorePropertySelectors.h" #import "MAPIStoreTypes.h" +#import "MAPIStoreUserContext.h" #import "NSDate+MAPIStore.h" #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -170,11 +171,21 @@ static Class NSExceptionK, MAPIStoreFolderK; return [sogoObject nameInContainer]; } -- (id) context +- (MAPIStoreContext *) context { return [container context]; } +- (MAPIStoreUserContext *) userContext +{ + return [[self context] userContext]; +} + +- (MAPIStoreMapping *) mapping +{ + return [[self userContext] mapping]; +} + - (void) cleanupCaches { } @@ -217,7 +228,7 @@ static Class NSExceptionK, MAPIStoreFolderK; NSTimeZone *tz; WOContext *woContext; - woContext = [[self context] woContext]; + woContext = [[self userContext] woContext]; owner = [sogoObject ownerInContext: woContext]; ud = [[SOGoUser userWithLogin: owner] userDefaults]; tz = [ud timeZone]; diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index 7f6878f96..a5fbf7982 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -52,6 +52,7 @@ static enum mapistore_error sogo_backend_unexpected_error() { NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + abort(); return MAPISTORE_SUCCESS; } @@ -147,7 +148,8 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, } static enum mapistore_error -sogo_backend_list_contexts(const char *username, TALLOC_CTX *mem_ctx, +sogo_backend_list_contexts(const char *username, struct tdb_wrap *indexingTdb, + TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listp) { NSAutoreleasePool *pool; @@ -162,6 +164,7 @@ sogo_backend_list_contexts(const char *username, TALLOC_CTX *mem_ctx, { userName = [NSString stringWithUTF8String: username]; *contexts_listp = [MAPIStoreContextK listAllContextsForUser: userName + withTDBIndexing: indexingTdb inMemCtx: mem_ctx]; rc = MAPISTORE_SUCCESS; } diff --git a/OpenChange/MAPIStoreTasksContext.m b/OpenChange/MAPIStoreTasksContext.m index 644176aa3..c100cc3c2 100644 --- a/OpenChange/MAPIStoreTasksContext.m +++ b/OpenChange/MAPIStoreTasksContext.m @@ -21,29 +21,38 @@ */ #import +#import #import "MAPIStoreTasksFolder.h" -#import "MAPIStoreMapping.h" +#import "MAPIStoreUserContext.h" #import "MAPIStoreTasksContext.h" #undef DEBUG #include +static Class MAPIStoreTasksFolderK; + @implementation MAPIStoreTasksContext ++ (void) initialize +{ + MAPIStoreTasksFolderK = [MAPIStoreTasksFolder class]; +} + + (NSString *) MAPIModuleName { return @"tasks"; } + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { struct mapistore_contexts_list *context; context = talloc_zero(memCtx, struct mapistore_contexts_list); - context->url = talloc_asprintf (context, "sogo://%s@tasks/", + context->url = talloc_asprintf (context, "sogo://%s@tasks/personal", [userName UTF8String]); // context->name = "Tâches personnelles"; context->main_folder = true; @@ -54,11 +63,14 @@ return context; } -- (void) setupBaseFolder: (NSURL *) newURL +- (Class) MAPIStoreFolderClass { - baseFolder = [MAPIStoreTasksFolder baseFolderWithURL: newURL - inContext: self]; - [baseFolder retain]; + return MAPIStoreTasksFolderK; +} + +- (id) rootSOGoFolder +{ + return [userContext calendarRoot]; } @end diff --git a/OpenChange/MAPIStoreTasksFolder.m b/OpenChange/MAPIStoreTasksFolder.m index 228fb8eb5..323bdf6e8 100644 --- a/OpenChange/MAPIStoreTasksFolder.m +++ b/OpenChange/MAPIStoreTasksFolder.m @@ -42,37 +42,6 @@ @implementation MAPIStoreTasksFolder -- (id) initWithURL: (NSURL *) newURL - inContext: (MAPIStoreContext *) newContext -{ - SOGoUserFolder *userFolder; - SOGoAppointmentFolders *parentFolder; - WOContext *woContext; - - if ((self = [super initWithURL: newURL - inContext: newContext])) - { - woContext = [newContext woContext]; - userFolder = [SOGoUserFolder objectWithName: [newURL user] - inContainer: MAPIApp]; - [parentContainersBag addObject: userFolder]; - [woContext setClientObject: userFolder]; - - parentFolder = [userFolder lookupName: @"Calendar" - inContext: woContext - acquire: NO]; - [parentContainersBag addObject: parentFolder]; - [woContext setClientObject: parentFolder]; - - sogoObject = [parentFolder lookupName: @"personal" - inContext: woContext - acquire: NO]; - [sogoObject retain]; - } - - return self; -} - - (MAPIStoreMessageTable *) messageTable { [self synchroniseCache]; diff --git a/OpenChange/SOGoMAPIFSFolder.m b/OpenChange/SOGoMAPIFSFolder.m index b2cf7cbe5..7969d9e65 100644 --- a/OpenChange/SOGoMAPIFSFolder.m +++ b/OpenChange/SOGoMAPIFSFolder.m @@ -96,7 +96,7 @@ static NSString *privateDir = nil; - (id) initWithURL: (NSURL *) url andTableType: (uint8_t) tableType { - NSString *path, *tableParticle; + NSString *path, *username, *tableParticle; if ((self = [self init])) { @@ -116,9 +116,11 @@ static NSString *privateDir = nil; path = [url path]; if (![path hasSuffix: @"/"]) path = [NSString stringWithFormat: @"%@/", path]; + username = [url user]; directory = [NSString stringWithFormat: @"%@/mapistore/SOGo/%@/%@/%@%@", - privateDir, [url user], tableParticle, + privateDir, username, tableParticle, [url host], path]; + [self setOwner: username]; [self logWithFormat: @"directory: %@", directory]; [directory retain]; ASSIGN (nameInContainer, [path stringByDeletingLastPathComponent]);