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