mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-11 14:57:12 +00:00
Monotone-Parent: 38816d5f2c5865f939ccd8290226d22c43482e08
Monotone-Revision: 1960a36a480c2b580275d8352c65f53c16c80b5a Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-11-07T15:58:43 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
1 parent
7e3890af89
commit
b83e708b70
20 files changed
+173
-319
No files matched your search
@@ -0,0 +1,718 @@
|
||||
/*
|
||||
Copyright (C) 2004-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.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSKeyValueCoding.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/SoObject.h>
|
||||
#import <NGObjWeb/SoObject+SoDAV.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
#import <GDLContentStore/GCSChannelManager.h>
|
||||
#import <GDLContentStore/GCSFolderManager.h>
|
||||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <GDLContentStore/GCSFolderType.h>
|
||||
#import <GDLContentStore/NSURL+GCS.h>
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
#import <UI/SOGoUI/SOGoFolderAdvisory.h>
|
||||
|
||||
#import "NSArray+Utilities.h"
|
||||
#import "NSString+Utilities.h"
|
||||
|
||||
#import "SOGoContentObject.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "SOGoUser.h"
|
||||
|
||||
#import "SOGoGCSFolder.h"
|
||||
|
||||
static NSString *defaultUserID = @"<default>";
|
||||
|
||||
@implementation SOGoGCSFolder
|
||||
|
||||
+ (id) folderWithSubscriptionReference: (NSString *) reference
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
id newFolder;
|
||||
NSArray *elements, *pathElements;
|
||||
NSString *ocsPath, *objectPath, *owner, *ocsName, *folderName;
|
||||
|
||||
elements = [reference componentsSeparatedByString: @":"];
|
||||
owner = [elements objectAtIndex: 0];
|
||||
objectPath = [elements objectAtIndex: 1];
|
||||
pathElements = [objectPath componentsSeparatedByString: @"/"];
|
||||
if ([pathElements count] > 1)
|
||||
ocsName = [pathElements objectAtIndex: 1];
|
||||
else
|
||||
ocsName = @"personal";
|
||||
|
||||
ocsPath = [NSString stringWithFormat: @"/Users/%@/%@/%@",
|
||||
owner, [pathElements objectAtIndex: 0], ocsName];
|
||||
folderName = [NSString stringWithFormat: @"%@_%@", owner, ocsName];
|
||||
newFolder = [[self alloc] initWithName: folderName
|
||||
inContainer: aContainer];
|
||||
[newFolder setOCSPath: ocsPath];
|
||||
[newFolder setOwner: owner];
|
||||
|
||||
return newFolder;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
displayName = nil;
|
||||
ocsPath = nil;
|
||||
ocsFolder = nil;
|
||||
aclCache = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[ocsFolder release];
|
||||
[ocsPath release];
|
||||
[aclCache release];
|
||||
[displayName release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (void) _setDisplayNameFromRow: (NSDictionary *) row
|
||||
{
|
||||
NSString *currentLogin, *ownerLogin;
|
||||
NSDictionary *ownerIdentity;
|
||||
|
||||
displayName
|
||||
= [NSMutableString stringWithString: [row objectForKey: @"c_foldername"]];
|
||||
currentLogin = [[context activeUser] login];
|
||||
ownerLogin = [self ownerInContext: context];
|
||||
if (![currentLogin isEqualToString: ownerLogin])
|
||||
{
|
||||
ownerIdentity = [[SOGoUser userWithLogin: ownerLogin roles: nil]
|
||||
primaryIdentity];
|
||||
[displayName appendFormat: @" (%@ <%@>)",
|
||||
[ownerIdentity objectForKey: @"fullName"],
|
||||
[ownerIdentity objectForKey: @"email"]];
|
||||
}
|
||||
[displayName retain];
|
||||
}
|
||||
|
||||
- (void) _fetchDisplayName
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql;
|
||||
NSArray *attrs;
|
||||
NSDictionary *row;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"SELECT c_foldername FROM %@"
|
||||
@" WHERE c_path = '%@'"),
|
||||
[folderLocation gcsTableName], ocsPath];
|
||||
[fc evaluateExpressionX: sql];
|
||||
attrs = [fc describeResults: NO];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
if (row)
|
||||
[self _setDisplayNameFromRow: row];
|
||||
[fc cancelFetch];
|
||||
[cm releaseChannel: fc];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
if (!displayName)
|
||||
[self _fetchDisplayName];
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (void) setOCSPath: (NSString *) _path
|
||||
{
|
||||
if (![ocsPath isEqualToString:_path])
|
||||
{
|
||||
if (ocsPath)
|
||||
[self warnWithFormat: @"GCS path is already set! '%@'", _path];
|
||||
ASSIGN (ocsPath, _path);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) ocsPath
|
||||
{
|
||||
return ocsPath;
|
||||
}
|
||||
|
||||
- (GCSFolderManager *) folderManager
|
||||
{
|
||||
static GCSFolderManager *folderManager = nil;
|
||||
|
||||
if (!folderManager)
|
||||
folderManager = [GCSFolderManager defaultFolderManager];
|
||||
|
||||
return folderManager;
|
||||
}
|
||||
|
||||
- (GCSFolder *) ocsFolderForPath: (NSString *) _path
|
||||
{
|
||||
return [[self folderManager] folderAtPath: _path];
|
||||
}
|
||||
|
||||
- (BOOL) folderIsMandatory
|
||||
{
|
||||
return [nameInContainer isEqualToString: @"personal"];
|
||||
}
|
||||
|
||||
- (NSString *) davDisplayName
|
||||
{
|
||||
return [self displayName];
|
||||
}
|
||||
|
||||
- (GCSFolder *) ocsFolder
|
||||
{
|
||||
GCSFolder *folder;
|
||||
NSString *userLogin;
|
||||
|
||||
if (!ocsFolder)
|
||||
{
|
||||
ocsFolder = [self ocsFolderForPath: [self ocsPath]];
|
||||
userLogin = [[context activeUser] login];
|
||||
if (!ocsFolder
|
||||
&& [userLogin isEqualToString: [self ownerInContext: context]]
|
||||
&& [self folderIsMandatory]
|
||||
&& [self create])
|
||||
ocsFolder = [self ocsFolderForPath: [self ocsPath]];
|
||||
[ocsFolder retain];
|
||||
}
|
||||
|
||||
if ([ocsFolder isNotNull])
|
||||
folder = ocsFolder;
|
||||
else
|
||||
folder = nil;
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
- (void) sendFolderAdvisoryTemplate: (NSString *) template
|
||||
{
|
||||
NSString *pageName;
|
||||
SOGoUser *user;
|
||||
SOGoFolderAdvisory *page;
|
||||
|
||||
user = [context activeUser];
|
||||
pageName = [NSString stringWithFormat: @"SOGoFolder%@%@Advisory",
|
||||
[user language], template];
|
||||
|
||||
page = [[WOApplication application] pageWithName: pageName
|
||||
inContext: context];
|
||||
[page setFolderObject: self];
|
||||
[page setRecipientUID: [user login]];
|
||||
[page send];
|
||||
}
|
||||
|
||||
|
||||
// if (!result) [self sendFolderAdvisoryTemplate: @"Addition"];
|
||||
|
||||
- (BOOL) create
|
||||
{
|
||||
NSException *result;
|
||||
|
||||
result = [[self folderManager] createFolderOfType: [self folderType]
|
||||
withName: displayName
|
||||
atPath: ocsPath];
|
||||
|
||||
return (result == nil);
|
||||
}
|
||||
|
||||
- (NSException *) delete
|
||||
{
|
||||
NSException *error;
|
||||
|
||||
// We just fetch our displayName since our table will use it!
|
||||
[self displayName];
|
||||
|
||||
if ([nameInContainer isEqualToString: @"personal"])
|
||||
error = [NSException exceptionWithHTTPStatus: 403
|
||||
reason: @"folder 'personal' cannot be deleted"];
|
||||
else
|
||||
error = [[self folderManager] deleteFolderAtPath: ocsPath];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
// if (!error) [self sendFolderAdvisoryTemplate: @"Removal"];
|
||||
|
||||
- (void) renameTo: (NSString *) newName
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql;
|
||||
|
||||
[displayName release];
|
||||
displayName = nil;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"UPDATE %@ SET c_foldername = '%@'"
|
||||
@" WHERE c_path = '%@'"),
|
||||
[folderLocation gcsTableName], newName, ocsPath];
|
||||
[fc evaluateExpressionX: sql];
|
||||
[cm releaseChannel: fc];
|
||||
// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
|
||||
// uidColumnName, [self uid]];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContentObjectNames
|
||||
{
|
||||
NSArray *fields, *records;
|
||||
|
||||
fields = [NSArray arrayWithObject: @"c_name"];
|
||||
records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil];
|
||||
if (![records isNotNull])
|
||||
{
|
||||
[self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([records isKindOfClass: [NSException class]])
|
||||
return records;
|
||||
return [records objectsForKey: @"c_name"];
|
||||
}
|
||||
|
||||
- (BOOL) nameExistsInFolder: (NSString *) objectName
|
||||
{
|
||||
NSArray *fields, *records;
|
||||
EOQualifier *qualifier;
|
||||
|
||||
qualifier
|
||||
= [EOQualifier qualifierWithQualifierFormat:
|
||||
[NSString stringWithFormat: @"c_name='%@'", objectName]];
|
||||
|
||||
fields = [NSArray arrayWithObject: @"c_name"];
|
||||
records = [[self ocsFolder] fetchFields: fields
|
||||
matchingQualifier: qualifier];
|
||||
return (records
|
||||
&& ![records isKindOfClass:[NSException class]]
|
||||
&& [records count] > 0);
|
||||
}
|
||||
|
||||
- (void) deleteEntriesWithIds: (NSArray *) ids
|
||||
{
|
||||
unsigned int count, max;
|
||||
NSString *currentID;
|
||||
SOGoContentObject *deleteObject;
|
||||
|
||||
max = [ids count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentID = [ids objectAtIndex: count];
|
||||
deleteObject = [self lookupName: currentID
|
||||
inContext: context acquire: NO];
|
||||
if (![deleteObject isKindOfClass: [NSException class]])
|
||||
[deleteObject delete];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects
|
||||
{
|
||||
NSDictionary *files;
|
||||
|
||||
files = [[self ocsFolder] fetchContentsOfAllFiles];
|
||||
if (![files isNotNull])
|
||||
{
|
||||
[self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([files isKindOfClass:[NSException class]])
|
||||
return files;
|
||||
return files;
|
||||
}
|
||||
|
||||
/* reflection */
|
||||
|
||||
- (NSString *) defaultFilenameExtension
|
||||
{
|
||||
/*
|
||||
Override to add an extension to a filename
|
||||
|
||||
Note: be careful with that, needs to be consistent with object lookup!
|
||||
*/
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *) davResourceType
|
||||
{
|
||||
NSArray *rType, *groupDavCollection;
|
||||
|
||||
if ([self respondsToSelector: @selector (groupDavResourceType)])
|
||||
{
|
||||
groupDavCollection
|
||||
= [NSArray arrayWithObjects: [self groupDavResourceType],
|
||||
XMLNS_GROUPDAV, nil];
|
||||
rType = [NSArray arrayWithObjects: @"collection", groupDavCollection,
|
||||
nil];
|
||||
}
|
||||
else
|
||||
rType = [NSArray arrayWithObject: @"collection"];
|
||||
|
||||
return rType;
|
||||
}
|
||||
|
||||
- (NSArray *) toOneRelationshipKeys
|
||||
{
|
||||
/* toOneRelationshipKeys are the 'files' contained in a folder */
|
||||
NSMutableArray *ma;
|
||||
NSArray *names;
|
||||
NSString *name, *ext;
|
||||
unsigned i, count;
|
||||
NSRange r;
|
||||
|
||||
names = [self fetchContentObjectNames];
|
||||
count = [names count];
|
||||
ext = [self defaultFilenameExtension];
|
||||
if (count && [ext length] > 0)
|
||||
{
|
||||
ma = [NSMutableArray arrayWithCapacity: count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
name = [names objectAtIndex: i];
|
||||
r = [name rangeOfString: @"."];
|
||||
if (r.length == 0)
|
||||
name = [NSMutableString stringWithFormat: @"%@.%@", name, ext];
|
||||
[ma addObject: name];
|
||||
}
|
||||
|
||||
names = ma;
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
/* acls as a container */
|
||||
|
||||
- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
|
||||
{
|
||||
EOQualifier *qualifier;
|
||||
NSString *qs;
|
||||
NSArray *records;
|
||||
|
||||
qs = [NSString stringWithFormat: @"c_object = '/%@'",
|
||||
[objectPathArray componentsJoinedByString: @"/"]];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
|
||||
|
||||
return [records valueForKey: @"c_uid"];
|
||||
}
|
||||
|
||||
- (NSArray *) _fetchAclsForUser: (NSString *) uid
|
||||
forObjectAtPath: (NSString *) objectPath
|
||||
{
|
||||
EOQualifier *qualifier;
|
||||
NSArray *records;
|
||||
NSMutableArray *acls;
|
||||
NSString *qs;
|
||||
|
||||
qs = [NSString stringWithFormat: @"(c_object = '/%@') AND (c_uid = '%@')",
|
||||
objectPath, uid];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
|
||||
|
||||
acls = [NSMutableArray array];
|
||||
if ([records count] > 0)
|
||||
{
|
||||
[acls addObject: SOGoRole_AuthorizedSubscriber];
|
||||
[acls addObjectsFromArray: [records valueForKey: @"c_role"]];
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
- (void) _cacheRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
forObjectAtPath: (NSString *) objectPath
|
||||
{
|
||||
NSMutableDictionary *aclsForObject;
|
||||
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
if (!aclsForObject)
|
||||
{
|
||||
aclsForObject = [NSMutableDictionary dictionary];
|
||||
[aclCache setObject: aclsForObject
|
||||
forKey: objectPath];
|
||||
}
|
||||
if (roles)
|
||||
[aclsForObject setObject: roles forKey: uid];
|
||||
else
|
||||
[aclsForObject removeObjectForKey: uid];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
NSArray *acls;
|
||||
NSString *objectPath;
|
||||
NSDictionary *aclsForObject;
|
||||
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
if (aclsForObject)
|
||||
acls = [aclsForObject objectForKey: uid];
|
||||
else
|
||||
acls = nil;
|
||||
if (!acls)
|
||||
{
|
||||
acls = [self _fetchAclsForUser: uid forObjectAtPath: objectPath];
|
||||
[self _cacheRoles: acls forUser: uid forObjectAtPath: objectPath];
|
||||
}
|
||||
|
||||
if (!([acls count] || [uid isEqualToString: defaultUserID]))
|
||||
acls = [self aclsForUser: defaultUserID
|
||||
forObjectAtPath: objectPathArray];
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) users
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
EOQualifier *qualifier;
|
||||
NSString *uids, *qs, *objectPath;
|
||||
NSMutableDictionary *aclsForObject;
|
||||
|
||||
if ([users count] > 0)
|
||||
{
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aclsForObject = [aclCache objectForKey: objectPath];
|
||||
if (aclsForObject)
|
||||
[aclsForObject removeObjectsForKeys: users];
|
||||
uids = [users componentsJoinedByString: @"') OR (c_uid = '"];
|
||||
qs = [NSString
|
||||
stringWithFormat: @"(c_object = '/%@') AND ((c_uid = '%@'))",
|
||||
objectPath, uids];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
[[self ocsFolder] deleteAclMatchingQualifier: qualifier];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _commitRoles: (NSArray *) roles
|
||||
forUID: (NSString *) uid
|
||||
forObject: (NSString *) objectPath
|
||||
{
|
||||
EOAdaptorChannel *channel;
|
||||
GCSFolder *folder;
|
||||
NSEnumerator *userRoles;
|
||||
NSString *SQL, *currentRole;
|
||||
|
||||
folder = [self ocsFolder];
|
||||
channel = [folder acquireAclChannel];
|
||||
userRoles = [roles objectEnumerator];
|
||||
currentRole = [userRoles nextObject];
|
||||
while (currentRole)
|
||||
{
|
||||
SQL = [NSString stringWithFormat: @"INSERT INTO %@"
|
||||
@" (c_object, c_uid, c_role)"
|
||||
@" VALUES ('/%@', '%@', '%@')",
|
||||
[folder aclTableName],
|
||||
objectPath, uid, currentRole];
|
||||
[channel evaluateExpressionX: SQL];
|
||||
currentRole = [userRoles nextObject];
|
||||
}
|
||||
|
||||
[folder releaseChannel: channel];
|
||||
}
|
||||
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
NSString *objectPath;
|
||||
NSMutableArray *newRoles;
|
||||
|
||||
[self removeAclsForUsers: [NSArray arrayWithObject: uid]
|
||||
forObjectAtPath: objectPathArray];
|
||||
|
||||
newRoles = [NSMutableArray arrayWithArray: roles];
|
||||
[newRoles removeObject: SOGoRole_AuthorizedSubscriber];
|
||||
[newRoles removeObject: SOGoRole_None];
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
[self _cacheRoles: newRoles forUser: uid
|
||||
forObjectAtPath: objectPath];
|
||||
if (![newRoles count])
|
||||
[newRoles addObject: SOGoRole_None];
|
||||
|
||||
[self _commitRoles: newRoles forUID: uid forObject: objectPath];
|
||||
}
|
||||
|
||||
/* acls */
|
||||
- (NSArray *) aclUsers
|
||||
{
|
||||
return [self aclUsersForObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
NSMutableArray *acls;
|
||||
NSArray *ownAcls, *containerAcls;
|
||||
|
||||
acls = [NSMutableArray array];
|
||||
ownAcls = [self aclsForUser: uid
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
[acls addObjectsFromArray: ownAcls];
|
||||
if ([container respondsToSelector: @selector (aclsForUser:)])
|
||||
{
|
||||
containerAcls = [container aclsForUser: uid];
|
||||
if ([containerAcls count] > 0)
|
||||
{
|
||||
if ([containerAcls containsObject: SOGoRole_ObjectReader])
|
||||
[acls addObject: SOGoRole_ObjectViewer];
|
||||
#warning this should be checked
|
||||
if ([containerAcls containsObject: SOGoRole_ObjectEraser])
|
||||
[acls addObject: SOGoRole_ObjectEraser];
|
||||
}
|
||||
}
|
||||
|
||||
return acls;
|
||||
}
|
||||
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
return [self setRoles: roles
|
||||
forUser: uid
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) users
|
||||
{
|
||||
return [self removeAclsForUsers: users
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (NSString *) defaultUserID
|
||||
{
|
||||
return defaultUserID;
|
||||
}
|
||||
|
||||
- (NSComparisonResult) _compareByOrigin: (SOGoFolder *) otherFolder
|
||||
{
|
||||
NSArray *thisElements, *otherElements;
|
||||
unsigned thisCount, otherCount;
|
||||
NSComparisonResult comparison;
|
||||
|
||||
thisElements = [nameInContainer componentsSeparatedByString: @"_"];
|
||||
otherElements = [[otherFolder nameInContainer]
|
||||
componentsSeparatedByString: @"_"];
|
||||
thisCount = [thisElements count];
|
||||
otherCount = [otherElements count];
|
||||
if (thisCount == otherCount)
|
||||
{
|
||||
if (thisCount == 1)
|
||||
comparison = NSOrderedSame;
|
||||
else
|
||||
comparison = [[thisElements objectAtIndex: 0]
|
||||
compare: [otherElements objectAtIndex: 0]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thisCount > otherCount)
|
||||
comparison = NSOrderedDescending;
|
||||
else
|
||||
comparison = NSOrderedAscending;
|
||||
}
|
||||
|
||||
return comparison;
|
||||
}
|
||||
|
||||
- (NSComparisonResult) _compareByNameInContainer: (SOGoFolder *) otherFolder
|
||||
{
|
||||
NSString *otherName;
|
||||
NSComparisonResult comparison;
|
||||
|
||||
otherName = [otherFolder nameInContainer];
|
||||
if ([nameInContainer hasSuffix: @"personal"])
|
||||
{
|
||||
if ([otherName hasSuffix: @"personal"])
|
||||
comparison = [nameInContainer compare: otherName];
|
||||
else
|
||||
comparison = NSOrderedAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([otherName hasSuffix: @"personal"])
|
||||
comparison = NSOrderedDescending;
|
||||
else
|
||||
comparison = NSOrderedSame;
|
||||
}
|
||||
|
||||
return comparison;
|
||||
}
|
||||
|
||||
- (NSComparisonResult) compare: (SOGoGCSFolder *) otherFolder
|
||||
{
|
||||
NSComparisonResult comparison;
|
||||
|
||||
comparison = [self _compareByOrigin: otherFolder];
|
||||
if (comparison == NSOrderedSame)
|
||||
{
|
||||
comparison = [self _compareByNameInContainer: otherFolder];
|
||||
if (comparison == NSOrderedSame)
|
||||
comparison
|
||||
= [[self displayName]
|
||||
localizedCaseInsensitiveCompare: [otherFolder displayName]];
|
||||
}
|
||||
|
||||
return comparison;
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (void) appendAttributesToDescription: (NSMutableString *) _ms
|
||||
{
|
||||
[super appendAttributesToDescription:_ms];
|
||||
|
||||
[_ms appendFormat:@" ocs=%@", [self ocsPath]];
|
||||
}
|
||||
|
||||
@end /* SOGoFolder */
|
||||
Reference in new issue
Block a user