propagate from branch 'ca.inverse.sogo.1_3_9' (head a8c1ef20873db2c870d93bd5f81876e3cb41c719)
to branch 'ca.inverse.sogo' (head 231e422b9b38aa18cacf5236082f57d828dbf8f2) Monotone-Parent: 231e422b9b38aa18cacf5236082f57d828dbf8f2 Monotone-Parent: a8c1ef20873db2c870d93bd5f81876e3cb41c719 Monotone-Revision: 6eb618087a406a6325b55eae8131b9965c37aed9 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2011-10-26T19:11:52 Monotone-Branch: ca.inverse.sogomaint-2.0.2
commit
dcf0925ece
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,11 @@
|
|||
2011-10-26 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SQLSource.m
|
||||
(-checkLogin:password:perr:expire:grace:): authentication can be
|
||||
performed against any database column defined in the new
|
||||
LoginFieldNames defaults parameter.
|
||||
(-_lookupContactEntry:considerEmail:): idem.
|
||||
|
||||
2011-10-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m
|
||||
|
@ -14,6 +22,13 @@
|
|||
* OpenChange/MAPIStoreSOGo.m (sogo_message_create_attachment):
|
||||
implemented new backend method.
|
||||
|
||||
2011-10-25 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/MainUI/SOGoRootPage.m (-cookieUsername)
|
||||
(-cookieWithUsername:): getter/setter for the new SOGoLogin
|
||||
cookie. This is used for the new "Remember username" checkbox that
|
||||
appears on the login page.
|
||||
|
||||
2011-10-25 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/EOQualifier+MAPIFS.[hm]: now evaluates
|
||||
|
|
Binary file not shown.
Binary file not shown.
17
NEWS
17
NEWS
|
@ -1,4 +1,4 @@
|
|||
2.0-20111004 (2.0.0beta1 - branched from upcoming v1.3.9)
|
||||
1.3-201110DD (1.3.9)
|
||||
---------------------
|
||||
New Features
|
||||
- new user defaults SOGoDefaultCalendar to specify which calendar is used when
|
||||
|
@ -7,11 +7,26 @@ New Features
|
|||
automatically added to the free-busy information
|
||||
- new indicator in the link banner when a vacation message (auto-reply) is active
|
||||
- new snooze function for events alarms in Web interface
|
||||
- new "Remember login" checkbox on the login page
|
||||
- authentication with SQL sources can now be performed on any database column
|
||||
using the new LoginFieldNames parameter
|
||||
|
||||
Enhancements
|
||||
- added support for the CalDAV move operation
|
||||
- phone numbers in the contacts web module are now links (tel:)
|
||||
- revamp of the modules link banner (15-pixel taller)
|
||||
- updated CKEditor to version 3.6.2
|
||||
- updated unread and flagged icons in Webmail module
|
||||
- new dependency on GNUstep 1.23
|
||||
|
||||
Bug Fixes
|
||||
- fixed support for Apple iOS 5
|
||||
- fixed handling of untagged IMAP responses
|
||||
- fixed handling of commas in email addresses when composing a message
|
||||
- fixed creation of clickable links for URLs surrounded by square brackets
|
||||
- fixed behaviour of combo box for contacts categories
|
||||
- fixed Swedish translation classes
|
||||
- fixed bug when setting no ACL on a calendar
|
||||
|
||||
1.3-20110726 (1.3.8b)
|
||||
---------------------
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
allowsNull = YES;
|
||||
},
|
||||
{
|
||||
columnName = c_telephoneNumber;
|
||||
columnName = c_telephonenumber;
|
||||
sqlType = "VARCHAR2(255)";
|
||||
allowsNull = YES;
|
||||
},
|
||||
|
|
|
@ -761,7 +761,7 @@
|
|||
else
|
||||
cacheUid = aUID;
|
||||
jsonUser = [[SOGoCache sharedCache] userAttributesForLogin: cacheUid];
|
||||
currentUser = [jsonUser objectFromJSONString];
|
||||
currentUser = [jsonUser objectFromJSONString];
|
||||
if (!([currentUser objectForKey: @"emails"]
|
||||
&& [currentUser objectForKey: @"cn"]))
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
NSString *_sourceID;
|
||||
NSString *_domain;
|
||||
NSString *_authenticationFilter;
|
||||
NSArray *_loginFields;
|
||||
NSArray *_mailFields;
|
||||
NSString *_imapLoginField;
|
||||
NSString *_userPasswordAlgorithm;
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
{
|
||||
_sourceID = nil;
|
||||
_authenticationFilter = nil;
|
||||
_loginFields = nil;
|
||||
_mailFields = nil;
|
||||
_userPasswordAlgorithm = nil;
|
||||
_viewURL = nil;
|
||||
|
@ -95,6 +96,7 @@
|
|||
{
|
||||
[_sourceID release];
|
||||
[_authenticationFilter release];
|
||||
[_loginFields release];
|
||||
[_mailFields release];
|
||||
[_userPasswordAlgorithm release];
|
||||
[_viewURL release];
|
||||
|
@ -111,6 +113,7 @@
|
|||
|
||||
ASSIGN(_sourceID, [udSource objectForKey: @"id"]);
|
||||
ASSIGN(_authenticationFilter, [udSource objectForKey: @"authenticationFilter"]);
|
||||
ASSIGN(_loginFields, [udSource objectForKey: @"LoginFieldNames"]);
|
||||
ASSIGN(_mailFields, [udSource objectForKey: @"MailFieldNames"]);
|
||||
ASSIGN(_userPasswordAlgorithm, [udSource objectForKey: @"userPasswordAlgorithm"]);
|
||||
ASSIGN(_imapLoginField, [udSource objectForKey: @"IMAPLoginFieldName"]);
|
||||
|
@ -227,9 +230,31 @@
|
|||
channel = [cm acquireOpenChannelForURL: _viewURL];
|
||||
if (channel)
|
||||
{
|
||||
qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: _login];
|
||||
if (_loginFields)
|
||||
{
|
||||
NSMutableArray *qualifiers;
|
||||
NSString *field;
|
||||
EOQualifier *loginQualifier;
|
||||
int i;
|
||||
|
||||
qualifiers = [NSMutableArray arrayWithCapacity: [_loginFields count]];
|
||||
for (i = 0; i < [_loginFields count]; i++)
|
||||
{
|
||||
field = [_loginFields objectAtIndex: i];
|
||||
loginQualifier = [[EOKeyValueQualifier alloc] initWithKey: field
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: _login];
|
||||
[loginQualifier autorelease];
|
||||
[qualifiers addObject: loginQualifier];
|
||||
}
|
||||
qualifier = [[EOOrQualifier alloc] initWithQualifierArray: qualifiers];
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: _login];
|
||||
}
|
||||
[qualifier autorelease];
|
||||
sql = [NSMutableString stringWithFormat: @"SELECT c_password"
|
||||
@" FROM %@"
|
||||
|
@ -353,12 +378,14 @@
|
|||
considerEmail: (BOOL) b
|
||||
{
|
||||
NSMutableDictionary *response;
|
||||
NSMutableArray *qualifiers;
|
||||
EOAdaptorChannel *channel;
|
||||
EOQualifier *qualifier;
|
||||
EOQualifier *loginQualifier, *qualifier;
|
||||
GCSChannelManager *cm;
|
||||
NSMutableString *sql;
|
||||
NSString *value;
|
||||
NSString *value, *field;
|
||||
NSException *ex;
|
||||
int i;
|
||||
|
||||
response = nil;
|
||||
|
||||
|
@ -367,25 +394,65 @@
|
|||
channel = [cm acquireOpenChannelForURL: _viewURL];
|
||||
if (channel)
|
||||
{
|
||||
if (!b)
|
||||
sql = [NSMutableString stringWithFormat: (@"SELECT *"
|
||||
@" FROM %@"
|
||||
@" WHERE c_uid = '%@'"),
|
||||
[_viewURL gcsTableName], theID];
|
||||
else
|
||||
{
|
||||
sql = [NSMutableString stringWithFormat: (@"SELECT *"
|
||||
@" FROM %@"
|
||||
@" WHERE c_uid = '%@' OR"
|
||||
@" LOWER(mail) = '%@'"),
|
||||
[_viewURL gcsTableName], theID, [theID lowercaseString]];
|
||||
qualifiers = [NSMutableArray arrayWithCapacity: [_loginFields count] + 1];
|
||||
|
||||
// Always compare against the c_uid field
|
||||
loginQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: theID];
|
||||
[loginQualifier autorelease];
|
||||
[qualifiers addObject: loginQualifier];
|
||||
|
||||
if (_loginFields)
|
||||
{
|
||||
for (i = 0; i < [_loginFields count]; i++)
|
||||
{
|
||||
field = [_loginFields objectAtIndex: i];
|
||||
if ([field caseInsensitiveCompare: @"c_uid"] != NSOrderedSame)
|
||||
{
|
||||
loginQualifier = [[EOKeyValueQualifier alloc] initWithKey: field
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: theID];
|
||||
[loginQualifier autorelease];
|
||||
[qualifiers addObject: loginQualifier];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b)
|
||||
{
|
||||
// Always compare againts the mail field
|
||||
loginQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"mail"
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: [theID lowercaseString]];
|
||||
[loginQualifier autorelease];
|
||||
[qualifiers addObject: loginQualifier];
|
||||
|
||||
if (_mailFields && [_mailFields count] > 0)
|
||||
if (_mailFields)
|
||||
{
|
||||
[sql appendString: [self _whereClauseFromArray: _mailFields value: [theID lowercaseString] exact: YES]];
|
||||
}
|
||||
for (i = 0; i < [_mailFields count]; i++)
|
||||
{
|
||||
field = [_mailFields objectAtIndex: i];
|
||||
if ([field caseInsensitiveCompare: @"mail"] != NSOrderedSame
|
||||
&& ![_loginFields containsObject: field])
|
||||
{
|
||||
loginQualifier = [[EOKeyValueQualifier alloc] initWithKey: field
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: [theID lowercaseString]];
|
||||
[loginQualifier autorelease];
|
||||
[qualifiers addObject: loginQualifier];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sql = [NSMutableString stringWithFormat: @"SELECT *"
|
||||
@" FROM %@"
|
||||
@" WHERE ",
|
||||
[_viewURL gcsTableName]];
|
||||
qualifier = [[EOOrQualifier alloc] initWithQualifierArray: qualifiers];
|
||||
[qualifier _gcsAppendToString: sql];
|
||||
|
||||
ex = [channel evaluateExpressionX: sql];
|
||||
if (!ex)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"Username:" = "Username:";
|
||||
"Password:" = "Password:";
|
||||
"Domain:" = "Domain:";
|
||||
"Remember username" = "Remember username";
|
||||
|
||||
"Connect" = "Connect";
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"Username:" = "Nom d'utilisateur :";
|
||||
"Password:" = "Mot de passe :";
|
||||
"Domain:" = "Domaine :";
|
||||
"Remember username" = "Se souvenir de moi";
|
||||
|
||||
"Connect" = "Connexion";
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
@interface SOGoRootPage : UIxComponent
|
||||
{
|
||||
id item;
|
||||
NSString *cookieLogin;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -58,6 +58,22 @@
|
|||
|
||||
@implementation SOGoRootPage
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
cookieLogin = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[cookieLogin release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *) connectURL
|
||||
|
@ -65,6 +81,25 @@
|
|||
return [NSString stringWithFormat: @"%@/connect", [self applicationPath]];
|
||||
}
|
||||
|
||||
- (NSString *) cookieUsername
|
||||
{
|
||||
NSString *value;
|
||||
|
||||
if (cookieLogin == nil)
|
||||
{
|
||||
value = [[context request] cookieValueForKey: @"SOGoLogin"];
|
||||
cookieLogin = [value isNotNull]? [value stringByDecodingBase64] : @"";
|
||||
[cookieLogin retain];
|
||||
}
|
||||
|
||||
return cookieLogin;
|
||||
}
|
||||
|
||||
- (BOOL) rememberLogin
|
||||
{
|
||||
return ([[self cookieUsername] length]);
|
||||
}
|
||||
|
||||
- (WOCookie *) _cookieWithUsername: (NSString *) username
|
||||
andPassword: (NSString *) password
|
||||
forAuthenticator: (SOGoWebAuthenticator *) auth
|
||||
|
@ -105,6 +140,32 @@
|
|||
return authCookie;
|
||||
}
|
||||
|
||||
- (WOCookie *) _cookieWithUsername: (NSString *) username
|
||||
{
|
||||
WOCookie *loginCookie;
|
||||
NSString *appName;
|
||||
NSCalendarDate *date;
|
||||
|
||||
appName = [[context request] applicationName];
|
||||
if (username)
|
||||
{
|
||||
loginCookie = [WOCookie cookieWithName: @"SOGoLogin"
|
||||
value: [username stringByEncodingBase64]];
|
||||
}
|
||||
else
|
||||
{
|
||||
loginCookie = [WOCookie cookieWithName: @"SOGoLogin"
|
||||
value: nil];
|
||||
date = [NSCalendarDate calendarDate];
|
||||
[date setTimeZone: [NSTimeZone timeZoneWithAbbreviation: @"GMT"]];
|
||||
[loginCookie setExpires: [date yesterday]];
|
||||
}
|
||||
|
||||
[loginCookie setPath: [NSString stringWithFormat: @"/%@/", appName]];
|
||||
|
||||
return loginCookie;
|
||||
}
|
||||
|
||||
- (WOCookie *) _casLocationCookie: (BOOL) cookieReset
|
||||
{
|
||||
WOCookie *locationCookie;
|
||||
|
@ -155,7 +216,7 @@
|
|||
|
||||
SOGoPasswordPolicyError err;
|
||||
int expire, grace;
|
||||
BOOL b;
|
||||
BOOL rememberLogin, b;
|
||||
|
||||
err = PolicyNoError;
|
||||
expire = grace = -1;
|
||||
|
@ -166,6 +227,7 @@
|
|||
username = [request formValueForKey: @"userName"];
|
||||
password = [request formValueForKey: @"password"];
|
||||
language = [request formValueForKey: @"language"];
|
||||
rememberLogin = [[request formValueForKey: @"rememberLogin"] boolValue];
|
||||
domain = [request formValueForKey: @"domain"];
|
||||
|
||||
if ((b = [auth checkLogin: username password: password domain: &domain
|
||||
|
@ -220,6 +282,11 @@
|
|||
response = [self _responseWithLDAPPolicyError: err];
|
||||
}
|
||||
|
||||
if (rememberLogin)
|
||||
[response addCookie: [self _cookieWithUsername: username]];
|
||||
else
|
||||
[response addCookie: [self _cookieWithUsername: nil]];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<td id="loginCell" width="230">
|
||||
<label><var:string label:value="Username:"/><br/>
|
||||
<input class="textField" id="userName" name="userName"
|
||||
type="text" var:value="userName" /></label>
|
||||
type="text" var:value="cookieUsername" /></label>
|
||||
<label><var:string label:value="Password:"/><br/>
|
||||
<input class="textField" id="password"
|
||||
name="password" type="password" var:value="password" /></label>
|
||||
|
@ -61,6 +61,7 @@
|
|||
string="item"
|
||||
/></label>
|
||||
</var:if>
|
||||
<label><input id="rememberLogin" type="checkbox" class="checkBox" var:checked="rememberLogin"/> <var:string label:value="Remember username"/></label>
|
||||
<label>
|
||||
<a href="#" class="button" id="submit" name="submit">
|
||||
<span><var:string label:value="Connect" /></span></a>
|
||||
|
|
|
@ -94,7 +94,7 @@ DIV#administrationModules UL LI
|
|||
DIV#rightPanel
|
||||
{
|
||||
position: absolute;
|
||||
top: 6em;
|
||||
top: 80px;
|
||||
left: 15em;
|
||||
margin-left: 5px;
|
||||
right: 0px;
|
||||
|
|
|
@ -29,7 +29,6 @@ function initLogin() {
|
|||
submit.observe("click", onLoginClick);
|
||||
|
||||
var userName = $("userName");
|
||||
userName.focus();
|
||||
userName.observe("keydown", onFieldKeyDown);
|
||||
|
||||
var passw = $("password");
|
||||
|
@ -40,6 +39,11 @@ function initLogin() {
|
|||
|
||||
var submitBtn = $("submit");
|
||||
submitBtn.disabled = false;
|
||||
|
||||
if (userName.value.empty())
|
||||
userName.focus();
|
||||
else
|
||||
passw.focus();
|
||||
}
|
||||
|
||||
function onFieldKeyDown(event) {
|
||||
|
@ -82,6 +86,9 @@ function onLoginClick(event) {
|
|||
: ("&language=" + language.value));
|
||||
if (domain)
|
||||
parameters += "&domain=" + domain.value;
|
||||
if ($("rememberLogin").checked)
|
||||
parameters += "&rememberLogin=1";
|
||||
|
||||
/// Discarded as it seems to create a cookie for nothing. To discard
|
||||
// a cookie in JS, have a look here: http://www.quirksmode.org/js/cookies.html
|
||||
//document.cookie = "";\
|
||||
|
|
6
Version
6
Version
|
@ -2,6 +2,6 @@
|
|||
# This file is included by library makefiles to set the version information
|
||||
# of the executable.
|
||||
|
||||
MAJOR_VERSION=2
|
||||
MINOR_VERSION=0
|
||||
SUBMINOR_VERSION=0
|
||||
MAJOR_VERSION=1
|
||||
MINOR_VERSION=3
|
||||
SUBMINOR_VERSION=9
|
||||
|
|
|
@ -10,7 +10,7 @@ Group: Productivity/Groupware
|
|||
Source: SOGo-%{sogo_version}.tar.gz
|
||||
Prefix: /usr
|
||||
AutoReqProv: off
|
||||
Requires: gnustep-base, sope%{sope_major_version}%{sope_minor_version}-core, httpd, sope%{sope_major_version}%{sope_minor_version}-core, sope%{sope_major_version}%{sope_minor_version}-appserver, sope%{sope_major_version}%{sope_minor_version}-ldap, sope%{sope_major_version}%{sope_minor_version}-cards >= %{sogo_version}, sope%{sope_major_version}%{sope_minor_version}-gdl1-contentstore >= %{sogo_version}, sope%{sope_major_version}%{sope_minor_version}-sbjson, memcached, libmemcached
|
||||
Requires: gnustep-base >= 1.23, sope%{sope_major_version}%{sope_minor_version}-core, httpd, sope%{sope_major_version}%{sope_minor_version}-core, sope%{sope_major_version}%{sope_minor_version}-appserver, sope%{sope_major_version}%{sope_minor_version}-ldap, sope%{sope_major_version}%{sope_minor_version}-cards >= %{sogo_version}, sope%{sope_major_version}%{sope_minor_version}-gdl1-contentstore >= %{sogo_version}, sope%{sope_major_version}%{sope_minor_version}-sbjson, memcached, libmemcached
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
|
||||
BuildPreReq: gcc-objc gnustep-base gnustep-make sope%{sope_major_version}%{sope_minor_version}-appserver-devel sope%{sope_major_version}%{sope_minor_version}-core-devel sope%{sope_major_version}%{sope_minor_version}-ldap-devel sope%{sope_major_version}%{sope_minor_version}-mime-devel sope%{sope_major_version}%{sope_minor_version}-xml-devel sope%{sope_major_version}%{sope_minor_version}-gdl1-devel sope%{sope_major_version}%{sope_minor_version}-sbjson-devel libmemcached-devel samba4 openchange
|
||||
|
||||
|
|
Loading…
Reference in New Issue