Added support for the parameter "IMAPLoginMailField" for SQL/LDAP sources, and the parameter "authenticationFilter" for SQL sources. See ChangeLog.

Monotone-Parent: 1cdaff22cdbdb961e1937dc8f1ac1936bd06dc99
Monotone-Revision: 36439821e42cfcb830bfff9081d7e1318f1e92ab

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2011-04-14T18:41:10
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Francis Lachapelle
2011-04-14 18:41:10 +00:00
parent a7d852fbec
commit a87bba64b2
9 changed files with 169 additions and 34 deletions
+23
View File
@@ -1,5 +1,28 @@
2011-04-14 Francis Lachapelle <flachapelle@inverse.ca>
* SoObjects/SOGo/SOGoUserManager.m (-getImapLoginForUID:): we now
consider the source parameter IMAPLoginFieldName. We continue to support
SOGoForceIMAPLoginWithEmail at the domain/system level.
* SoObjects/SOGo/LDAPSource.m: we can now define a new parameter
named IMAPLoginFieldName to specify which field to use for IMAP
authentication. By default, we use the value of the UIDFieldName.
* SoObjects/SOGo/SQLSource.m
(-checkLogin:password:perr:expire:grace:): if the defaults parameter
authenticationFilter is defined, we add it to the SQL where clause.
(_lookupContactEntry:considerEmail:): we add a new key
(canAuthenticate) to the returned dictionary that specifies if the
user can authenticate or not. We also add c_imaplogin when the
user must authenticate with a different username to the IMAP server.
* SoObjects/SOGo/SOGoUser.m (-canAuthenticate): new method that
returns true if the user can authenticate, based on the
authentication filter associated to the source.
* SoObjects/SOGo/SOGoGCSFolder.m (-ocsFolder): don't automatically
create the folder if the user can't authenticate.
* UI/Contacts/UIxContactsListActions.m: was
UIxContactsListView.m. The new method contactsListAction now
returns a JSON representation of the addressbook.
+3 -1
View File
@@ -4,6 +4,7 @@
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -53,7 +54,7 @@
NSString *CNField;
NSString *UIDField;
NSArray *mailFields, *searchFields;
NSString *IMAPHostField;
NSString *IMAPHostField, *IMAPLoginField;
NSArray *bindFields;
BOOL _bindAsCurrentUser;
@@ -83,6 +84,7 @@
mailFields: (NSArray *) newMailFields
searchFields: (NSArray *) newSearchFields
IMAPHostField: (NSString *) newIMAPHostField
IMAPLoginField: (NSString *) newIMAPLoginField
andBindFields: (id) newBindFields;
- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID;
+18
View File
@@ -4,6 +4,7 @@
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -161,6 +162,7 @@ static NSArray *commonSearchFields;
searchFields = [NSArray arrayWithObjects: @"sn", @"displayname", @"telephonenumber", nil];
[searchFields retain];
IMAPHostField = nil;
IMAPLoginField = nil;
bindFields = nil;
_scope = @"sub";
_filter = nil;
@@ -188,6 +190,7 @@ static NSArray *commonSearchFields;
[mailFields release];
[searchFields release];
[IMAPHostField release];
[IMAPLoginField release];
[bindFields release];
[_filter release];
[sourceID release];
@@ -223,6 +226,7 @@ static NSArray *commonSearchFields;
mailFields: [udSource objectForKey: @"MailFieldNames"]
searchFields: [udSource objectForKey: @"SearchFieldNames"]
IMAPHostField: [udSource objectForKey: @"IMAPHostFieldName"]
IMAPLoginField: [udSource objectForKey: @"IMAPLoginFieldName"]
andBindFields: [udSource objectForKey: @"bindFields"]];
if ([sourceDomain length])
@@ -305,6 +309,7 @@ static NSArray *commonSearchFields;
mailFields: (NSArray *) newMailFields
searchFields: (NSArray *) newSearchFields
IMAPHostField: (NSString *) newIMAPHostField
IMAPLoginField: (NSString *) newIMAPLoginField
andBindFields: (id) newBindFields
{
ASSIGN (baseDN, [newBaseDN lowercaseString]);
@@ -316,6 +321,8 @@ static NSArray *commonSearchFields;
ASSIGN (UIDField, newUIDField);
if (newIMAPHostField)
ASSIGN (IMAPHostField, newIMAPHostField);
if (newIMAPLoginField)
ASSIGN (IMAPLoginField, newIMAPLoginField);
if (newMailFields)
ASSIGN (mailFields, newMailFields);
if (newSearchFields)
@@ -694,6 +701,10 @@ static NSArray *commonSearchFields;
// Add IMAP hostname from user defaults
if ([IMAPHostField length])
[searchAttributes addObjectUniquely: IMAPHostField];
// Add IMAP login from user defaults
if ([IMAPLoginField length])
[searchAttributes addObjectUniquely: IMAPLoginField];
}
return searchAttributes;
@@ -761,6 +772,13 @@ static NSArray *commonSearchFields;
if ([ldapValue length] > 0)
[contactEntry setObject: ldapValue forKey: @"c_imaphostname"];
}
if (IMAPLoginField)
{
ldapValue = [[ldapEntry attributeWithName: IMAPLoginField] stringValueAtIndex: 0];
if ([ldapValue length] > 0)
[contactEntry setObject: ldapValue forKey: @"c_imaplogin"];
}
}
- (void) _fillConstraints: (NGLdapEntry *) ldapEntry
+4 -1
View File
@@ -480,14 +480,17 @@ static NSArray *childRecordFields = nil;
- (GCSFolder *) ocsFolder
{
GCSFolder *folder;
SOGoUser *user;
NSString *userLogin;
if (!ocsFolder)
{
ocsFolder = [self ocsFolderForPath: [self ocsPath]];
userLogin = [[context activeUser] login];
user = [context activeUser];
userLogin = [user login];
if (!ocsFolder
&& [userLogin isEqualToString: [self ownerInContext: context]]
&& [user canAuthenticate]
&& [self folderIsMandatory]
&& [self create])
ocsFolder = [self ocsFolderForPath: [self ocsPath]];
+1
View File
@@ -112,6 +112,7 @@
- (NSMutableDictionary *) defaultIdentity;
- (BOOL) isSuperUser;
- (BOOL) canAuthenticate;
/* module access */
- (BOOL) canAccessModule: (NSString *) module;
+9
View File
@@ -757,6 +757,15 @@
return [[_domainDefaults superUsernames] containsObject: login];
}
- (BOOL) canAuthenticate
{
id authValue;
authValue = [self _fetchFieldForUser: @"canAuthenticate"];
return [authValue boolValue];
}
/* module access */
- (BOOL) canAccessModule: (NSString *) module
{
+19 -8
View File
@@ -337,17 +337,23 @@
- (NSString *) getImapLoginForUID: (NSString *) uid
{
NSDictionary *contactInfos;
NSString *domain;
NSString *domain, *login;
SOGoDomainDefaults *dd;
contactInfos = [self contactInfosForUserWithUIDorEmail: uid];
login = [contactInfos objectForKey: @"c_imaplogin"];
domain = [contactInfos objectForKey: @"c_domain"];
if ([domain length])
dd = [SOGoDomainDefaults defaultsForDomain: domain];
else
dd = [SOGoSystemDefaults sharedSystemDefaults];
return ([dd forceIMAPLoginWithEmail] ? [self getEmailForUID: uid] : uid);
if (login == nil)
{
if ([domain length])
dd = [SOGoDomainDefaults defaultsForDomain: domain];
else
dd = [SOGoSystemDefaults sharedSystemDefaults];
login = [dd forceIMAPLoginWithEmail] ? [self getEmailForUID: uid] : uid;
}
return login;
}
- (NSString *) getUIDForEmail: (NSString *) email
@@ -549,7 +555,7 @@
NSDictionary *userEntry;
NSEnumerator *sogoSources;
NSObject <SOGoDNSource> *currentSource;
NSString *sourceID, *cn, *c_domain, *c_uid, *c_imaphostname;
NSString *sourceID, *cn, *c_domain, *c_uid, *c_imaphostname, *c_imaplogin;
NSArray *c_emails;
BOOL access;
@@ -558,6 +564,7 @@
c_uid = nil;
c_domain = nil;
c_imaphostname = nil;
c_imaplogin = nil;
[currentUser setObject: [NSNumber numberWithBool: YES]
forKey: @"CalendarAccess"];
@@ -583,6 +590,8 @@
[emails addObjectsFromArray: c_emails];
if (!c_imaphostname)
c_imaphostname = [userEntry objectForKey: @"c_imaphostname"];
if (!c_imaplogin)
c_imaplogin = [userEntry objectForKey: @"c_imaplogin"];
access = [[userEntry objectForKey: @"CalendarAccess"] boolValue];
if (!access)
[currentUser setObject: [NSNumber numberWithBool: NO]
@@ -603,6 +612,8 @@
if (c_imaphostname)
[currentUser setObject: c_imaphostname forKey: @"c_imaphostname"];
if (c_imaplogin)
[currentUser setObject: c_imaplogin forKey: @"c_imaplogin"];
[currentUser setObject: emails forKey: @"emails"];
[currentUser setObject: cn forKey: @"cn"];
[currentUser setObject: c_uid forKey: @"c_uid"];
+4 -1
View File
@@ -2,7 +2,8 @@
*
* Copyright (C) 2009-2011 Inverse inc.
*
* Author: Ludovic Marcotte <lmarcotte@inverse.ca>
* Authors: Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@invers.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +37,9 @@
{
NSString *_sourceID;
NSString *_domain;
NSString *_authenticationFilter;
NSArray *_mailFields;
NSString *_imapLoginField;
NSString *_userPasswordAlgorithm;
NSURL *_viewURL;
}
+88 -23
View File
@@ -2,7 +2,8 @@
*
* Copyright (C) 2009-2011 Inverse inc.
*
* Author: Ludovic Marcotte <lmarcotte@inverse.ca>
* Authors: Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,9 +32,8 @@
#import <GDLContentStore/GCSChannelManager.h>
#import <GDLContentStore/NSURL+GCS.h>
#import <GDLContentStore/EOQualifier+GCS.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLAccess/EOAdaptorContext.h>
#import <GDLAccess/EOAttribute.h>
#import "SOGoConstants.h"
#import "NSString+Utilities.h"
@@ -79,6 +79,7 @@
if ((self = [super init]))
{
_sourceID = nil;
_authenticationFilter = nil;
_mailFields = nil;
_userPasswordAlgorithm = nil;
_viewURL = nil;
@@ -90,6 +91,7 @@
- (void) dealloc
{
[_sourceID release];
[_authenticationFilter release];
[_mailFields release];
[_userPasswordAlgorithm release];
[_viewURL release];
@@ -103,8 +105,10 @@
self = [self init];
ASSIGN(_sourceID, [udSource objectForKey: @"id"]);
ASSIGN(_authenticationFilter, [udSource objectForKey: @"authenticationFilter"]);
ASSIGN(_mailFields, [udSource objectForKey: @"MailFieldNames"]);
ASSIGN(_userPasswordAlgorithm, [udSource objectForKey: @"userPasswordAlgorithm"]);
ASSIGN(_imapLoginField, [udSource objectForKey: @"IMAPLoginFieldName"]);
if (!_userPasswordAlgorithm)
_userPasswordAlgorithm = @"none";
@@ -203,9 +207,10 @@
grace: (int *) _grace
{
EOAdaptorChannel *channel;
EOQualifier *qualifier;
GCSChannelManager *cm;
NSException *ex;
NSString *sql;
NSMutableString *sql;
BOOL rc;
rc = NO;
@@ -214,12 +219,25 @@
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: _viewURL];
if (channel)
{
sql = [NSString stringWithFormat: (@"SELECT c_password"
@" FROM %@"
@" WHERE c_uid = '%@'"),
[_viewURL gcsTableName], _login];
{
qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
operatorSelector: EOQualifierOperatorEqual
value: _login];
[qualifier autorelease];
sql = [NSMutableString stringWithFormat: @"SELECT c_password"
@" FROM %@"
@" WHERE ",
[_viewURL gcsTableName]];
if (_authenticationFilter)
{
qualifier = [[EOAndQualifier alloc] initWithQualifiers:
qualifier,
[EOQualifier qualifierWithQualifierFormat: _authenticationFilter],
nil];
[qualifier autorelease];
}
[qualifier _gcsAppendToString: sql];
ex = [channel evaluateExpressionX: sql];
if (!ex)
{
@@ -235,7 +253,8 @@
[channel cancelFetch];
}
else
[self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];
[self errorWithFormat: @"could not run SQL '%@': %@", qualifier, ex];
[cm releaseChannel: channel];
}
else
@@ -328,8 +347,10 @@
{
NSMutableDictionary *response;
EOAdaptorChannel *channel;
EOQualifier *qualifier;
GCSChannelManager *cm;
NSString *sql, *value;
NSMutableString *sql;
NSString *value;
NSException *ex;
response = nil;
@@ -340,21 +361,21 @@
if (channel)
{
if (!b)
sql = [NSString stringWithFormat: (@"SELECT *"
@" FROM %@"
@" WHERE c_uid = '%@'"),
[_viewURL gcsTableName], theID];
sql = [NSMutableString stringWithFormat: (@"SELECT *"
@" FROM %@"
@" WHERE c_uid = '%@'"),
[_viewURL gcsTableName], theID];
else
{
sql = [NSString stringWithFormat: (@"SELECT *"
@" FROM %@"
@" WHERE c_uid = '%@' OR"
@" LOWER(mail) = '%@'"),
[_viewURL gcsTableName], theID, [theID lowercaseString]];
sql = [NSMutableString stringWithFormat: (@"SELECT *"
@" FROM %@"
@" WHERE c_uid = '%@' OR"
@" LOWER(mail) = '%@'"),
[_viewURL gcsTableName], theID, [theID lowercaseString]];
if (_mailFields && [_mailFields count] > 0)
{
sql = [sql stringByAppendingString: [self _whereClauseFromArray: _mailFields value: [theID lowercaseString] exact: YES]];
[sql appendString: [self _whereClauseFromArray: _mailFields value: [theID lowercaseString] exact: YES]];
}
}
@@ -397,6 +418,50 @@
}
[response setObject: emails forKey: @"c_emails"];
// We check if the user can authenticate
if (_authenticationFilter)
{
EOQualifier *q_uid, *q_auth;
sql = [NSMutableString stringWithFormat: @"SELECT c_uid"
@" FROM %@"
@" WHERE ",
[_viewURL gcsTableName]];
q_auth = [EOQualifier qualifierWithQualifierFormat: _authenticationFilter];
q_uid = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
operatorSelector: EOQualifierOperatorEqual
value: theID];
[q_uid autorelease];
qualifier = [[EOAndQualifier alloc] initWithQualifiers: q_uid, q_auth, nil];
[qualifier autorelease];
[qualifier _gcsAppendToString: sql];
ex = [channel evaluateExpressionX: sql];
if (!ex)
{
NSDictionary *authResponse;
authResponse = [channel fetchAttributes: [channel describeResults: NO] withZone: NULL];
[response setObject: [NSNumber numberWithBool: [authResponse count] > 0] forKey: @"canAuthenticate"];
[channel cancelFetch];
}
else
[self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];
}
else
[response setObject: [NSNumber numberWithBool: YES] forKey: @"canAuthenticate"];
// We check if we should use a different login for IMAP
if (_imapLoginField)
{
if ([response objectForKey: _imapLoginField])
[response setObject: [response objectForKey: _imapLoginField] forKey: @"c_imaplogin"];
}
}
else
[self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];