mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-22 05:19:28 +00:00
Monotone-Parent: c85cb655e68544b7193dc65e0c1dd577f63454c7
Monotone-Revision: bb3480fceb6cb5272d17ac7b9d0999cd0706581b Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-06-01T18:12:01 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
18
ChangeLog
18
ChangeLog
@@ -1,5 +1,23 @@
|
||||
2010-06-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-_privacySqlString): renamed to the new standardized
|
||||
"aclSQLListingFilter". Again, a difference is now made between
|
||||
empty and nil return strings, which we now apply here too.
|
||||
(-bareFetchFields:from:to:title:component:additionalFilters:,
|
||||
(-fetchFields:from:to:title:component:additionalFilters:includeProtectedInformation:):
|
||||
make use of the new semantics to the above method.
|
||||
|
||||
* SoObjects/SOGo/SOGoGCSFolder.m (-aclSQLListingFilter): new
|
||||
overridable method designed to return a filter to SQL queries that
|
||||
avoids requesting records that are not meant to be visible to the
|
||||
active user. Replaces and extends -[SOGoAppointmentFolder
|
||||
_privacySqlString] with the additional convention that returning a
|
||||
nil string will prevent any query at all.
|
||||
(-toOneRelationshipKeys): new overriden method (see below). Make
|
||||
use of the new aclSQLListingFilter method to retrieve records so
|
||||
that unaccessible records are not even listed.
|
||||
|
||||
* SoObjects/SOGo/SOGoFolder.m (-fetchContentObjectNames): removed
|
||||
this useless alias to "toOneRelationshipKeys".
|
||||
|
||||
|
||||
@@ -444,70 +444,41 @@ static NSNumber *sharedYes = nil;
|
||||
end, start];
|
||||
}
|
||||
|
||||
- (NSString *) _privacyClassificationStringsForUID: (NSString *) uid
|
||||
- (NSString *) aclSQLListingFilter
|
||||
{
|
||||
NSMutableString *classificationString;
|
||||
NSString *currentRole;
|
||||
unsigned int counter;
|
||||
iCalAccessClass classes[] = {iCalAccessPublic, iCalAccessPrivate,
|
||||
iCalAccessConfidential};
|
||||
|
||||
classificationString = [NSMutableString string];
|
||||
for (counter = 0; counter < 3; counter++)
|
||||
{
|
||||
currentRole = [self roleForComponentsWithAccessClass: classes[counter]
|
||||
forUser: uid];
|
||||
if ([currentRole length] > 0)
|
||||
[classificationString appendFormat: @"c_classification = %d or ",
|
||||
classes[counter]];
|
||||
}
|
||||
|
||||
return classificationString;
|
||||
}
|
||||
|
||||
- (NSString *) _privacySqlString
|
||||
{
|
||||
NSString *privacySqlString, *login;
|
||||
NSString *filter;
|
||||
NSMutableArray *grantedClasses, *deniedClasses;
|
||||
NSNumber *classNumber;
|
||||
unsigned int grantedCount;
|
||||
iCalAccessClass currentClass;
|
||||
|
||||
login = [[context activeUser] login];
|
||||
if ([login isEqualToString: @"freebusy"])
|
||||
privacySqlString = @"c_isopaque = 1";
|
||||
else
|
||||
[self initializeQuickTablesAclsInContext: context];
|
||||
grantedClasses = [NSMutableArray arrayWithCapacity: 3];
|
||||
deniedClasses = [NSMutableArray arrayWithCapacity: 3];
|
||||
for (currentClass = 0;
|
||||
currentClass < iCalAccessClassCount; currentClass++)
|
||||
{
|
||||
[self initializeQuickTablesAclsInContext: context];
|
||||
grantedClasses = [NSMutableArray arrayWithCapacity: 3];
|
||||
deniedClasses = [NSMutableArray arrayWithCapacity: 3];
|
||||
for (currentClass = 0;
|
||||
currentClass < iCalAccessClassCount; currentClass++)
|
||||
{
|
||||
classNumber = [NSNumber numberWithInt: currentClass];
|
||||
if (userCanAccessObjectsClassifiedAs[currentClass])
|
||||
[grantedClasses addObject: classNumber];
|
||||
else
|
||||
[deniedClasses addObject: classNumber];
|
||||
}
|
||||
grantedCount = [grantedClasses count];
|
||||
if (grantedCount == 3)
|
||||
privacySqlString = @"";
|
||||
else if (grantedCount == 2)
|
||||
privacySqlString
|
||||
= [NSString stringWithFormat: @"c_classification != %@",
|
||||
[deniedClasses objectAtIndex: 0]];
|
||||
else if (grantedCount == 1)
|
||||
privacySqlString
|
||||
= [NSString stringWithFormat: @"c_classification = %@",
|
||||
[grantedClasses objectAtIndex: 0]];
|
||||
classNumber = [NSNumber numberWithInt: currentClass];
|
||||
if (userCanAccessObjectsClassifiedAs[currentClass])
|
||||
[grantedClasses addObject: classNumber];
|
||||
else
|
||||
/* We prevent any event/task from being listed. There must be a better
|
||||
way... */
|
||||
privacySqlString = @"c_classification = 255";
|
||||
[deniedClasses addObject: classNumber];
|
||||
}
|
||||
grantedCount = [grantedClasses count];
|
||||
if (grantedCount == 3)
|
||||
filter = @"";
|
||||
else if (grantedCount == 2)
|
||||
filter
|
||||
= [NSString stringWithFormat: @"c_classification != %@",
|
||||
[deniedClasses objectAtIndex: 0]];
|
||||
else if (grantedCount == 1)
|
||||
filter
|
||||
= [NSString stringWithFormat: @"c_classification = %@",
|
||||
[grantedClasses objectAtIndex: 0]];
|
||||
else
|
||||
filter = nil;
|
||||
|
||||
return privacySqlString;
|
||||
return filter;
|
||||
}
|
||||
|
||||
- (NSArray *) bareFetchFields: (NSArray *) fields
|
||||
@@ -520,8 +491,9 @@ static NSNumber *sharedYes = nil;
|
||||
EOQualifier *qualifier;
|
||||
GCSFolder *folder;
|
||||
NSString *sql, *dateSqlString, *titleSqlString, *componentSqlString,
|
||||
*privacySqlString;
|
||||
*privacySQLString;
|
||||
NSMutableString *filterSqlString;
|
||||
NSArray *records;
|
||||
|
||||
folder = [self ocsFolder];
|
||||
if (startDate && endDate)
|
||||
@@ -544,25 +516,32 @@ static NSNumber *sharedYes = nil;
|
||||
if ([filters length])
|
||||
[filterSqlString appendFormat: @"AND (%@)", filters];
|
||||
|
||||
privacySqlString = [self _privacySqlString];
|
||||
if ([privacySqlString length])
|
||||
[filterSqlString appendFormat: @"AND (%@)", privacySqlString];
|
||||
privacySQLString = [self aclSQLListingFilter];
|
||||
if (privacySQLString)
|
||||
{
|
||||
if ([privacySQLString length])
|
||||
[filterSqlString appendFormat: @"AND (%@)", privacySQLString];
|
||||
|
||||
/* prepare mandatory fields */
|
||||
/* prepare mandatory fields */
|
||||
|
||||
sql = [NSString stringWithFormat: @"%@%@%@%@",
|
||||
dateSqlString, titleSqlString, componentSqlString,
|
||||
filterSqlString];
|
||||
/* sql is empty when we fetch everything (all parameters are nil) */
|
||||
if ([sql length] > 0)
|
||||
sql = [sql substringFromIndex: 4];
|
||||
sql = [NSString stringWithFormat: @"%@%@%@%@",
|
||||
dateSqlString, titleSqlString, componentSqlString,
|
||||
filterSqlString];
|
||||
/* sql is empty when we fetch everything (all parameters are nil) */
|
||||
if ([sql length] > 0)
|
||||
sql = [sql substringFromIndex: 4];
|
||||
else
|
||||
sql = nil;
|
||||
|
||||
/* fetch non-recurrent apts first */
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
|
||||
|
||||
records = [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
}
|
||||
else
|
||||
sql = nil;
|
||||
|
||||
/* fetch non-recurrent apts first */
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
|
||||
records = [NSArray array];
|
||||
|
||||
return [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
return records;
|
||||
}
|
||||
|
||||
- (BOOL) _checkIfWeCanRememberRecords: (NSArray *) fields
|
||||
@@ -965,7 +944,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
NSMutableArray *fields, *ma;
|
||||
NSArray *records;
|
||||
NSMutableString *baseWhere;
|
||||
NSString *where, *dateSqlString, *privacySqlString, *currentLogin;
|
||||
NSString *where, *dateSqlString, *privacySQLString, *currentLogin;
|
||||
NSCalendarDate *endDate;
|
||||
NGCalendarDateRange *r;
|
||||
BOOL rememberRecords, canCycle;
|
||||
@@ -1005,76 +984,83 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
dateSqlString = @"";
|
||||
}
|
||||
|
||||
privacySqlString = [self _privacySqlString];
|
||||
if ([privacySqlString length])
|
||||
[baseWhere appendFormat: @"AND %@", privacySqlString];
|
||||
|
||||
if ([title length])
|
||||
[baseWhere appendFormat: @"AND c_title isCaseInsensitiveLike: '%%%@%%'",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]];
|
||||
|
||||
if ([filters length])
|
||||
[baseWhere appendFormat: @"AND (%@)", filters];
|
||||
|
||||
/* prepare mandatory fields */
|
||||
|
||||
fields = [NSMutableArray arrayWithArray: _fields];
|
||||
[fields addObjectUniquely: @"c_name"];
|
||||
[fields addObjectUniquely: @"c_uid"];
|
||||
[fields addObjectUniquely: @"c_startdate"];
|
||||
[fields addObjectUniquely: @"c_enddate"];
|
||||
[fields addObjectUniquely: @"c_isallday"];
|
||||
|
||||
if (canCycle)
|
||||
where = [NSString stringWithFormat: @"%@ %@ AND c_iscycle = 0",
|
||||
baseWhere, dateSqlString];
|
||||
else
|
||||
where = baseWhere;
|
||||
|
||||
/* fetch non-recurrent apts first */
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
||||
[where substringFromIndex: 4]];
|
||||
records = [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
if (records)
|
||||
privacySQLString = [self aclSQLListingFilter];
|
||||
if (privacySQLString)
|
||||
{
|
||||
if (r)
|
||||
records = [self fixupRecords: records];
|
||||
ma = [NSMutableArray arrayWithArray: records];
|
||||
}
|
||||
else
|
||||
ma = nil;
|
||||
if ([privacySQLString length])
|
||||
[baseWhere appendFormat: @"AND %@", privacySQLString];
|
||||
|
||||
/* fetch recurrent apts now. we do NOT consider events with no cycle end. */
|
||||
// || _endDate || filters)
|
||||
if (canCycle && _endDate)
|
||||
{
|
||||
where = [NSString stringWithFormat: @"%@ AND c_iscycle = 1", baseWhere];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: [where substringFromIndex: 4]];
|
||||
if ([title length])
|
||||
[baseWhere
|
||||
appendFormat: @"AND c_title isCaseInsensitiveLike: '%%%@%%'",
|
||||
[title stringByReplacingString: @"'" withString: @"\\'\\'"]];
|
||||
|
||||
if ([filters length])
|
||||
[baseWhere appendFormat: @"AND (%@)", filters];
|
||||
|
||||
/* prepare mandatory fields */
|
||||
|
||||
fields = [NSMutableArray arrayWithArray: _fields];
|
||||
[fields addObjectUniquely: @"c_name"];
|
||||
[fields addObjectUniquely: @"c_uid"];
|
||||
[fields addObjectUniquely: @"c_startdate"];
|
||||
[fields addObjectUniquely: @"c_enddate"];
|
||||
[fields addObjectUniquely: @"c_isallday"];
|
||||
|
||||
if (canCycle)
|
||||
where = [NSString stringWithFormat: @"%@ %@ AND c_iscycle = 0",
|
||||
baseWhere, dateSqlString];
|
||||
else
|
||||
where = baseWhere;
|
||||
|
||||
/* fetch non-recurrent apts first */
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
||||
[where substringFromIndex: 4]];
|
||||
records = [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
if (records)
|
||||
{
|
||||
if (r)
|
||||
records = [self _flattenCycleRecords: records fetchRange: r];
|
||||
if (ma)
|
||||
[ma addObjectsFromArray: records];
|
||||
else
|
||||
ma = [NSMutableArray arrayWithArray: records];
|
||||
records = [self fixupRecords: records];
|
||||
ma = [NSMutableArray arrayWithArray: records];
|
||||
}
|
||||
}
|
||||
if (!ma)
|
||||
{
|
||||
[self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
ma = nil;
|
||||
|
||||
currentLogin = [[context activeUser] login];
|
||||
if (![currentLogin isEqualToString: owner] && !_includeProtectedInformation)
|
||||
[self _fixupProtectedInformation: [ma objectEnumerator]
|
||||
inFields: _fields
|
||||
forUser: currentLogin];
|
||||
/* fetch recurrent apts now. we do NOT consider events with no cycle
|
||||
end. */
|
||||
if (canCycle && _endDate)
|
||||
{
|
||||
where = [NSString stringWithFormat: @"%@ AND c_iscycle = 1", baseWhere];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: [where substringFromIndex: 4]];
|
||||
records = [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
if (records)
|
||||
{
|
||||
if (r)
|
||||
records = [self _flattenCycleRecords: records fetchRange: r];
|
||||
if (ma)
|
||||
[ma addObjectsFromArray: records];
|
||||
else
|
||||
ma = [NSMutableArray arrayWithArray: records];
|
||||
}
|
||||
}
|
||||
if (!ma)
|
||||
{
|
||||
[self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (rememberRecords)
|
||||
[self _rememberRecords: ma];
|
||||
currentLogin = [[context activeUser] login];
|
||||
if (![currentLogin isEqualToString: owner]
|
||||
&& !_includeProtectedInformation)
|
||||
[self _fixupProtectedInformation: [ma objectEnumerator]
|
||||
inFields: _fields
|
||||
forUser: currentLogin];
|
||||
|
||||
if (rememberRecords)
|
||||
[self _rememberRecords: ma];
|
||||
}
|
||||
else
|
||||
ma = [NSMutableArray array];
|
||||
|
||||
return ma;
|
||||
}
|
||||
|
||||
@@ -85,8 +85,6 @@
|
||||
- (id) createChildComponentWithName: (NSString *) newName
|
||||
andContent: (NSString *) newContent;
|
||||
|
||||
- (NSArray *) fetchContentObjectNames;
|
||||
|
||||
/* folder type */
|
||||
|
||||
- (BOOL) folderIsMandatory;
|
||||
|
||||
@@ -550,24 +550,63 @@ static NSArray *childRecordFields = nil;
|
||||
[self _subscriberRenameTo: newName];
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContentObjectNames
|
||||
- (NSString *) aclSQLListingFilter
|
||||
{
|
||||
NSString *filter, *login;
|
||||
NSArray *roles;
|
||||
|
||||
login = [[context activeUser] login];
|
||||
if (activeUserIsOwner
|
||||
|| [[self ownerInContext: nil] isEqualToString: login])
|
||||
filter = @"";
|
||||
else
|
||||
{
|
||||
roles = [self aclsForUser: login];
|
||||
if ([roles containsObject: SOGoRole_ObjectViewer]
|
||||
|| [roles containsObject: SOGoRole_ObjectEditor])
|
||||
filter = @"";
|
||||
else
|
||||
filter = nil;
|
||||
}
|
||||
|
||||
/* An empty string indicates that the filter is empty while a return value
|
||||
of nil indicates that the query should not even be performed. */
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
- (NSArray *) toOneRelationshipKeys
|
||||
{
|
||||
NSArray *records, *names;
|
||||
|
||||
records = [[self ocsFolder] fetchFields: childRecordFields
|
||||
matchingQualifier:nil];
|
||||
if (![records isNotNull])
|
||||
{
|
||||
[self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([records isKindOfClass: [NSException class]])
|
||||
return records;
|
||||
NSString *sqlFilter;
|
||||
EOQualifier *qualifier;
|
||||
|
||||
[childRecords release];
|
||||
names = [records objectsForKey: @"c_name" notFoundMarker: nil];
|
||||
childRecords = [[NSMutableDictionary alloc] initWithObjects: records
|
||||
forKeys: names];
|
||||
sqlFilter = [self aclSQLListingFilter];
|
||||
if (sqlFilter)
|
||||
{
|
||||
if ([sqlFilter length] > 0)
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: sqlFilter];
|
||||
else
|
||||
qualifier = nil;
|
||||
|
||||
records = [[self ocsFolder] fetchFields: childRecordFields
|
||||
matchingQualifier: qualifier];
|
||||
if (![records isNotNull])
|
||||
{
|
||||
[self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([records isKindOfClass: [NSException class]])
|
||||
return records;
|
||||
|
||||
names = [records objectsForKey: @"c_name" notFoundMarker: nil];
|
||||
|
||||
[childRecords release];
|
||||
childRecords = [[NSMutableDictionary alloc] initWithObjects: records
|
||||
forKeys: names];
|
||||
}
|
||||
else
|
||||
names = [NSArray array];
|
||||
|
||||
return names;
|
||||
}
|
||||
@@ -1472,6 +1511,9 @@ static NSArray *childRecordFields = nil;
|
||||
forObjectAtPath: objectPathArray];
|
||||
|
||||
newRoles = [NSMutableArray arrayWithArray: roles];
|
||||
[newRoles removeObject: SoRole_Authenticated];
|
||||
[newRoles removeObject: SoRole_Anonymous];
|
||||
[newRoles removeObject: SOGoRole_PublicUser];
|
||||
[newRoles removeObject: SOGoRole_AuthorizedSubscriber];
|
||||
[newRoles removeObject: SOGoRole_None];
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
|
||||
Reference in New Issue
Block a user