From bd9d6678defcbd65e2b7858c851f49155c9177cd Mon Sep 17 00:00:00 2001 From: helge Date: Fri, 8 Jul 2005 13:27:51 +0000 Subject: [PATCH] added caching of shared mailbox info added discovery of shared from addresses git-svn-id: http://svn.opengroupware.org/SOGo/trunk@704 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/SOGo/AgenorUserManager.h | 3 + SOGo/SoObjects/SOGo/AgenorUserManager.m | 136 ++++++++++++++++++----- SOGo/SoObjects/SOGo/ChangeLog | 11 ++ SOGo/SoObjects/SOGo/GNUmakefile | 7 +- SOGo/SoObjects/SOGo/GNUmakefile.preamble | 1 + SOGo/SoObjects/SOGo/SOGoLRUCache.m | 6 +- SOGo/SoObjects/SOGo/Version | 2 +- SOGo/SoObjects/SOGo/agenor_emails4uid.m | 85 ++++++++++++++ 8 files changed, 220 insertions(+), 31 deletions(-) create mode 100644 SOGo/SoObjects/SOGo/agenor_emails4uid.m diff --git a/SOGo/SoObjects/SOGo/AgenorUserManager.h b/SOGo/SoObjects/SOGo/AgenorUserManager.h index 4aef5cd6..7df36f4d 100644 --- a/SOGo/SoObjects/SOGo/AgenorUserManager.h +++ b/SOGo/SoObjects/SOGo/AgenorUserManager.h @@ -39,6 +39,8 @@ SOGoLRUCache *serverCache; SOGoLRUCache *uidCache; SOGoLRUCache *emailCache; + SOGoLRUCache *shareStoreCache; + SOGoLRUCache *shareEMailCache; } + (id)sharedUserManager; @@ -56,6 +58,7 @@ - (NSString *)getServerForUID:(NSString *)_uid; - (NSArray *)getSharedMailboxAccountStringsForUID:(NSString *)_uid; +- (NSArray *)getSharedMailboxEMailsForUID:(NSString *)_uid; - (NSURL *)getFreeBusyURLForUID:(NSString *)_uid; diff --git a/SOGo/SoObjects/SOGo/AgenorUserManager.m b/SOGo/SoObjects/SOGo/AgenorUserManager.m index 109d8c0b..c47f0365 100644 --- a/SOGo/SoObjects/SOGo/AgenorUserManager.m +++ b/SOGo/SoObjects/SOGo/AgenorUserManager.m @@ -46,8 +46,13 @@ static BOOL debugOn = NO; static BOOL useLDAP = NO; static NSString *ldapHost = nil; static NSString *ldapBaseDN = nil; -static NSString *fallbackIMAP4Server = nil; -static NSString *defaultMailDomain = @"equipement.gouv.fr"; +static NSString *fallbackIMAP4Server = nil; +static NSString *defaultMailDomain = @"equipement.gouv.fr"; +static NSString *shareLDAPClass = @"mineqMelBoite"; +static NSString *shareLoginSeparator = @".-."; +static NSString *mailEmissionAttrName = @"mineqMelmailEmission"; + +static NSArray *fromEMailAttrs = nil; + (void)initialize { static BOOL didInit = NO; @@ -73,6 +78,9 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; NSLog(@"Note: using fallback IMAP4 server: '%@'", fallbackIMAP4Server); else fallbackIMAP4Server = nil; + + fromEMailAttrs = + [[NSArray alloc] initWithObjects:mailEmissionAttrName, nil]; } + (id)sharedUserManager { @@ -85,19 +93,23 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; - (id)init { self = [super init]; if(self) { - self->serverCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; - self->cnCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; - self->uidCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; - self->emailCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->serverCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->cnCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->uidCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->emailCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->shareStoreCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->shareEMailCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; } return self; } - (void)dealloc { - [self->serverCache release]; - [self->cnCache release]; - [self->uidCache release]; - [self->emailCache release]; + [self->shareStoreCache release]; + [self->shareEMailCache release]; + [self->serverCache release]; + [self->cnCache release]; + [self->uidCache release]; + [self->emailCache release]; [super dealloc]; } @@ -244,7 +256,6 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; } - (NSString *)primaryGetEmailForAgenorUID:(NSString *)_uid { - static NSArray *emailAttrs = nil; NGLdapConnection *conn; EOQualifier *q; NSEnumerator *resultEnum; @@ -253,15 +264,12 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; NSString *email; unsigned count; - if (emailAttrs == nil) - emailAttrs = [[NSArray alloc] initWithObjects:@"mineqMelmailEmission",nil]; - q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid]; conn = [self ldapConnection]; resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN qualifier:q - attributes:emailAttrs]; + attributes:fromEMailAttrs]; entry = [resultEnum nextObject]; if (entry == nil) { if(debugOn) { @@ -271,13 +279,13 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; } return nil; } - emailAttr = [entry attributeWithName:@"mineqMelmailEmission"]; + emailAttr = [entry attributeWithName:mailEmissionAttrName]; if (emailAttr == nil) return nil; /* shit happens */ - + email = nil; count = [emailAttr count]; -#if 0 +#if 0 // TODO: explain why this is commented out! if (count > 1) { unsigned i; @@ -622,21 +630,19 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; Sample: "(&(mineqMelPartages=guizmo.g:*)(objectclass=mineqMelBoite))" "guizmo.g" is the uid of the user - + Login: guizmo.g.-.baluh.hommes.tests-montee-en-charge-ogo (uid + ".-." + share-uid) - + Note: shared mailboxes can be on different hosts! */ - static NSString *shareLDAPClass = @"mineqMelBoite"; - static NSString *shareLoginSeparator = @".-."; NSMutableArray *shares = nil; NGLdapConnection *conn; - EOQualifier *q; - NSString *sharePattern; - NSEnumerator *resultEnum; - NGLdapEntry *entry; + EOQualifier *q; + NSString *sharePattern; + NSEnumerator *resultEnum; + NGLdapEntry *entry; if ([_uid length] == 0) return nil; @@ -646,6 +652,10 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; @"Note: LDAP access is disabled, returning no shared accounts."]; return nil; } + + /* check cache */ + if ((shares = [self->shareStoreCache objectForKey:_uid]) != nil) + return shares; sharePattern = [_uid stringByAppendingString:@":*"]; @@ -686,6 +696,80 @@ static NSString *defaultMailDomain = @"equipement.gouv.fr"; shareLogin = [shareLogin stringByAppendingString:server]; [shares addObject:shareLogin]; } + + /* ensure that ordering is always the same */ + [shares sortUsingSelector:@selector(compare:)]; + + /* cache */ + shares = (shares == nil) ? [NSArray array] : [[shares copy] autorelease]; + [self->shareStoreCache addObject:shares forKey:_uid]; + return shares; +} + +- (NSArray *)getSharedMailboxEMailsForUID:(NSString *)_uid { + NSMutableArray *shares = nil; + NGLdapConnection *conn; + EOQualifier *q; + NSString *gPattern, *cPattern; + NSEnumerator *resultEnum; + NGLdapEntry *entry; + + if ([_uid length] == 0) + return nil; + + if (!useLDAP) { + [self logWithFormat: + @"Note: LDAP access is disabled, returning no shared froms."]; + return nil; + } + + /* check cache */ + if ((shares = [self->shareEMailCache objectForKey:_uid]) != nil) + return shares; + + /* G and C mean "emission access" */ + gPattern = [_uid stringByAppendingString:@":G"]; + cPattern = [_uid stringByAppendingString:@":C"]; + + q = [EOQualifier qualifierWithQualifierFormat: + @"((mineqMelPartages = %@) OR (mineqMelPartages = %@)) " + @"AND (objectclass = %@)", + gPattern, cPattern, shareLDAPClass]; + + conn = [self ldapConnection]; + + resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN + qualifier:q + attributes:fromEMailAttrs]; + + while ((entry = [resultEnum nextObject]) != nil) { + id emissionAttr; + + emissionAttr = [entry attributeWithName:mailEmissionAttrName]; + if ([emissionAttr count] == 0) { + [self logWithFormat:@"WARNING: share has no %@ attr: %@", + mailEmissionAttrName, [entry dn]]; + continue; + } + + if ([emissionAttr count] > 1) { + [self logWithFormat: + @"WARNING: share has more than one value in %@ attr: %@", + mailEmissionAttrName, [entry dn]]; + continue; + } + + emissionAttr = [emissionAttr stringValueAtIndex:0]; + if (shares == nil) shares = [NSMutableArray arrayWithCapacity:4]; + [shares addObject:emissionAttr]; + } + + /* ensure that ordering is always the same */ + [shares sortUsingSelector:@selector(compare:)]; + + /* cache */ + shares = (shares == nil) ? [NSArray array] : [[shares copy] autorelease]; + [self->shareEMailCache addObject:shares forKey:_uid]; return shares; } diff --git a/SOGo/SoObjects/SOGo/ChangeLog b/SOGo/SoObjects/SOGo/ChangeLog index 0706bdcb..905da61d 100644 --- a/SOGo/SoObjects/SOGo/ChangeLog +++ b/SOGo/SoObjects/SOGo/ChangeLog @@ -1,3 +1,14 @@ +2005-07-08 Helge Hess + + * v0.9.42 + + * added agenor_emails4uid tool to check whether the + uid=>allowed-from-mails discovery in AgenorUserManager works + + * AgenorUserManager.m: added -getSharedMailboxEMailsForUID: method to + discover the shared emails the user is allowed to post from, + added caching of shared emails and Cyrus-logins + 2005-07-08 Helge Hess * WOContext+Agenor.m: use SOGoInternetDetectQualifier for detecting diff --git a/SOGo/SoObjects/SOGo/GNUmakefile b/SOGo/SoObjects/SOGo/GNUmakefile index e6b00c7c..c8659420 100644 --- a/SOGo/SoObjects/SOGo/GNUmakefile +++ b/SOGo/SoObjects/SOGo/GNUmakefile @@ -6,7 +6,7 @@ include $(GNUSTEP_MAKEFILES)/common.make -include ./Version LIBRARY_NAME = libSOGo -TOOL_NAME = agenor_email2uid agenor_shares4uid +TOOL_NAME = agenor_email2uid agenor_shares4uid agenor_emails4uid libSOGo_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) @@ -57,6 +57,11 @@ agenor_shares4uid_OBJC_FILES += \ AgenorUserManager.m \ SOGoLRUCache.m \ +agenor_emails4uid_OBJC_FILES += \ + agenor_emails4uid.m \ + AgenorUserManager.m \ + SOGoLRUCache.m \ + -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/library.make include $(GNUSTEP_MAKEFILES)/tool.make diff --git a/SOGo/SoObjects/SOGo/GNUmakefile.preamble b/SOGo/SoObjects/SOGo/GNUmakefile.preamble index 9ecfb265..59f2df93 100644 --- a/SOGo/SoObjects/SOGo/GNUmakefile.preamble +++ b/SOGo/SoObjects/SOGo/GNUmakefile.preamble @@ -26,3 +26,4 @@ libSOGo_LIBRARIES_DEPEND_UPON += \ agenor_email2uid_TOOL_LIBS += -lNGLdap agenor_shares4uid_TOOL_LIBS += -lNGLdap +agenor_emails4uid_TOOL_LIBS += -lNGLdap diff --git a/SOGo/SoObjects/SOGo/SOGoLRUCache.m b/SOGo/SoObjects/SOGo/SOGoLRUCache.m index dd11e77c..3233f771 100644 --- a/SOGo/SoObjects/SOGo/SOGoLRUCache.m +++ b/SOGo/SoObjects/SOGo/SOGoLRUCache.m @@ -77,16 +77,16 @@ - (void)addObject:(id)_obj forKey:(id)_key { SOGoLRUCacheItem *item; - + NSAssert(_obj, @"Attempt to insert nil object!"); - + if([self->entries count] >= self->size) { /* need to find minimum and get rid of it */ NSEnumerator *keyEnum; SOGoLRUCacheItem *item; id key, leastUsedItemKey; unsigned minimumUseCount = INT_MAX; - + keyEnum = [self->entries keyEnumerator]; while((key = [keyEnum nextObject])) { item = [self->entries objectForKey:key]; diff --git a/SOGo/SoObjects/SOGo/Version b/SOGo/SoObjects/SOGo/Version index a84cdcc5..d736dfc4 100644 --- a/SOGo/SoObjects/SOGo/Version +++ b/SOGo/SoObjects/SOGo/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=41 +SUBMINOR_VERSION:=42 # v0.9.34 requires libGDLContentStore v4.5.26 # v0.9.26 requires libOGoContentStore v0.9.13 diff --git a/SOGo/SoObjects/SOGo/agenor_emails4uid.m b/SOGo/SoObjects/SOGo/agenor_emails4uid.m new file mode 100644 index 00000000..42959dbc --- /dev/null +++ b/SOGo/SoObjects/SOGo/agenor_emails4uid.m @@ -0,0 +1,85 @@ +/* + Copyright (C) 2005 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include "AgenorUserManager.h" +#include "common.h" + +static void usage(NSArray *args) { + fprintf(stderr, "usage: %s \n", + [[args objectAtIndex:0] cString]); +} + +static void handleUID(NSString *uid, AgenorUserManager *userManager) { + NSArray *emails; + NSString *primary; + unsigned i, count; + + primary = [userManager getEmailForUID:uid]; + emails = [userManager getSharedMailboxEMailsForUID:uid]; + + printf("%s:", [uid cString]); + + if ([primary length] > 0) + printf(" %s\n", [primary cString]); + else + printf(" \n"); + + if ((count = [emails count]) == 0) { + printf(" \n"); + return; + } + + for (i = 0; i < count; i++) + printf(" %s\n", [[emails objectAtIndex:i] cString]); +} + +static void doIt(NSArray *args) { + AgenorUserManager *userManager; + NSEnumerator *e; + NSString *uid; + + if ([args count] < 2) { + usage(args); + return; + } + + userManager = [AgenorUserManager sharedUserManager]; + + e = [args objectEnumerator]; + [e nextObject]; /* consume the command name */ + + while ((uid = [e nextObject]) != nil) + handleUID(uid, userManager); +} + +int main(int argc, char **argv, char **env) { + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; +#if LIB_FOUNDATION_LIBRARY + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; +#endif + + doIt([[NSProcessInfo processInfo] argumentsWithoutDefaults]); + + [pool release]; + return 0; +} -- 2.39.5