diff --git a/admin/inc/class.admin_account.inc.php b/admin/inc/class.admin_account.inc.php index 913e7f0e3d..5e56c68749 100644 --- a/admin/inc/class.admin_account.inc.php +++ b/admin/inc/class.admin_account.inc.php @@ -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) diff --git a/etemplate/templates/default/etemplate2.css b/etemplate/templates/default/etemplate2.css index c64e6a448b..9f481f2b40 100644 --- a/etemplate/templates/default/etemplate2.css +++ b/etemplate/templates/default/etemplate2.css @@ -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 { diff --git a/login.php b/login.php index e1934232e4..969ed78d89 100755 --- a/login.php +++ b/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'] . '
'; - 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'] . '
'; + 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); } diff --git a/phpgwapi/inc/class.auth.inc.php b/phpgwapi/inc/class.auth.inc.php index d1044789e8..e10ea2251c 100644 --- a/phpgwapi/inc/class.auth.inc.php +++ b/phpgwapi/inc/class.auth.inc.php @@ -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').'
'; - //echo "User changed password at:".egw_time::to($GLOBALS['egw_info']['user'][$alpwchange]).'
'; - //echo "User password is ".((egw_time::to('now','ts')-$GLOBALS['egw_info']['user'][$alpwchange])/86400)." days old
"; - //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.
'; - //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).'
'; + // 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
'; - //$result = $GLOBALS['egw_info']['server']['change_pwd_every_x_days'] - $daysLeftUntilChangeReq; - //echo $GLOBALS['egw_info']['server']['change_pwd_every_x_days'].' - '.$daysLeftUntilChangeReq.'='. $result.'
'; - 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)); diff --git a/phpgwapi/inc/class.auth_sql.inc.php b/phpgwapi/inc/class.auth_sql.inc.php index 288b1b537a..695cd08313 100644 --- a/phpgwapi/inc/class.auth_sql.inc.php +++ b/phpgwapi/inc/class.auth_sql.inc.php @@ -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']; diff --git a/phpgwapi/inc/class.egw_framework.inc.php b/phpgwapi/inc/class.egw_framework.inc.php index 1477587096..730450f89e 100644 --- a/phpgwapi/inc/class.egw_framework.inc.php +++ b/phpgwapi/inc/class.egw_framework.inc.php @@ -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'])) { diff --git a/phpgwapi/inc/class.egw_session.inc.php b/phpgwapi/inc/class.egw_session.inc.php index 5449be0914..1cab173efb 100644 --- a/phpgwapi/inc/class.egw_session.inc.php +++ b/phpgwapi/inc/class.egw_session.inc.php @@ -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; diff --git a/phpgwapi/lang/egw_de.lang b/phpgwapi/lang/egw_de.lang index d16dad7a1b..ccf087bb8b 100644 --- a/phpgwapi/lang/egw_de.lang +++ b/phpgwapi/lang/egw_de.lang @@ -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 diff --git a/phpgwapi/templates/default/login.tpl b/phpgwapi/templates/default/login.tpl index 3b40c26d41..723a8ae38f 100644 --- a/phpgwapi/templates/default/login.tpl +++ b/phpgwapi/templates/default/login.tpl @@ -5,12 +5,16 @@
{lang_message}
-
{cd}
+ + + - + - + + + + + + + + + + + diff --git a/phpgwapi/templates/idots/css/traditional.css b/phpgwapi/templates/idots/css/traditional.css index 327ee1970b..775a29fd7a 100755 --- a/phpgwapi/templates/idots/css/traditional.css +++ b/phpgwapi/templates/idots/css/traditional.css @@ -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; diff --git a/pixelegg/css/pixelegg.css b/pixelegg/css/pixelegg.css index 546a2cbc9a..61ef09fb45 100644 --- a/pixelegg/css/pixelegg.css +++ b/pixelegg/css/pixelegg.css @@ -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; diff --git a/pixelegg/inc/class.pixelegg_framework.inc.php b/pixelegg/inc/class.pixelegg_framework.inc.php index 77a6df04ee..a4c15a55e0 100755 --- a/pixelegg/inc/class.pixelegg_framework.inc.php +++ b/pixelegg/inc/class.pixelegg_framework.inc.php @@ -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); } } diff --git a/pixelegg/less/layout_loginPage.less b/pixelegg/less/layout_loginPage.less index ad45d598ce..358a7bc75f 100644 --- a/pixelegg/less/layout_loginPage.less +++ b/pixelegg/less/layout_loginPage.less @@ -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; + } diff --git a/pixelegg/login.tpl b/pixelegg/login.tpl index fafe8b6ac4..68940b5352 100644 --- a/pixelegg/login.tpl +++ b/pixelegg/login.tpl @@ -8,7 +8,7 @@
{lang_message}
-
{cd}
+
{cd}
{website_title}
+
{cd}
+
@@ -40,16 +44,26 @@
{lang_username}: 
{lang_password}: 
{lang_new_password}: 
{lang_repeat_password}: 
  - +
@@ -43,16 +43,26 @@ - + - + + + + + + + + + + + diff --git a/preferences/inc/class.preferences_password.inc.php b/preferences/inc/class.preferences_password.inc.php index 36bdae790a..12c3986234 100644 --- a/preferences/inc/class.preferences_password.inc.php +++ b/preferences/inc/class.preferences_password.inc.php @@ -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; + } }
{lang_username}: 
{lang_password}: 
{lang_new_password}: 
{lang_repeat_password}: 
  - +