mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-08 01:45:08 +00:00
See ChangeLog
Monotone-Parent: 5bef03fdbb4e4f3112fabf6812f1a2e0932c85a9 Monotone-Revision: 785d7cb3b05b0317ec2ce52a1f17d6c130bf53fb Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2010-10-15T18:30:08 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2010-10-15 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoGCSFolder.m - remove the ACL cache
|
||||
and moved it to SOGoCache with memcached support. Also
|
||||
modified _setDisplayNameFromRow: to NOT use SOGoUser
|
||||
instances and it is _very costly_ to do so.
|
||||
* SoObjects/SOGo/SOGoCache.{h,m} - added support for
|
||||
caching ACLs locally and in memcached
|
||||
|
||||
2010-10-15 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreContext.m (-getPath:ofFMID:withTableType:):
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
- improved groups support by caching results
|
||||
- updated the Polish, Italian and Ukrainian translations
|
||||
- added the capability of renaming subscribed address books
|
||||
- acls are now cached in memcached and added a major performance
|
||||
improvement when listing calendar / contact folders
|
||||
|
||||
|
||||
1.3-20100921 (1.3.2)
|
||||
--------------------
|
||||
|
||||
@@ -103,6 +103,11 @@
|
||||
- (void) setCASPGTId: (NSString *) pgtId
|
||||
forPGTIOU: (NSString *) pgtIou;
|
||||
|
||||
- (void) setACLs: (NSDictionary *) theACLs
|
||||
forPath: (NSString *) thePath;
|
||||
|
||||
- (NSMutableDictionary *) aclsForPath: (NSString *) thePath;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SOGOCACHE_H */
|
||||
|
||||
+69
-16
@@ -25,9 +25,16 @@
|
||||
* [ Cache Structure ]
|
||||
*
|
||||
* users value = instances of SOGoUser > flushed after the completion of every SOGo requests
|
||||
* groups value = instances of SOGoGroup > flushed after the completion of every SOGo requests
|
||||
* imap4Connections value =
|
||||
* localCache value = any value of what's in memcached - this is used to NOT query memcached within the same sogod instance
|
||||
*
|
||||
* [ Distributed (using memcached) cache structure ]
|
||||
*
|
||||
* <uid>+defaults value = NSDictionary instance > user's defaults
|
||||
* <uid>+settings value = NSDictionary instance > user's settings
|
||||
* <uid>+attributes value = NSMutableDictionary instance > user's LDAP attributes
|
||||
* <object path>+acl value = NSDictionary instance > ACLs on an object at specified path
|
||||
* <groupname>+<domain> value = NSString instance (array components separated by ",") or group member logins for a specific group in domain
|
||||
*/
|
||||
|
||||
@@ -41,6 +48,7 @@
|
||||
#import <NGObjWeb/SoObject.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "NSDictionary+BSJSONAdditions.h"
|
||||
#import "SOGoObject.h"
|
||||
#import "SOGoSystemDefaults.h"
|
||||
#import "SOGoUser.h"
|
||||
@@ -262,10 +270,10 @@ static memcached_st *handle = NULL;
|
||||
{
|
||||
keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
|
||||
valueData = [value dataUsingEncoding: NSUTF8StringEncoding];
|
||||
error = memcached_set (handle,
|
||||
[keyData bytes], [keyData length],
|
||||
[valueData bytes], [valueData length],
|
||||
expiration, 0);
|
||||
error = memcached_set(handle,
|
||||
[keyData bytes], [keyData length],
|
||||
[valueData bytes], [valueData length],
|
||||
expiration, 0);
|
||||
if (error != MEMCACHED_SUCCESS)
|
||||
[self logWithFormat:
|
||||
@"an error occurred when caching value for key '%@':"
|
||||
@@ -327,6 +335,8 @@ static memcached_st *handle = NULL;
|
||||
NSData *keyData;
|
||||
memcached_return rc;
|
||||
|
||||
[localCache removeObjectForKey: key];
|
||||
|
||||
if (handle)
|
||||
{
|
||||
keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
|
||||
@@ -343,25 +353,39 @@ static memcached_st *handle = NULL;
|
||||
key];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This method is used to cache a specific value (represented as a
|
||||
// string, usually JSON stuff) using the specified key and type-suffix
|
||||
//
|
||||
// The final key will aways be of the form: <key>+<type suffix>
|
||||
//
|
||||
// This method will insert the value in the localCache and also
|
||||
// in memcached.
|
||||
//
|
||||
- (void) _cacheValues: (NSString *) theAttributes
|
||||
ofType: (NSString *) theType
|
||||
forLogin: (NSString *) theLogin
|
||||
forKey: (NSString *) theKey
|
||||
{
|
||||
NSString *keyName;
|
||||
|
||||
keyName = [NSString stringWithFormat: @"%@+%@", theLogin, theType];
|
||||
[self setValue: theAttributes forKey: keyName];
|
||||
[localCache setObject: theAttributes forKey: keyName];
|
||||
keyName = [NSString stringWithFormat: @"%@+%@", theKey, theType];
|
||||
|
||||
if (theAttributes)
|
||||
{
|
||||
[self setValue: theAttributes forKey: keyName];
|
||||
[localCache setObject: theAttributes forKey: keyName];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) _valuesOfType: (NSString *) theType
|
||||
forLogin: (NSString *) theLogin
|
||||
forKey: (NSString *) theKey
|
||||
{
|
||||
NSString *valueString, *keyName;
|
||||
|
||||
valueString = nil;
|
||||
|
||||
keyName = [NSString stringWithFormat: @"%@+%@", theLogin, theType];
|
||||
keyName = [NSString stringWithFormat: @"%@+%@", theKey, theType];
|
||||
valueString = [localCache objectForKey: keyName];
|
||||
if (!valueString)
|
||||
{
|
||||
@@ -377,36 +401,36 @@ static memcached_st *handle = NULL;
|
||||
forLogin: (NSString *) login
|
||||
{
|
||||
[self _cacheValues: theAttributes ofType: @"attributes"
|
||||
forLogin: login];
|
||||
forKey: login];
|
||||
}
|
||||
|
||||
- (NSString *) userAttributesForLogin: (NSString *) theLogin
|
||||
{
|
||||
return [self _valuesOfType: @"attributes" forLogin: theLogin];
|
||||
return [self _valuesOfType: @"attributes" forKey: theLogin];
|
||||
}
|
||||
|
||||
- (void) setUserDefaults: (NSString *) theAttributes
|
||||
forLogin: (NSString *) login
|
||||
{
|
||||
[self _cacheValues: theAttributes ofType: @"defaults"
|
||||
forLogin: login];
|
||||
forKey: login];
|
||||
}
|
||||
|
||||
- (NSString *) userDefaultsForLogin: (NSString *) theLogin
|
||||
{
|
||||
return [self _valuesOfType: @"defaults" forLogin: theLogin];
|
||||
return [self _valuesOfType: @"defaults" forKey: theLogin];
|
||||
}
|
||||
|
||||
- (void) setUserSettings: (NSString *) theAttributes
|
||||
forLogin: (NSString *) login
|
||||
{
|
||||
[self _cacheValues: theAttributes ofType: @"settings"
|
||||
forLogin: login];
|
||||
forKey: login];
|
||||
}
|
||||
|
||||
- (NSString *) userSettingsForLogin: (NSString *) theLogin
|
||||
{
|
||||
return [self _valuesOfType: @"settings" forLogin: theLogin];
|
||||
return [self _valuesOfType: @"settings" forKey: theLogin];
|
||||
}
|
||||
|
||||
/* CAS session support */
|
||||
@@ -452,4 +476,33 @@ static memcached_st *handle = NULL;
|
||||
forKey: [NSString stringWithFormat: @"cas-pgtiou:%@", pgtIou]];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) setACLs: (NSDictionary *) theACLs
|
||||
forPath: (NSString *) thePath
|
||||
{
|
||||
NSLog(@"setting ACLs: %@ (%@) forPath: %@", [theACLs jsonStringValue], theACLs, thePath);
|
||||
if (theACLs)
|
||||
[self _cacheValues: [theACLs jsonStringValue]
|
||||
ofType: @"acl"
|
||||
forKey: thePath];
|
||||
else
|
||||
[self removeValueForKey: [NSString stringWithFormat: @"%@+acl", thePath]];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) aclsForPath: (NSString *) thePath
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [self _valuesOfType: @"acl" forKey: thePath];
|
||||
|
||||
if (s)
|
||||
return [NSMutableDictionary dictionaryWithJSONString: s];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
Copyright (C) 2006-2010 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
This file is part of SOGo.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
SOGo 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
|
||||
SOGo 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.
|
||||
@@ -50,7 +51,6 @@
|
||||
NSString *ocsPath;
|
||||
GCSFolder *ocsFolder;
|
||||
NSMutableDictionary *childRecords;
|
||||
NSMutableDictionary *aclCache;
|
||||
BOOL userCanAccessAllObjects; /* i.e. user obtains 'Access Object' on
|
||||
subobjects */
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#import "SOGoUser.h"
|
||||
#import "SOGoUserDefaults.h"
|
||||
#import "SOGoUserSettings.h"
|
||||
#import "SOGoUserManager.h"
|
||||
#import "SOGoWebDAVAclManager.h"
|
||||
#import "WORequest+SOGo.h"
|
||||
#import "WOResponse+SOGo.h"
|
||||
@@ -198,7 +199,6 @@ static NSArray *childRecordFields = nil;
|
||||
{
|
||||
ocsPath = nil;
|
||||
ocsFolder = nil;
|
||||
aclCache = [NSMutableDictionary new];
|
||||
childRecords = [NSMutableDictionary new];
|
||||
userCanAccessAllObjects = NO;
|
||||
}
|
||||
@@ -210,7 +210,6 @@ static NSArray *childRecordFields = nil;
|
||||
{
|
||||
[ocsFolder release];
|
||||
[ocsPath release];
|
||||
[aclCache release];
|
||||
[childRecords release];
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -286,11 +285,14 @@ static NSArray *childRecordFields = nil;
|
||||
|
||||
if (!activeUserIsOwner)
|
||||
{
|
||||
ownerIdentity = [[SOGoUser userWithLogin: owner]
|
||||
primaryIdentity];
|
||||
[displayName
|
||||
appendString: [ownerIdentity keysWithFormat:
|
||||
@" (%{fullName} <%{email}>)"]];
|
||||
// We MUST NOT use SOGoUser instances here (by calling -primaryIdentity)
|
||||
// as it'll load user defaults and user settings which is _very costly_
|
||||
// since it involves JSON parsing and database requests
|
||||
ownerIdentity = [[SOGoUserManager sharedUserManager]
|
||||
contactInfosForUserWithUIDorEmail: owner];
|
||||
|
||||
[displayName appendFormat: @" (%@ <%@>)", [ownerIdentity objectForKey: @"cn"],
|
||||
[ownerIdentity objectForKey: @"c_email"]];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1480,17 +1482,23 @@ static NSArray *childRecordFields = nil;
|
||||
{
|
||||
NSMutableDictionary *aclsForObject;
|
||||
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
aclsForObject = [[SOGoCache sharedCache] aclsForPath: objectPath];
|
||||
if (!aclsForObject)
|
||||
{
|
||||
aclsForObject = [NSMutableDictionary dictionary];
|
||||
[aclCache setObject: aclsForObject
|
||||
forKey: objectPath];
|
||||
}
|
||||
if (roles)
|
||||
[aclsForObject setObject: roles forKey: uid];
|
||||
{
|
||||
[aclsForObject setObject: roles forKey: uid];
|
||||
}
|
||||
else
|
||||
[aclsForObject removeObjectForKey: uid];
|
||||
{
|
||||
[aclsForObject removeObjectForKey: uid];
|
||||
}
|
||||
|
||||
// We update our distributed cache
|
||||
[[SOGoCache sharedCache] setACLs: aclsForObject
|
||||
forPath: objectPath];
|
||||
}
|
||||
|
||||
- (NSArray *) _realAclsForUser: (NSString *) uid
|
||||
@@ -1501,7 +1509,7 @@ static NSArray *childRecordFields = nil;
|
||||
NSDictionary *aclsForObject;
|
||||
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
aclsForObject = [[SOGoCache sharedCache] aclsForPath: objectPath];
|
||||
if (aclsForObject)
|
||||
acls = [aclsForObject objectForKey: uid];
|
||||
else
|
||||
@@ -1571,9 +1579,13 @@ static NSArray *childRecordFields = nil;
|
||||
}
|
||||
}
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
aclsForObject = [[SOGoCache sharedCache] aclsForPath: objectPath];
|
||||
if (aclsForObject)
|
||||
[aclsForObject removeObjectsForKeys: usersAndGroups];
|
||||
{
|
||||
[aclsForObject removeObjectsForKeys: usersAndGroups];
|
||||
[[SOGoCache sharedCache] setACLs: aclsForObject
|
||||
forPath: objectPath];
|
||||
}
|
||||
uids = [usersAndGroups componentsJoinedByString: @"') OR (c_uid = '"];
|
||||
qs = [NSString
|
||||
stringWithFormat: @"(c_object = '/%@') AND ((c_uid = '%@'))",
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
NSArray *allEmails;
|
||||
NSMutableArray *mailAccounts;
|
||||
NSString *cn;
|
||||
BOOL propagateCache;
|
||||
}
|
||||
|
||||
// + (NSString *) language;
|
||||
|
||||
Reference in New Issue
Block a user