ModulesConstraints and listRequiresDot for SQL
SQL sources used for authentication can now have module constraints. Entries of SQL sources used as address books can now be displayed automatically.pull/218/merge
parent
08ec68c07c
commit
a2129f3e4a
|
@ -1612,7 +1612,7 @@ SQL source:
|
|||
|
||||
[cols="3,47a,50"]
|
||||
|=======================================================================
|
||||
.18+^|D |SOGoUserSources
|
||||
.20+^|D |SOGoUserSources
|
||||
|Parameter used to set the SQL and/or LDAP sources used for
|
||||
authentication and global address books. Multiple sources can be
|
||||
specified as an array of dictionaries. A dictionary that defines a SQL
|
||||
|
@ -1719,6 +1719,23 @@ to the user.
|
|||
|
||||
See the _Multi-domains Configuration_ section in this document for more
|
||||
information.
|
||||
|
||||
|listRequiresDot (optional)
|
||||
|If set to `YES`, listing of this SQL source is only possible when performing a search (respecting the SOGoSearchMinimumWordLength parameter) or when explicitely typing a single dot.
|
||||
Defaults to `YES` when unset.
|
||||
|
||||
|ModulesConstraints (optional)
|
||||
|Limits the access of any module through a constraint based on a SQL
|
||||
column; must be a dictionary with keys `Mail`, and/or `Calendar`,
|
||||
and/or `ActiveSync` for example:
|
||||
|
||||
----
|
||||
ModulesConstraints = {
|
||||
Calendar = {
|
||||
c_ou = employees;
|
||||
};
|
||||
};
|
||||
----
|
||||
|=======================================================================
|
||||
|
||||
Here is an example of an SQL-based authentication and address book
|
||||
|
|
2
NEWS
2
NEWS
|
@ -3,6 +3,8 @@
|
|||
|
||||
New features
|
||||
- [core] can now invite attendees to exceptions only (#2561)
|
||||
- [core] add support for module constraints in SQL sources
|
||||
- [core] add support for listRequiresDot in SQL sources
|
||||
- [web] display freebusy information of owner in appointment editor
|
||||
- [web] register SOGo as a handler for the mailto scheme (#1223)
|
||||
- [web] new events list view where events are grouped by day
|
||||
|
|
|
@ -229,8 +229,7 @@ static Class NSStringK;
|
|||
else
|
||||
queryTimeout = [dd ldapQueryTimeout];
|
||||
|
||||
ASSIGN(modulesConstraints,
|
||||
[udSource objectForKey: @"ModulesConstraints"]);
|
||||
ASSIGN(modulesConstraints, [udSource objectForKey: @"ModulesConstraints"]);
|
||||
ASSIGN(_filter, [udSource objectForKey: @"filter"]);
|
||||
ASSIGN(_userPasswordAlgorithm, [udSource objectForKey: @"userPasswordAlgorithm"]);
|
||||
ASSIGN(_scope, ([udSource objectForKey: @"scope"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SQLSource.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2011 Inverse inc.
|
||||
* Copyright (C) 2009-2017 Inverse inc.
|
||||
*
|
||||
* Authors: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
* Francis Lachapelle <flachapelle@invers.ca>
|
||||
|
@ -50,6 +50,10 @@
|
|||
/* resources handling */
|
||||
NSString *_kindField;
|
||||
NSString *_multipleBookingsField;
|
||||
|
||||
BOOL _listRequiresDot;
|
||||
|
||||
NSDictionary *_modulesConstraints;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -96,6 +96,8 @@
|
|||
_multipleBookingsField = nil;
|
||||
_imapHostField = nil;
|
||||
_sieveHostField = nil;
|
||||
_listRequiresDot = YES;
|
||||
_modulesConstraints = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -114,6 +116,7 @@
|
|||
[_domainField release];
|
||||
[_imapHostField release];
|
||||
[_sieveHostField release];
|
||||
[_modulesConstraints release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -121,6 +124,8 @@
|
|||
- (id) initFromUDSource: (NSDictionary *) udSource
|
||||
inDomain: (NSString *) sourceDomain
|
||||
{
|
||||
NSNumber *dotValue;
|
||||
|
||||
self = [self init];
|
||||
|
||||
ASSIGN(_sourceID, [udSource objectForKey: @"id"]);
|
||||
|
@ -134,6 +139,7 @@
|
|||
ASSIGN(_kindField, [udSource objectForKey: @"KindFieldName"]);
|
||||
ASSIGN(_multipleBookingsField, [udSource objectForKey: @"MultipleBookingsFieldName"]);
|
||||
ASSIGN(_domainField, [udSource objectForKey: @"DomainFieldName"]);
|
||||
ASSIGN(_modulesConstraints, [udSource objectForKey: @"ModulesConstraints"]);
|
||||
if ([udSource objectForKey: @"prependPasswordScheme"])
|
||||
_prependPasswordScheme = [[udSource objectForKey: @"prependPasswordScheme"] boolValue];
|
||||
else
|
||||
|
@ -145,6 +151,10 @@
|
|||
if ([udSource objectForKey: @"viewURL"])
|
||||
_viewURL = [[NSURL alloc] initWithString: [udSource objectForKey: @"viewURL"]];
|
||||
|
||||
dotValue = [udSource objectForKey: @"listRequiresDot"];
|
||||
if (dotValue)
|
||||
[self setListRequiresDot: [dotValue boolValue]];
|
||||
|
||||
#warning this domain code has no effect yet
|
||||
if ([sourceDomain length])
|
||||
ASSIGN (_domain, sourceDomain);
|
||||
|
@ -379,6 +389,35 @@
|
|||
return s;
|
||||
}
|
||||
|
||||
- (void) _fillConstraintsForModule: (NSString *) module
|
||||
intoRecord: (NSMutableDictionary *) record
|
||||
{
|
||||
NSDictionary *constraints;
|
||||
NSEnumerator *matches;
|
||||
NSString *currentMatch, *currentValue, *recordValue;
|
||||
BOOL result;
|
||||
|
||||
result = YES;
|
||||
|
||||
constraints = [_modulesConstraints objectForKey: module];
|
||||
if (constraints)
|
||||
{
|
||||
matches = [[constraints allKeys] objectEnumerator];
|
||||
while (result == YES && (currentMatch = [matches nextObject]))
|
||||
{
|
||||
currentValue = [constraints objectForKey: currentMatch];
|
||||
recordValue = [record objectForKey: currentMatch];
|
||||
result = NO;
|
||||
|
||||
if ([recordValue caseInsensitiveMatches: currentValue])
|
||||
result = YES;
|
||||
}
|
||||
}
|
||||
|
||||
[record setObject: [NSNumber numberWithBool: result]
|
||||
forKey: [NSString stringWithFormat: @"%@Access", module]];
|
||||
}
|
||||
|
||||
- (NSDictionary *) _lookupContactEntry: (NSString *) theID
|
||||
considerEmail: (BOOL) b
|
||||
inDomain: (NSString *) domain
|
||||
|
@ -491,12 +530,9 @@
|
|||
forKey: [field substringFromIndex: 2]];
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// We have to do this here since we do not manage modules
|
||||
// constraints right now over a SQL backend.
|
||||
[response setObject: [NSNumber numberWithBool: YES] forKey: @"CalendarAccess"];
|
||||
[response setObject: [NSNumber numberWithBool: YES] forKey: @"MailAccess"];
|
||||
[response setObject: [NSNumber numberWithBool: YES] forKey: @"ActiveSyncAccess"];
|
||||
[self _fillConstraintsForModule: @"Calendar" intoRecord: response];
|
||||
[self _fillConstraintsForModule: @"Mail" intoRecord: response];
|
||||
[self _fillConstraintsForModule: @"ActiveSync" intoRecord: response];
|
||||
|
||||
// We set the domain, if any
|
||||
value = nil;
|
||||
|
@ -767,6 +803,8 @@
|
|||
|
||||
results = [NSMutableArray array];
|
||||
|
||||
if ([filter length] > 0 || !_listRequiresDot)
|
||||
{
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
channel = [cm acquireOpenChannelForURL: _viewURL];
|
||||
if (channel)
|
||||
|
@ -830,6 +868,7 @@
|
|||
else
|
||||
[self errorWithFormat:@"failed to acquire channel for URL: %@",
|
||||
[_viewURL absoluteString]];
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
@ -856,13 +895,12 @@
|
|||
|
||||
- (void) setListRequiresDot: (BOOL) newListRequiresDot
|
||||
{
|
||||
_listRequiresDot = newListRequiresDot;
|
||||
}
|
||||
|
||||
- (BOOL) listRequiresDot
|
||||
{
|
||||
/* This method is not implemented for SQLSource. It must enable a mechanism
|
||||
where using "." is not required to list the content of addressbooks. */
|
||||
return YES;
|
||||
return _listRequiresDot;
|
||||
}
|
||||
|
||||
/* card editing */
|
||||
|
|
Loading…
Reference in New Issue