mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-03 15:54:18 +00:00
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:
+129
-151
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user