See ChangeLog

Monotone-Parent: a0ddb6969a3af4885bc30844a5dc0bcda95a8212
Monotone-Revision: ae3b606b25bf64895dc0e94fd5ceccaa439e457f

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2010-03-14T23:07:42
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Ludovic Marcotte 2010-03-14 23:07:42 +00:00
parent d7bca94299
commit 914e382dcd
3 changed files with 74 additions and 37 deletions

View File

@ -1,3 +1,8 @@
2010-03-14 Ludovic Marcotte <lmarcotte@inverse.ca>
* Improved the password policy code. All corner
cases should now be handled correctly.
2010-03-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m

View File

@ -1,20 +1,22 @@
/*
Copyright (C) 2006-2010 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
License along with SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
@ -137,7 +139,7 @@
BOOL b;
err = PolicyNoError;
expire = grace = 0;
expire = grace = -1;
auth = [[WOApplication application]
authenticatorInContext: context];
@ -148,17 +150,23 @@
if ((b = [auth checkLogin: username password: password
perr: &err expire: &expire grace: &grace])
&& (err == PolicyNoError))
&& (err == PolicyNoError)
// no password policy
&& ((expire < 0 && grace < 0) // no password policy or everything is alright
|| (expire < 0 && grace > 0) // password expired, grace still permits login
|| (expire > 0 && grace == -1))) // password about to expire
{
[self logWithFormat: @"successful login for user '%@'", username];
response = [self responseWith204];
// We must warn the user that he has to change his password
if (err == PolicyChangeAfterReset)
{
}
NSDictionary *json;
[self logWithFormat: @"successful login for user '%@' - expire = %d grace = %d", username, expire, grace];
json = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: expire], @"expire",
[NSNumber numberWithInt: grace], @"grace", nil];
response = [self responseWithStatus: 200
andJSONRepresentation: json];
authCookie = [self _cookieWithUsername: username andPassword: password
forAuthenticator: auth];
[response addCookie: authCookie];
@ -174,20 +182,7 @@
}
else
{
[self logWithFormat: @"Login for user '%@' might not have worked - password policy: %d bound: ", username, err, b];
if (err == PolicyNoError)
{
[self logWithFormat: @"failed login for user '%@' due to wrong password", username];
}
else if (err == PolicyAccountLocked)
{
// Account has been locked due to too many failures
}
else if (err == PolicyPasswordExpired)
{
// The password MUST be changed - we need to ask for the old password and the new one here
}
[self logWithFormat: @"Login for user '%@' might not have worked - password policy: %d grace: %d expire: %d bound: %d", username, err, grace, expire, b];
response = [self _responseWithLDAPPolicyError: err];
}

View File

@ -79,7 +79,7 @@ function onLoginClick(event) {
: ("&language=" + language.value));
/// 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 = "";
//document.cookie = "";\
triggerAjaxRequest(url, onLoginCallback, null, (parameters),
{ "Content-type": "application/x-www-form-urlencoded",
"Content-length": parameters.length,
@ -95,7 +95,7 @@ function onLoginCallback(http) {
if (http.readyState == 4) {
var submitBtn = $("submit");
if (isHttpStatus204(http.status)) {
if (http.status == 200) {
// Make sure browser's cookies are enabled
var loginCookie = readLoginCookie();
if (!loginCookie) {
@ -104,7 +104,21 @@ function onLoginCallback(http) {
return;
}
redirectToUserPage();
var jsonResponse = http.responseText.evalJSON(false);
if (jsonResponse
&& typeof(jsonResponse["expire"]) != "undefined"
&& typeof(jsonResponse["grace"]) != "undefined") {
if (jsonResponse["expire"] < 0 && jsonResponse["grace"] > 0)
showPasswordDialog("grace", createPasswordGraceDialog, jsonResponse["grace"]);
else if (jsonResponse["expire"] > 0 && jsonResponse["grace"] == -1)
showPasswordDialog("expiration", createPasswordExpirationDialog, jsonResponse["expire"]);
else {
redirectToUserPage();
}
}
else
redirectToUserPage();
}
else {
if (http.status == 403
@ -159,10 +173,14 @@ function handlePasswordError(jsonResponse) {
SetLogMessage("errorMessage",
_("Your account was locked due to too many"
+ " failed attempts."));
} else if (perr == PolicyChangeAfterReset
|| perr == PolicyPasswordExpired) {
} else if (perr == PolicyChangeAfterReset) {
showPasswordDialog("change", createPasswordChangeDialog, 5);
} else
} else if (perr == PolicyPasswordExpired) {
SetLogMessage("errorMessage",
_("Your account was locked due to an"
+ " expired password."));
}
else
SetLogMessage("errorMessage",
_("Login failed due to unhandled error case: " + perr));
}
@ -268,9 +286,8 @@ function createPasswordGraceDialog(tries) {
return createDialog("passwordGraceDialog",
_("Password Grace Period"),
_("You have %{0} logins remaining before your"
+ " password expires. Please change your"
+ " password in the preference dialog.")
.formatted(tries),
+ " account is locked. Please change your"
+ " password in the preference dialog.").formatted(tries),
button,
"right");
}
@ -279,6 +296,26 @@ function passwordGraceDialogOK(event) {
var dialog = $("passwordGraceDialog");
dialog.hide();
event.stop();
redirectToUserPage();
}
function createPasswordExpirationDialog(expire) {
var button = createButton("expirationOKButton", _("OK"));
button.observe("click", passwordExpirationDialogOK);
button.addClassName("actionButton");
return createDialog("passwordExpirationDialog",
_("Password about to expire"),
_("Your password is going to expire in %{0} seconds.").formatted(expire),
button,
"right");
}
function passwordExpirationDialogOK(event) {
var dialog = $("passwordExpirationDialog");
dialog.hide();
event.stop();
redirectToUserPage();
}
document.observe("dom:loaded", initLogin);