mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-23 07:09:20 +01:00
* 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:
parent
55248b0d18
commit
058ef3e89f
@ -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)
|
||||
|
@ -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
112
login.php
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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'];
|
||||
|
@ -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']))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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}: </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}: </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}: </td>
|
||||
<td><input name="new_passwd" tabindex="6" type="password" size="30" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">{lang_repeat_password}: </td>
|
||||
<td><input name="new_passwd2" tabindex="7" type="password" size="30" /></td>
|
||||
</tr>
|
||||
<!-- END change_password -->
|
||||
<tr>
|
||||
<td> </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 -->
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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}: </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}: </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}: </td>
|
||||
<td><input name="new_passwd" tabindex="6" type="password" size="30" {autofocus_new_passwd}/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">{lang_repeat_password}: </td>
|
||||
<td><input name="new_passwd2" tabindex="7" type="password" size="30" /></td>
|
||||
</tr>
|
||||
<!-- END change_password -->
|
||||
<tr>
|
||||
<td> </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 -->
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user