* Login/Password: handle forced password change on login page

r53022: visualize not existing ability to unset "must change password on next login", by making it readonly
r53024: change "password about to expire in N days" warning into an once per login info-message (was a redirect to password change)
This commit is contained in:
Ralf Becker 2015-07-01 17:54:18 +00:00
parent 55248b0d18
commit 058ef3e89f
15 changed files with 310 additions and 204 deletions

View File

@ -86,6 +86,12 @@ class admin_account
$readonlys = array();
// at least ADS does not allow to unset it and SQL backend does not implement it either
if ($account['mustchangepassword'])
{
$readonlys['mustchangepassword'] = true;
}
if ($deny_edit)
{
foreach(array_keys($account) as $key)

View File

@ -901,7 +901,7 @@ td.et2_required {
border: 1px solid #E1E16D;
color: #000000;
font-size: 11px;
height: 15px;
min-height: 15px;
padding: 4px 10px;
}
.error p {

112
login.php
View File

@ -132,11 +132,13 @@ else
return lang('Sorry, your login has expired');
case 4:
return lang('Cookies are required to login to this site');
case 5:
case egw_session::CD_BAD_LOGIN_OR_PASSWORD:
return lang('Bad login or password');
case 98:
case egw_session::CD_FORCE_PASSWORD_CHANGE:
return lang('You must change your password!');
case egw_session::CD_ACCOUNT_EXPIRED:
return lang('Account is expired');
case 99:
case egw_session::CD_BLOCKED:
return lang('Blocked, too many attempts');
case 10:
$GLOBALS['egw']->session->egw_setcookie('sessionid');
@ -272,9 +274,32 @@ else
$login .= '@'.$GLOBALS['egw_info']['server']['default_domain'];
}
}
$GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login,$passwd,$passwd_type);
$GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login, $passwd,
$passwd_type, false, true, true); // true = let session fail on forced password change
if(!isset($GLOBALS['sessionid']) || ! $GLOBALS['sessionid'])
if (!$GLOBALS['sessionid'] && $GLOBALS['egw']->session->cd_reason == egw_session::CD_FORCE_PASSWORD_CHANGE)
{
if (isset($_POST['new_passwd']))
{
if (($errors = preferences_password::do_change($passwd, $_POST['new_passwd'], $_POST['new_passwd2'])))
{
$force_password_change = implode("\n", $errors);
}
else
{
$GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login,$_POST['new_passwd'],$passwd_type);
}
}
else
{
$force_password_change = $GLOBALS['egw']->session->reason;
}
}
if (isset($force_password_change))
{
// will show new login-screen incl. new password field below
}
elseif (!isset($GLOBALS['sessionid']) || ! $GLOBALS['sessionid'])
{
$GLOBALS['egw']->session->egw_setcookie('eGW_remember','',0,'/');
egw::redirect_link('/login.php?cd=' . $GLOBALS['egw']->session->cd_reason);
@ -363,52 +388,49 @@ else
}
}
}
else
// show login screen
if(isset($_COOKIE['last_loginid']))
{
if(isset($_COOKIE['last_loginid']))
{
$accounts =& CreateObject('phpgwapi.accounts');
$prefs =& CreateObject('phpgwapi.preferences', $accounts->name2id($_COOKIE['last_loginid']));
$prefs = new preferences($GLOBALS['egw']->accounts->name2id($_COOKIE['last_loginid']));
if($prefs->account_id)
{
$GLOBALS['egw_info']['user']['preferences'] = $prefs->read_repository();
}
}
if ($_GET['lang'] && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_GET['lang']))
if($prefs->account_id)
{
$GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $_GET['lang'];
$GLOBALS['egw_info']['user']['preferences'] = $prefs->read_repository();
}
elseif(!isset($_COOKIE['last_loginid']) || !$prefs->account_id)
}
if ($_GET['lang'] && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_GET['lang']))
{
$GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $_GET['lang'];
}
elseif(!isset($_COOKIE['last_loginid']) || !$prefs->account_id)
{
// If the lastloginid cookies isn't set, we will default to the first language,
// the users browser accepts.
list($lang) = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
if(strlen($lang) > 2)
{
// If the lastloginid cookies isn't set, we will default to the first language,
// the users browser accepts.
list($lang) = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
if(strlen($lang) > 2)
{
$lang = substr($lang,0,2);
}
$GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $lang;
$lang = substr($lang,0,2);
}
if ($_COOKIE['eGW_cookie_test'] !== 'enabled')
{
egw_session::egw_setcookie('eGW_cookie_test','enabled',0);
}
#print 'LANG:' . $GLOBALS['egw_info']['user']['preferences']['common']['lang'] . '<br>';
translation::init(); // this will set the language according to the (new) set prefs
translation::add_app('login');
translation::add_app('loginscreen');
$GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $lang;
}
if ($_COOKIE['eGW_cookie_test'] !== 'enabled')
{
egw_session::egw_setcookie('eGW_cookie_test','enabled',0);
}
#print 'LANG:' . $GLOBALS['egw_info']['user']['preferences']['common']['lang'] . '<br>';
translation::init(); // this will set the language according to the (new) set prefs
translation::add_app('login');
translation::add_app('loginscreen');
$GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
{
translation::add_app('loginscreen','en'); // trying the en one
$GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
{
translation::add_app('loginscreen','en'); // trying the en one
$GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
}
if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
{
// remove the global var since the lang loginscreen message and its fallback (en) is empty or not set
unset($GLOBALS['loginscreenmessage']);
}
}
if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
{
// remove the global var since the lang loginscreen message and its fallback (en) is empty or not set
unset($GLOBALS['loginscreenmessage']);
}
foreach($_GET as $name => $value)
@ -424,5 +446,5 @@ else
$extra_vars = '?' . substr($extra_vars,1);
}
$GLOBALS['egw']->framework->login_screen($extra_vars);
$GLOBALS['egw']->framework->login_screen($extra_vars, $force_password_change);
}

View File

@ -59,19 +59,19 @@ class auth
* check if users are supposed to change their password every x sdays, then check if password is of old age
* or the devil-admin reset the users password and forced the user to change his password on next login.
*
* @param string $app to know where you are/ or where you want to go
* @param string $class to know where you are/ or where you want to go
* @param string $method to know where you are/ or where you want to go
* @return boolean true if check determined, that you passed the test, otherwise void, as we get redirected
* @param string& $message =null on return false: message why password needs to be changed
* @return boolean true: all good, false: password change required, null: password expires in N days
*/
static function check_password_age($app='', $class='', $method='')
static function check_password_change(&$message=null)
{
// dont check anything for anonymous sessions/ users that are flagged as anonymous
if (is_object($GLOBALS['egw']->session) && $GLOBALS['egw']->session->session_flags == 'A') return true;
// some statics (and initialisation to make information and timecalculation a) more readable in conditions b) persistent per request
// if user has to be warned about an upcomming passwordchange, remember for the session, that he was informed
static $UserKnowsAboutPwdChange=null;
if (is_null($UserKnowsAboutPwdChange)) $UserKnowsAboutPwdChange =& egw_cache::getSession('phpgwapi','auth_UserKnowsAboutPwdChange');
// retrieve the timestamp regarding the last change of the password from auth system and store it with the session
static $alpwchange_val=null;
static $pwdTsChecked=null;
@ -87,7 +87,7 @@ class auth
// on the other side, if your auth system does not require an forcedPasswordChange, you will not be asked.
if (method_exists($backend,'getLastPwdChange'))
{
$alpwchange_val = $backend->getLastPwdChange($GLOBALS['egw_info']['user']['account_lid']);
$alpwchange_val = $backend->getLastPwdChange($GLOBALS['egw']->session->account_lid);
$pwdTsChecked = true;
}
// if your authsystem does not provide that information, its likely, that you cannot change your password there,
@ -101,19 +101,13 @@ class auth
}
static $passwordAgeBorder=null;
static $daysLeftUntilChangeReq=null;
// some debug output and develop options to move the horizons and warn levels around
//$GLOBALS['egw_info']['server']['change_pwd_every_x_days'] =35;
//$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change']=5;
//echo egw_time::to('now','ts').'<br>';
//echo "User changed password at:".egw_time::to($GLOBALS['egw_info']['user'][$alpwchange]).'<br>';
//echo "User password is ".((egw_time::to('now','ts')-$GLOBALS['egw_info']['user'][$alpwchange])/86400)." days old<br>";
//echo "Users must change passwords every ".$GLOBALS['egw_info']['server']['change_pwd_every_x_days'].' days ('.($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400).') seconds.<br>';
//error_log(__METHOD__.__LINE__.'#'.$alpwchange_val.'# is null:'.is_null($alpwchange_val).'# is empty:'.empty($alpwchange_val).'# is set:'.isset($alpwchange_val));
//echo egw_time::to('now','ts')-($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400).'<br>';
// if neither timestamp isset return true, nothing to do (exept this means the password is too old)
if (is_null($alpwchange_val) &&
empty($GLOBALS['egw_info']['server']['change_pwd_every_x_days'])
) return true;
empty($GLOBALS['egw_info']['server']['change_pwd_every_x_days']))
{
return true;
}
if (is_null($passwordAgeBorder) && $GLOBALS['egw_info']['server']['change_pwd_every_x_days'])
{
$passwordAgeBorder = (egw_time::to('now','ts')-($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400));
@ -123,60 +117,55 @@ class auth
// maxage - passwordage = days left until change is required
$daysLeftUntilChangeReq = ($GLOBALS['egw_info']['server']['change_pwd_every_x_days'] - ((egw_time::to('now','ts')-($alpwchange_val?$alpwchange_val:0))/86400));
}
//echo "Warn about the upcomming change ".$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'].' days before that time is reached<br>';
//$result = $GLOBALS['egw_info']['server']['change_pwd_every_x_days'] - $daysLeftUntilChangeReq;
//echo $GLOBALS['egw_info']['server']['change_pwd_every_x_days'].' - '.$daysLeftUntilChangeReq.'='. $result.'<br>';
if (!($app == 'preferences' && $class == 'preferences_password' && $method == 'change') &&
(
($GLOBALS['egw_info']['server']['change_pwd_every_x_days'] &&
($GLOBALS['egw_info']['user']['apps']['preferences'] || $GLOBALS['egw_info']['user']['apps']['password']) &&
(
($passwordAgeBorder > $alpwchange_val) ||
(
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq
)
)
) || $alpwchange_val==0
)
)
if ($alpwchange_val == 0 || // admin requested password change
$passwordAgeBorder > $alpwchange_val || // change password every N days policy requests change
// user should be warned N days in advance about change and is not yet
$GLOBALS['egw_info']['server']['change_pwd_every_x_days'] &&
$GLOBALS['egw_info']['user']['apps']['preferences'] &&
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq &&
$UserKnowsAboutPwdChange !== true)
{
if ($GLOBALS['egw']->acl->check('nopasswordchange', 1, 'preferences')) return true; // user has no rights to change password
if ($UserKnowsAboutPwdChange === true && !($passwordAgeBorder > $alpwchange_val || $alpwchange_val==0)) return true; // user has already been informed about the upcomming password expiration
if (!is_null($alpwchange_val))
if ($alpwchange_val == 0)
{
if ($alpwchange_val == 0)
{
$message = lang('an admin required that you must change your password upon login.');
}
elseif (($passwordAgeBorder < $alpwchange_val) ||
(
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq &&
$daysLeftUntilChangeReq > 0
)
)
$message = lang('An admin required that you must change your password upon login.');
}
elseif ($passwordAgeBorder > $alpwchange_val && $alpwchange_val > 0)
{
error_log(__METHOD__.' Password of '.$GLOBALS['egw_info']['user']['account_lid'].' ('.$GLOBALS['egw_info']['user']['account_fullname'].') is of old age.'.array2string(array(
'ts'=> $alpwchange_val,
'date'=>egw_time::to($alpwchange_val))));
$message = lang('It has been more then %1 days since you changed your password',$GLOBALS['egw_info']['server']['change_pwd_every_x_days']);
}
else
{
// login page does not inform user about passwords about to expire
if ($GLOBALS['egw_info']['flags']['currentapp'] != 'login' &&
($GLOBALS['egw_info']['flags']['currentapp'] != 'home' ||
strpos($_SERVER['SCRIPT_NAME'], '/home/') !== false))
{
$UserKnowsAboutPwdChange = true;
$message = lang('your password is about to expire in %1 days, you may change your password now',round($daysLeftUntilChangeReq));
}
elseif ($passwordAgeBorder > $alpwchange_val && $alpwchange_val > 0)
{
error_log(__METHOD__.' Password of '.$GLOBALS['egw_info']['user']['account_lid'].' ('.$GLOBALS['egw_info']['user']['account_fullname'].') is of old age.'.array2string(array(
'ts'=> $alpwchange_val,
'date'=>egw_time::to($alpwchange_val))));
$message = lang('it has been more then %1 days since you changed your password',$GLOBALS['egw_info']['server']['change_pwd_every_x_days']);
}
egw::redirect_link('/index.php',array(
'menuaction' => 'preferences.preferences_password.change',
'message' => $message,
'nopopup' => true,
));
$message = lang('Your password is about to expire in %1 days, you may change your password now',round($daysLeftUntilChangeReq));
// user has no rights to change password --> do NOT warn, as only forced check ignores rights
if ($GLOBALS['egw']->acl->check('nopasswordchange', 1, 'preferences')) return true;
return null;
}
return false;
}
return true;
}
/**
* Retired password check method called all over the place
*
* @deprecated use check_password_change
*/
static function check_password_age()
{
return true; // no change
}
/**
* fetch the last pwd change for the user
*
@ -234,7 +223,7 @@ class auth
}
if (($ret = $this->backend->change_password($old_passwd, $new_passwd, $account_id)))
{
if ($account_id == $GLOBALS['egw_info']['user']['account_id'])
if ($account_id == $GLOBALS['egw']->session->account_id)
{
// need to change current users password in session
egw_cache::setSession('phpgwapi', 'password', base64_encode($new_passwd));

View File

@ -200,7 +200,7 @@ class auth_sql implements auth_backend
{
$admin = True;
// Don't allow password changes for other accounts when using XML-RPC
if(!$account_id || $GLOBALS['egw_info']['flags']['currentapp'] == 'login')
if(!$account_id)
{
$admin = False;
$account_id = $GLOBALS['egw_info']['user']['account_id'];

View File

@ -572,11 +572,12 @@ abstract class egw_framework
abstract function footer();
/**
* displays a login screen
*
* @param string $extra_vars for login url
* Displays the login screen
*
* @param string $extra_vars for login url
* @param string $change_passwd =null string with message to render input fields for password change
*/
function login_screen($extra_vars)
function login_screen($extra_vars, $change_passwd=null)
{
self::csp_frame_src_attrs(array()); // array() no external frame-sources
@ -587,8 +588,32 @@ abstract class egw_framework
$tmpl->set_var('lang_message',$GLOBALS['loginscreenmessage']);
$last_loginid = $_COOKIE['last_loginid'];
// hide change-password fields, if not requested
if (!$change_passwd)
{
$tmpl->set_block('login_form','change_password');
$tmpl->set_var('change_password', '');
$tmpl->set_var('lang_password',lang('password'));
$tmpl->set_var('cd',check_logoutcode($_GET['cd']));
$tmpl->set_var('cd_class', isset($_GET['cd']) && $_GET['cd'] != 1 ? 'error' : '');
$last_loginid = $_COOKIE['last_loginid'];
$last_domain = $_COOKIE['last_domain'];
$tmpl->set_var('passwd', '');
$tmpl->set_var('autofocus_login', 'autofocus');
}
else
{
$tmpl->set_var('lang_password',lang('Old password'));
$tmpl->set_var('lang_new_password',lang('New password'));
$tmpl->set_var('lang_repeat_password',lang('Repeat password'));
$tmpl->set_var('cd', $change_passwd);
$tmpl->set_var('cd_class', 'error');
$last_loginid = $_POST['login'];
$last_domain = $_POST['domain'];
$tmpl->set_var('passwd', $_POST['passwd']);
$tmpl->set_var('autofocus_login', '');
$tmpl->set_var('autofocus_new_passwd', 'autofocus');
}
if($GLOBALS['egw_info']['server']['show_domain_selectbox'])
{
foreach(array_keys($GLOBALS['egw_domain']) as $domain)
@ -597,7 +622,7 @@ abstract class egw_framework
}
$tmpl->set_var(array(
'lang_domain' => lang('domain'),
'select_domain' => html::select('logindomain',$_COOKIE['last_domain'],$domains,true,'tabindex="2"',0,false),
'select_domain' => html::select('logindomain',$last_domain,$domains,true,'tabindex="2"',0,false),
));
}
else
@ -612,9 +637,9 @@ abstract class egw_framework
reset($GLOBALS['egw_domain']);
list($default_domain) = each($GLOBALS['egw_domain']);
if($_COOKIE['last_domain'] != $default_domain && !empty($_COOKIE['last_domain']))
if(!empty ($last_domain) && $last_domain != $default_domain)
{
$last_loginid .= '@' . $_COOKIE['last_domain'];
$last_loginid .= '@' . $last_domain;
}
}
}
@ -654,12 +679,10 @@ abstract class egw_framework
}
$tmpl->set_var('login_url', $GLOBALS['egw_info']['server']['webserver_url'] . '/login.php' . $extra_vars);
$tmpl->set_var('version',$GLOBALS['egw_info']['server']['versions']['phpgwapi']);
$tmpl->set_var('cd',check_logoutcode($_GET['cd']));
$tmpl->set_var('cookie',$last_loginid);
$tmpl->set_var('version', $GLOBALS['egw_info']['server']['versions']['phpgwapi']);
$tmpl->set_var('login', $last_loginid);
$tmpl->set_var('lang_username',lang('username'));
$tmpl->set_var('lang_password',lang('password'));
$tmpl->set_var('lang_login',lang('login'));
$tmpl->set_var('website_title', $GLOBALS['egw_info']['server']['site_title']);
@ -825,6 +848,14 @@ abstract class egw_framework
*/
protected function _get_header(array $extra=array())
{
// display password expires in N days message once per session
$message = null;
if ($GLOBALS['egw_info']['flags']['currentapp'] != 'login' &&
auth::check_password_change($message) !== true)
{
self::message($message, 'info');
}
// get used language code (with a little xss check, if someone tries to sneak something in)
if (preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$GLOBALS['egw_info']['user']['preferences']['common']['lang']))
{

View File

@ -166,6 +166,24 @@ class egw_session
*/
var $required_files;
/**
* Nummeric code why session creation failed
*
* @var int
*/
var $cd_reason;
const CD_BAD_LOGIN_OR_PASSWORD = 5;
const CD_FORCE_PASSWORD_CHANGE = 97;
const CD_ACCOUNT_EXPIRED = 98;
const CD_BLOCKED = 99; // to many failed attempts to loing
/**
* Verbose reason why session creation failed
*
* @var string
*/
var $reason;
/**
* Constructor just loads up some defaults from cookies
*
@ -422,9 +440,10 @@ class egw_session
* @param string $passwd_type type of password being used, ie plaintext, md5, sha1
* @param boolean $no_session =false dont create a real session, eg. for GroupDAV clients using only basic auth, no cookie support
* @param boolean $auth_check =true if false, the user is loged in without checking his password (eg. for single sign on), default = true
* @param boolean $fail_on_forced_password_change =false true: do NOT create session, if password change requested
* @return string session id
*/
function create($login,$passwd = '',$passwd_type = '',$no_session=false,$auth_check=true)
function create($login,$passwd = '',$passwd_type = '',$no_session=false,$auth_check=true,$fail_on_forced_password_change=false)
{
if (is_array($login))
{
@ -492,7 +511,7 @@ class egw_session
$this->account_id && $GLOBALS['egw']->accounts->get_type($this->account_id) == 'g')
{
$this->reason = $blocked ? 'blocked, too many attempts' : 'bad login or password';
$this->cd_reason = $blocked ? 99 : 5;
$this->cd_reason = $blocked ? self::CD_BLOCKED : self::CD_BAD_LOGIN_OR_PASSWORD;
// we dont log anon users as it would block the website
if (!$GLOBALS['egw']->acl->get_specific_rights_for_account($this->account_id,'anonymous','phpgwapi'))
@ -502,6 +521,11 @@ class egw_session
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check) UNSUCCESSFULL ($this->reason)");
return false;
}
if ($fail_on_forced_password_change && auth::check_password_change($this->reason) === false)
{
$this->cd_reason = self::CD_FORCE_PASSWORD_CHANGE;
return false;
}
if (!$this->account_id && $GLOBALS['egw_info']['server']['auto_create_acct'])
{
if ($GLOBALS['egw_info']['server']['auto_create_acct'] == 'lowercase')
@ -543,7 +567,7 @@ class egw_session
if ($GLOBALS['egw']->accounts->is_expired($GLOBALS['egw_info']['user']))
{
$this->reason = 'account is expired';
$this->cd_reason = 98;
$this->cd_reason = self::CD_ACCOUNT_EXPIRED;
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check) UNSUCCESSFULL ($this->reason)");
return false;

View File

@ -70,7 +70,7 @@ alphabet common de a,ä,b,c,d,e,f,g,h,i,j,k,l,m,n,o,ö,p,q,r,s,t,u,ü,v,w,x,y,z
alt common de Alt
alternate style-sheet: common de Alternatives Style-sheet
american samoa common de AMERICANISCH SAMOA
an admin required that you must change your password upon login. common de Sie werden hiermit aufgefordert Ihr Passwort zu ändern. (Dies wurde von einem Administrator veranlasst.)
an admin required that you must change your password upon login. common de Sie werden hiermit aufgefordert Ihr Passwort zu ändern. Dies wurde von einem Administrator veranlasst.
an error happened common de Ein Fehler ist aufgetreten.
an existing and by the webserver readable directory enables the image browser and upload. common de Ein existierendes, und vom Webserver lesbares Verzeichnis, schaltet den Bild Browser und Upload ein.
and common de und
@ -940,7 +940,7 @@ your message has been sent common de Ihre Nachricht wurde versendet
your password does not have required strength of %1 character classes and minimum length of %2 characters. common de Ihr Passwort hat nicht die benötigte Qualität von %1 Zeichenklassen und Mindestanzahl von %2 Zeichen.
your password does not have required strength: common de Ihr Passwort hat nicht die erforderliche Stärke:
your password failed the following criteria: common de Ihr Passwort entspricht nicht den folgenden Kriterien:
your password is about to expire in %1 days, you may change your password now common de Ihr Passwort läuft in %1 Tagen ab. Sie können nun hier Ihr Passwort ändern, oder warten bis Sie es ändern müssen.
your password is about to expire in %1 days, you may change your password now common de Ihr Passwort läuft in %1 Tagen ab. Sie können jetzt Ihr Passwort ändern, oder warten bis Sie es ändern müssen.
your password might not match the password policy. common de Ihr Passwort könnte den Richtlinien nicht entsprechen.
your search returned %1 matchs common de Ihre Suche ergab %1 Treffer
your search returned 1 match common de Ihre Suche ergab einen Treffer

View File

@ -5,12 +5,16 @@
</div>
<div id="centerBox">
<div id="loginScreenMessage">{lang_message}</div>
<div id="loginCdMessage">{cd}</div>
<form name="login_form" method="post" action="{login_url}">
<table class="divLoginbox divSideboxEntry" cellspacing="0" cellpadding="2" border="0" align="center">
<tr class="divLoginboxHeader">
<td colspan="3">{website_title}</td>
</tr>
<tr>
<td colspan="3">
<div id="loginCdMessage" class="{cd_class}">{cd}</div>
</td>
</tr>
<tr>
<td colspan="2" height="20">
<input type="hidden" name="passwd_type" value="text" />
@ -40,16 +44,26 @@
<!-- END remember_me_selection -->
<tr>
<td align="right">{lang_username}:&nbsp;</td>
<td><input name="login" tabindex="4" value="{cookie}" size="30" autofocus /></td>
<td><input name="login" tabindex="4" value="{login}" size="30" autofocus /></td>
</tr>
<tr>
<td align="right">{lang_password}:&nbsp;</td>
<td><input name="passwd" tabindex="5" type="password" size="30" /></td>
<td><input name="passwd" tabindex="5" value="{passwd}" type="password" size="30" /></td>
</tr>
<!-- BEGIN change_password -->
<tr>
<td align="right">{lang_new_password}:&nbsp;</td>
<td><input name="new_passwd" tabindex="6" type="password" size="30" /></td>
</tr>
<tr>
<td align="right">{lang_repeat_password}:&nbsp;</td>
<td><input name="new_passwd2" tabindex="7" type="password" size="30" /></td>
</tr>
<!-- END change_password -->
<tr>
<td>&nbsp;</td>
<td>
<input tabindex="6" type="submit" value=" {lang_login} " name="submitit" />
<input tabindex="8" type="submit" value=" {lang_login} " name="submitit" />
</td>
</tr>
<!-- BEGIN registration -->

View File

@ -201,7 +201,7 @@ input[type=image]
.divLoginbox
{
position:relative;
width: 370px;
width: 400px;
border: #9c9c9c 1px solid;
}
@ -483,6 +483,7 @@ body {
padding-bottom: 10px;
color: red;
font-style: italic;
margin: 7px 7px 0 0;
}
.divLoginboxHeader {
text-align: center;

View File

@ -2275,14 +2275,11 @@ body {
border-top-left-radius: 10px;
color: red;
text-align: center;
padding-top: 1em;
padding: 1em;
white-space: pre-wrap;
}
#loginMainDiv div#centerBox #loginCdMessage span {
padding: 0.5em;
font-size: 1.2em;
color: #189800;
text-shadow: -1px -1px 0px #101010, 1px 1px 0px #505050;
width: 100%;
#loginMainDiv div#centerBox #loginCdMessage.error {
font-weight: bold;
}
#loginMainDiv div#centerBox form {
margin: 1em;

View File

@ -61,7 +61,7 @@ class pixelegg_framework extends jdots_framework
}
return parent::header($extra);
}
/**
* Make given color lighter or darker by percentage
*
@ -78,7 +78,7 @@ class pixelegg_framework extends jdots_framework
$R = round($R * (100 + $percent) / 100);
$G = round($G * (100 + $percent) / 100);
$B = round($B * (100 + $percent) / 100);
$R = ($R<255)?$R:255;
$G = ($G<255)?$G:255;
$B = ($B<255)?$B:255;
@ -89,7 +89,7 @@ class pixelegg_framework extends jdots_framework
return '#'.$RR.$GG.$BB;
}
/**
* Overwrite to NOT add customizable colors from jDots
*
@ -104,12 +104,12 @@ class pixelegg_framework extends jdots_framework
$GLOBALS['egw_info']['user']['preferences']['common']['template_color']);
//The hex value of the color
$color_hex = ltrim($color, '#');
// Create a drak variant of the color
$color_hex_dark = $this->_color_shader($color_hex, 15);
// Create a draker variant of the color
$color_hex_darker = $this->_color_shader($color_hex, -30);
if (preg_match('/^(#[0-9A-F]+|[A-Z]+)$/i',$color)) // a little xss check
{
$ret['app_css'] = "
@ -163,8 +163,9 @@ div#egw_fw_header, div.egw_fw_ui_category:hover,#loginMainDiv,#loginMainDiv #div
* Reimplemented to remove site_title from login box and display it as loginscreenmessage, if none set.
*
* @param string $extra_vars for login url
* @param string $change_passwd =null string with message to render input fields for password change
*/
function login_screen($extra_vars)
function login_screen($extra_vars, $change_passwd=null)
{
if (empty($GLOBALS['loginscreenmessage']))
{
@ -172,6 +173,6 @@ div#egw_fw_header, div.egw_fw_ui_category:hover,#loginMainDiv,#loginMainDiv #div
}
unset($GLOBALS['egw_info']['server']['site_title']);
return parent::login_screen($extra_vars);
return parent::login_screen($extra_vars, $change_passwd);
}
}

View File

@ -94,23 +94,16 @@
// Message
#loginCdMessage{
margin: 1em;
.border_radius_button_lefttop;
color: red;
text-align: center;
padding-top: 1em;
// Text der Meldung
span {
padding: 0.5em;
font-size: 1.2em;
// .background-color-hint;
color: @color_hint;
text-shadow: -1px -1px 0px #101010, 1px 1px 0px #505050;
width: 100%;
}
margin: 1em;
.border_radius_button_lefttop;
color: red;
text-align: center;
padding: 1em;
white-space: pre-wrap;
}
#loginCdMessage.error {
font-weight: bold;
}

View File

@ -8,7 +8,7 @@
</div>
<div id="centerBox">
<div id="loginScreenMessage">{lang_message}</div>
<div id="loginCdMessage">{cd}</div>
<div id="loginCdMessage" class="{cd_class}">{cd}</div>
<form name="login_form" method="post" action="{login_url}">
<table class="divLoginbox divSideboxEntry" cellspacing="0" cellpadding="2" border="0" align="center">
<tr class="divLoginboxHeader">
@ -43,16 +43,26 @@
<!-- END remember_me_selection -->
<tr>
<td align="right">{lang_username}:&nbsp;</td>
<td><input name="login" tabindex="4" value="{cookie}" size="30" autofocus/></td>
<td><input name="login" tabindex="4" value="{login}" size="30" {autofocus_login}/></td>
</tr>
<tr>
<td align="right">{lang_password}:&nbsp;</td>
<td><input name="passwd" tabindex="5" type="password" size="30" /></td>
<td><input name="passwd" tabindex="5" value="{passwd}" type="password" size="30" /></td>
</tr>
<!-- BEGIN change_password -->
<tr>
<td align="right">{lang_new_password}:&nbsp;</td>
<td><input name="new_passwd" tabindex="6" type="password" size="30" {autofocus_new_passwd}/></td>
</tr>
<tr>
<td align="right">{lang_repeat_password}:&nbsp;</td>
<td><input name="new_passwd2" tabindex="7" type="password" size="30" /></td>
</tr>
<!-- END change_password -->
<tr>
<td>&nbsp;</td>
<td>
<input tabindex="6" type="submit" value=" {lang_login} " name="submitit" />
<input tabindex="8" type="submit" value=" {lang_login} " name="submitit" />
</td>
</tr>
<!-- BEGIN registration -->

View File

@ -27,7 +27,7 @@ class preferences_password
{
egw_framework::window_close('There was no password change!');
}
if (!is_array($content))
{
$content= array();
@ -36,43 +36,8 @@ class preferences_password
{
if ($content['button']['change'])
{
$o_passwd = $GLOBALS['egw_info']['user']['passwd'];
if($o_passwd != $content['o_passwd_2'])
if (($errors = self::do_change($content['o_passwd_2'], $content['n_passwd'], $content['n_passwd_2'])))
{
$errors[] = lang('The old password is not correct');
}
if($content['n_passwd'] != $content['n_passwd_2'])
{
$errors[] = lang('The two passwords are not the same');
}
if($o_passwd == $content['n_passwd'])
{
$errors[] = lang('Old password and new password are the same. This is invalid. You must enter a new password');
}
if(!$content['n_passwd'])
{
$errors[] = lang('You must enter a password');
}
// allow auth backends or configured password strenght to throw exceptions and display there message
if (!$errors)
{
try {
$passwd_changed = $GLOBALS['egw']->auth->change_password($o_passwd, $content['n_passwd'],
$GLOBALS['egw_info']['user']['account_id']);
}
catch (Exception $e) {
$errors[] = $e->getMessage();
}
}
if(!$passwd_changed)
{
if (!$errors) // if we have no specific error, add general message
{
$errors[] = lang('Failed to change password.');
}
egw_framework::message(implode("\n", $errors), 'error');
$content = array();
}
@ -81,7 +46,6 @@ class preferences_password
egw_framework::refresh_opener(lang('Password changed'), 'preferences');
egw_framework::window_close();
}
}
}
@ -90,4 +54,58 @@ class preferences_password
$tmpl->exec('preferences.preferences_password.change', $content,array(),array(),array(),2);
}
/**
* Do some basic checks and then change password
*
* @param string $old_passwd
* @param string $new_passwd
* @param string $new_passwd2
* @return array with already translated errors
*/
public static function do_change($old_passwd, $new_passwd, $new_passwd2)
{
if ($GLOBALS['egw_info']['flags']['currentapp'] != 'preferences')
{
translation::add_app('preferences');
}
$errors = array();
if (isset($GLOBALS['egw_info']['user']['passwd']) &&
$old_passwd !== $GLOBALS['egw_info']['user']['passwd'])
{
$errors[] = lang('The old password is not correct');
}
if ($new_passwd != $new_passwd2)
{
$errors[] = lang('The two passwords are not the same');
}
if ($old_passwd !== false && $old_passwd == $new_passwd)
{
$errors[] = lang('Old password and new password are the same. This is invalid. You must enter a new password');
}
if (!$new_passwd)
{
$errors[] = lang('You must enter a password');
}
// allow auth backends or configured password strenght to throw exceptions and display there message
if (!$errors)
{
try {
if (!$GLOBALS['egw']->auth->change_password($old_passwd, $new_passwd,
$GLOBALS['egw']->session->account_id))
{
// if we have no specific error, add general message
$errors[] = lang('Failed to change password.');
}
}
catch (Exception $e) {
$errors[] = $e->getMessage();
}
}
return $errors;
}
}