Monotone-Parent: 4e23e038f2b0b7eddf8b30700b8c9a8910768f98

Monotone-Revision: 9235e5dc4d151a3cba8ad842ac39e1b2d18c8201

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2012-01-29T19:55:21
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2012-01-29 19:55:21 +00:00
parent a7da84c804
commit 4b81cb167d
33 changed files with 537 additions and 852 deletions
+129 -151
View File
@@ -25,9 +25,7 @@
#import <Foundation/NSURL.h>
#import <Foundation/NSThread.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoUser.h>
@@ -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