diff --git a/4dev/update/20140822_edit_update/edit_tables.sql b/4dev/update/20140822_edit_update/edit_tables.sql new file mode 100644 index 00000000..6189c2a0 --- /dev/null +++ b/4dev/update/20140822_edit_update/edit_tables.sql @@ -0,0 +1,10 @@ +-- update edit tables +-- add login error count and last login error + +-- count login errors +ALTER TABLE edit_user ADD login_error_count INT DEFAULT 0; +-- last login error date +ALTER TABLE edit_user ADD login_error_date TIMESTAMP WITHOUT TIME ZONE; +-- if this is set to true, this user gets locked after max login errors are reached +ALTER TABLE edit_user ADD strict SMALLINT DEFAULT 0; +ALTER TABLE edit_user ADD locked SMALLINT DEFAULT 0; diff --git a/www/admin/edit_base.inc b/www/admin/edit_base.inc index 60c2e874..252772bb 100644 --- a/www/admin/edit_base.inc +++ b/www/admin/edit_base.inc @@ -222,12 +222,16 @@ switch ($form->my_page_name) { case "edit_users": + $elements[] = $form->form_create_element("login_error_count"); + $elements[] = $form->form_create_element("login_error_date"); $elements[] = $form->form_create_element("enabled"); $elements[] = $form->form_create_element("username"); $elements[] = $form->form_create_element("password"); $elements[] = $form->form_create_element("email"); $elements[] = $form->form_create_element("edit_group_id"); $elements[] = $form->form_create_element("edit_access_right_id"); + $elements[] = $form->form_create_element("strict"); + $elements[] = $form->form_create_element("locked"); $elements[] = $form->form_create_element("admin"); $elements[] = $form->form_create_element("debug"); $elements[] = $form->form_create_element("db_debug"); diff --git a/www/admin/table_arrays/array_edit_users.inc b/www/admin/table_arrays/array_edit_users.inc index d80efa47..d82a6f87 100644 --- a/www/admin/table_arrays/array_edit_users.inc +++ b/www/admin/table_arrays/array_edit_users.inc @@ -32,6 +32,26 @@ "0" => "No" ) ), + "strict" => array ( + "value" => $GLOBALS["strict"], + "output_name" => "Strict (Lock after errors)", + "type" => "binary", + "int" => 1, + "element_list" => array ( + "1" => "Yes", + "0" => "No" + ) + ), + "locked" => array ( + "value" => $GLOBALS["locked"], + "output_name" => "Locked (auto set if strict with errors)", + "type" => "binary", + "int" => 1, + "element_list" => array ( + "1" => "Yes", + "0" => "No" + ) + ), "admin" => array ( "value" => $GLOBALS["admin"], "output_name" => "Admin", @@ -98,12 +118,25 @@ "type" => "drop_down_db", "query" => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level" ), + "login_error_count" => array ( + "output_name" => "Login error count", + "value" => $GLOBALS['login_error_count'], + "type" => "view", + "empty" => "0" + ), + "login_error_date" => array ( + "output_name" => "Last login error", + "value" => $GLOBALS['login_error_date'], + "type" => "view", + "empty" => "-" + ), + // planned delete lock flag "protected" => array ( "value" => $GLOBALS["protected"], "int" => 1 ) ), - "load_query" => "SELECT edit_user_id, username, enabled, debug, db_debug FROM edit_user ORDER BY username", + "load_query" => "SELECT edit_user_id, username, enabled, debug, db_debug, strict, locked, login_error_count FROM edit_user ORDER BY username", "table_name" => "edit_user", "show_fields" => array ( array ( @@ -124,6 +157,20 @@ "binary" => array("Yes", "No"), "before_value" => "DB Debug: " ), + array ( + "name" => "strict", + "binary" => array("Yes", "No"), + "before_value" => "Strict: " + ), + array ( + "name" => "locked", + "binary" => array("Yes", "No"), + "before_value" => "Locked: " + ), + array ( + "name" => "login_error_count", + "before_value" => "Errors: " + ) ), "element_list" => array ( "edit_access_user" => array ( diff --git a/www/layout/admin/default/templates/edit_elements.tpl b/www/layout/admin/default/templates/edit_elements.tpl index 09e377a4..fd61e1a1 100644 --- a/www/layout/admin/default/templates/edit_elements.tpl +++ b/www/layout/admin/default/templates/edit_elements.tpl @@ -14,6 +14,9 @@ {* here is depending on type the content data *} + {if $element.type == 'view'} + {$element.data.value} + {/if} {if $element.type == 'binary' || $element.type == 'radio_array'} {html_radios values=$element.data.value output=$element.data.output name=$element.data.name selected=$element.data.checked separator=$element.data.separator} {/if} diff --git a/www/libs/Class.DB.Array.IO.inc b/www/libs/Class.DB.Array.IO.inc index 64172259..57e8e5c2 100644 --- a/www/libs/Class.DB.Array.IO.inc +++ b/www/libs/Class.DB.Array.IO.inc @@ -133,9 +133,9 @@ public function db_dump_array($write = 0) { reset($this->table_array); - while(list($spalte, $werte_array) = each($this->table_array)) + while(list($column, $data_array) = each($this->table_array)) { - $string .= "".$spalte." -> ".$werte_array["value"]."
"; + $string .= "".$column." -> ".$data_array["value"]."
"; } // add output to internal error_msg if ($write) @@ -184,12 +184,12 @@ public function db_reset_array($reset_pk = 0) { reset($this->table_array); - while(list($spalte, $werte_array) = each($this->table_array)) + while(list($column, $data_array) = each($this->table_array)) { - if (!$this->table_array[$spalte]["pk"]) - unset($this->table_array[$spalte]["value"]); + if (!$this->table_array[$column]["pk"]) + unset($this->table_array[$column]["value"]); else if ($reset_pk) - unset($this->table_array[$spalte]["value"]); + unset($this->table_array[$column]["value"]); } } @@ -208,27 +208,27 @@ $q .= $this->pk_name." = ".$this->table_array[$this->pk_name]["value"]." "; // delete files and build FK query reset($this->table_array); - while(list($spalte, $werte_array) = each($this->table_array)) + while(list($column, $data_array) = each($this->table_array)) { // suchen nach bildern und löschen ... - if ($this->table_array[$spalte]["file"] && file_exists($this->table_array[$spalte]["url"].$this->table_array[$spalte]["value"])) + if ($this->table_array[$column]["file"] && file_exists($this->table_array[$column]["url"].$this->table_array[$column]["value"])) { - if (file_exists($this->table_array[$spalte]["path"].$this->table_array[$spalte]["value"])) - unlink($this->table_array[$spalte]["path"].$this->table_array[$spalte]["value"]); - $dateiname = str_replace("_tn", "", $this->table_array[$spalte]["value"]); - if (file_exists($this->table_array[$spalte]["path"].$dateiname)) - unlink($this->table_array[$spalte]["path"].$dateiname); + if (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) + unlink($this->table_array[$column]["path"].$this->table_array[$column]["value"]); + $dateiname = str_replace("_tn", "", $this->table_array[$column]["value"]); + if (file_exists($this->table_array[$column]["path"].$dateiname)) + unlink($this->table_array[$column]["path"].$dateiname); } - if ($this->table_array[$spalte]["fk"]) + if ($this->table_array[$column]["fk"]) { // zusammenstellen der FKs if ($q_where) $q_where .= " AND "; - $q_where .= $spalte." = ".$this->table_array[$spalte]["value"]; + $q_where .= $column." = ".$this->table_array[$column]["value"]; } // allgemeines zurücksetzen des arrays - unset($this->table_array[$spalte]["value"]); + unset($this->table_array[$column]["value"]); } // attach fk row if there ... @@ -257,18 +257,18 @@ return $this->table_array; reset($this->table_array); // create select part & addition FK part - while (list($spalte, $werte_array)=each($this->table_array)) + while (list($column, $data_array)=each($this->table_array)) { if ($q_select) $q_select .= ", "; - $q_select .= $spalte; + $q_select .= $column; // check FK ... - if ($this->table_array[$spalte]["fk"] && $this->table_array[$spalte]["value"]) + if ($this->table_array[$column]["fk"] && $this->table_array[$column]["value"]) { if ($q_where) $q_where .= " AND "; - $q_where .= $spalte .= " = ".$this->table_array[$spalte]["value"]; + $q_where .= $column .= " = ".$this->table_array[$column]["value"]; } } @@ -285,23 +285,23 @@ if ($res = $this->db_fetch_array()) { reset($this->table_array); - while (list($spalte, $werte_array) = each($this->table_array)) + while (list($column, $data_array) = each($this->table_array)) { // wenn "edit" dann gib daten wie in DB zurück, ansonten aufbereiten für ausgabe // ?? sollte das nicht draußen ??? man weis ja net was da drin steht --> is noch zu überlegen -// echo "EDIT: $edit | Spalte: $spalte | type: ".$this->table_array[$spalte]["type"]." | Res: ".$res[$spalte]."
"; +// echo "EDIT: $edit | Spalte: $column | type: ".$this->table_array[$column]["type"]." | Res: ".$res[$column]."
"; if ($edit) { - $this->table_array[$spalte]["value"] = $res[$spalte]; + $this->table_array[$column]["value"] = $res[$column]; // if password, also write to hidden - if ($this->table_array[$spalte]["type"] == "password") + if ($this->table_array[$column]["type"] == "password") { - $this->table_array[$spalte]["HIDDEN_value"] = $res[$spalte]; + $this->table_array[$column]["HIDDEN_value"] = $res[$column]; } } else { - $this->table_array[$spalte]["value"] = $this->convert_data(nl2br($res[$spalte])); + $this->table_array[$column]["value"] = $this->convert_data(nl2br($res[$column])); // had to put out the htmlentities from the line above as it breaks japanese characters } } @@ -335,58 +335,58 @@ $insert = 0; reset ($this->table_array); - while (list($spalte, $werte_array) = each($this->table_array)) + while (list($column, $data_array) = each($this->table_array)) { /********************************* START FILE *************************************/ // file upload - if ($this->table_array[$spalte]["file"]) + if ($this->table_array[$column]["file"]) { // falls was im tmp drinnen, sprich ein upload, datei kopieren, Dateinamen in db schreiben // falls datei schon am server (physischer pfad), dann einfach url in db schreiben (update) // falls in "delete" "ja" dann loeschen (und gibts eh nur beim update) - if ($this->table_array[$spalte]["delete"]) + if ($this->table_array[$column]["delete"]) { - unset($this->table_array[$spalte]["delete"]); - if (file_exists($this->table_array[$spalte]["path"].$this->table_array[$spalte]["value"])) - unlink($this->table_array[$spalte]["path"].$this->table_array[$spalte]["value"]); - $dateiname = str_replace("_tn", "", $this->table_array[$spalte]["value"]); - if (file_exists($this->table_array[$spalte]["path"].$dateiname)) - unlink($this->table_array[$spalte]["path"].$dateiname); - $this->table_array[$spalte]["value"] = ""; + unset($this->table_array[$column]["delete"]); + if (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) + unlink($this->table_array[$column]["path"].$this->table_array[$column]["value"]); + $dateiname = str_replace("_tn", "", $this->table_array[$column]["value"]); + if (file_exists($this->table_array[$column]["path"].$dateiname)) + unlink($this->table_array[$column]["path"].$dateiname); + $this->table_array[$column]["value"] = ""; } else { - if ($this->table_array[$spalte]["tmp"] != "none" && $this->table_array[$spalte]["tmp"]) + if ($this->table_array[$column]["tmp"] != "none" && $this->table_array[$column]["tmp"]) { // Dateiname zusammenbasteln: org-name + _pkid liste + .ext - list($name, $ext) = explode(".",$this->table_array[$spalte]["dn"]); + list($name, $ext) = explode(".",$this->table_array[$column]["dn"]); // mozilla, patch - $fn_name = explode("/", $this->table_array[$spalte]["dn"]); - $this->table_array[$spalte]["dn"] = $fn_name[count($fn_name)-1]; - $filename_parts = explode(".", $this->table_array[$spalte]["dn"]); + $fn_name = explode("/", $this->table_array[$column]["dn"]); + $this->table_array[$column]["dn"] = $fn_name[count($fn_name)-1]; + $filename_parts = explode(".", $this->table_array[$column]["dn"]); $ext = end($filename_parts); array_splice($filename_parts, -1, 1); $name = str_replace(" ", "_", implode(".", $filename_parts)); //echo "PK: $pk_ids_file
"; $dateiname = $name.$pk_ids_file.".".$ext; //echo "Dn: $dateiname"; - copy($this->table_array[$spalte]["tmp"], $this->table_array[$spalte]["path"].$dateiname); + copy($this->table_array[$column]["tmp"], $this->table_array[$column]["path"].$dateiname); // automatisch thumbnail generieren, geht nur mit convert (ImageMagic!!!), aber nur bei bild .. if (strtolower($ext) == "jpeg" || strtolower($ext) == "jpg" || strtolower($ext) == "gif" || strtolower($ext) == "png") { $dateiname_tn = $name.$pk_ids_file."_tn.".$ext; - $eingang = $this->table_array[$spalte]["path"].$dateiname; - $ausgang = $this->table_array[$spalte]["path"].$dateiname_tn; + $eingang = $this->table_array[$column]["path"].$dateiname; + $ausgang = $this->table_array[$column]["path"].$dateiname_tn; $com = "convert -geometry 115 $eingang $ausgang"; exec($com); - $this->table_array[$spalte]["value"] = $dateiname_tn; + $this->table_array[$column]["value"] = $dateiname_tn; } else - $this->table_array[$spalte]["value"] = $dateiname; + $this->table_array[$column]["value"] = $dateiname; } - else if (file_exists($this->table_array[$spalte]["path"].$this->table_array[$spalte]["value"])) + else if (file_exists($this->table_array[$column]["path"].$this->table_array[$column]["value"])) { // mach gar nix, wenn bild schon da ??? } @@ -394,16 +394,17 @@ } // file IF /********************************* END FILE **************************************/ - if (!$this->table_array[$spalte]["pk"] && strlen($spalte) > 0 ) + // do not write 'pk' (primary key) or 'view' values + if (!$this->table_array[$column]["pk"] && $this->table_array[$column]['type'] != 'view' && strlen($column) > 0 ) { // for password use hidden value if main is not set - if ($this->table_array[$spalte]["type"] == "password" && !$this->table_array[$spalte]["value"]) - $this->table_array[$spalte]["value"] = $this->table_array[$spalte]["HIDDEN_value"]; + if ($this->table_array[$column]["type"] == "password" && !$this->table_array[$column]["value"]) + $this->table_array[$column]["value"] = $this->table_array[$column]["HIDDEN_value"]; if (!$insert) { if (strlen($q_data)) $q_data .= ", "; - $q_data .= $spalte." = "; + $q_data .= $column." = "; } else // this is insert @@ -412,19 +413,19 @@ $q_data .= ", "; if ($q_vars) $q_vars .= ", "; - $q_vars .= $spalte; + $q_vars .= $column; } // integer is different - if ($this->table_array[$spalte]["int"] || $this->table_array[$spalte]["int_null"]) + if ($this->table_array[$column]["int"] || $this->table_array[$column]["int_null"]) { -$this->debug('write_check', "[$spalte][".$this->table_array[$spalte]["value"]."] Foo: ".isset($this->table_array[$spalte]["value"])." | ".$this->table_array[$spalte]["int_null"]); - if (!$this->table_array[$spalte]["value"] && $this->table_array[$spalte]["int_null"]) +$this->debug('write_check', "[$column][".$this->table_array[$column]["value"]."] Foo: ".isset($this->table_array[$column]["value"])." | ".$this->table_array[$column]["int_null"]); + if (!$this->table_array[$column]["value"] && $this->table_array[$column]["int_null"]) $_value = 'NULL'; - elseif (!isset($this->table_array[$spalte]["value"])) + elseif (!isset($this->table_array[$column]["value"])) $_value = 0; else - $_value = $this->table_array[$spalte]["value"]; + $_value = $this->table_array[$column]["value"]; $q_data .= $_value; } else @@ -433,9 +434,9 @@ $this->debug('write_check', "[$spalte][".$this->table_array[$spalte]["value"]."] $q_data .= "'"; // if add slashes do convert & add slashes else write AS is if ($addslashes) - $q_data .= $this->db_escape_string($this->convert_entities($this->table_array[$spalte]["value"])); + $q_data .= $this->db_escape_string($this->convert_entities($this->table_array[$column]["value"])); else - $q_data .= addslashes($this->table_array[$spalte]["value"]); + $q_data .= addslashes($this->table_array[$column]["value"]); $q_data .= "'"; } } @@ -445,14 +446,14 @@ $this->debug('write_check', "[$spalte][".$this->table_array[$spalte]["value"]."] // get it at the end, cause now we can be more sure of no double IDs, etc reset($this->table_array); // create select part & addition FK part - while (list($spalte, $werte_array) = each($this->table_array)) + while (list($column, $data_array) = each($this->table_array)) { // check FK ... - if ($this->table_array[$spalte]["fk"] && $this->table_array[$spalte]["value"]) + if ($this->table_array[$column]["fk"] && $this->table_array[$column]["value"]) { if ($q_where) $q_where .= " AND "; - $q_where .= $spalte .= " = ".$this->table_array[$spalte]["value"]; + $q_where .= $column .= " = ".$this->table_array[$column]["value"]; } } diff --git a/www/libs/Class.Form.Generate.inc b/www/libs/Class.Form.Generate.inc index e0ca0261..1a509d87 100644 --- a/www/libs/Class.Form.Generate.inc +++ b/www/libs/Class.Form.Generate.inc @@ -25,7 +25,8 @@ * "fk" => 1/0 - sets the foreign key (do not use at the moment ... buggy ;) * "mandatory" => 1/0 - triggers * in output, but nor error check * "output_name" => "text" - text put as label for the element - * "type" => "text/textarea/date/drop_down_db/drop_down_array/drop_down_db_input/drop_down_db_same_db/radio_array/binary/hidden/file/password" + * "type" => "view/text/textarea/date/drop_down_db/drop_down_array/drop_down_db_input/drop_down_db_same_db/radio_array/binary/hidden/file/password" + * View is special, it just prints out the data as is, will not be saved * 1) more will come * 2) keep in mind that binary will not be checked, as it is always set to a value (default is "no") * ---- the next four fields are only NECESSARY (!!!) for drop_down_db_input @@ -44,6 +45,7 @@ * "error_check" => "custom/email/date/number/unique" - 1) more will come * "error_regex" => "regex" - if error_check is custom regex here * "error_example" => "text" - example input text for error_check (only custom right now) + * "empty" => "value/text" - ONLY for view. If no data found, set this value * --- file: * "save_dir" => "directory where it should be saved to * "accept_type" => "mime types accepted (mime/text,mime/jpeg ... etc)" @@ -689,6 +691,11 @@ $output_name .= ' *'; // create right side depending on "definiton" in table_array $type = $this->table_array[$element_name]["type"]; + // view only output + if ($this->table_array[$element_name]["type"] == "view") + { + $data['value'] = !$this->table_array[$element_name]["value"] ? $this->table_array[$element_name]['empty'] : $this->table_array[$element_name]["value"]; + } // binary true/false element if ($this->table_array[$element_name]["type"] == "binary") { diff --git a/www/libs/Class.Login.inc b/www/libs/Class.Login.inc index a4ee36ed..379bbc88 100644 --- a/www/libs/Class.Login.inc +++ b/www/libs/Class.Login.inc @@ -158,6 +158,10 @@ // set flag if password change is okay if (defined('PASSWORD_CHANGE')) $this->password_change = PASSWORD_CHANGE; + // max login counts before error reporting + $this->max_login_error_count = 10; + // users that never get locked, even if they are set strict + $this->lock_deny_users = array ('admin'); // internal $this->class_info["login"] = array( @@ -239,7 +243,7 @@ else { // we have to get the themes in here too - $q = "SELECT eu.edit_user_id, username, password, eu.edit_group_id, eg.name AS edit_group_name, admin, "; + $q = "SELECT eu.edit_user_id, username, password, eu.edit_group_id, eg.name AS edit_group_name, admin, eu.login_error_count, eu.login_error_date, eu.strict, eu.locked, "; $q .= "debug, db_debug, "; $q .= "eareu.level AS user_level, eareu.type AS user_type, "; $q .= "eareg.level AS group_level, eareg.type AS group_type, "; @@ -269,7 +273,25 @@ // $ and one alphanumeric letter, 13 chars long, but nor $ at the end: STD_DESC // if no $ => normal password // NOW, if we have a password encoded, but not the correct encoder available, throw special error - if ((preg_match("/^\\$2(a|y)\\$/", $res['password']) && CRYPT_BLOWFISH != 1) || (preg_match("/^\\$1\\$/", $res['password']) && CRYPT_MD5 != 1) || (preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && CRYPT_STD_DES != 1)) + + // check flow + // - user is enabled + // - user is not locked + // - password is readable + // - encrypted password matches + // - plain password matches + + // user is enabled + if (!$res["enabled"]) + { + $this->login_error = 104; + } + // user is locked, either set or auto set + elseif ($res['locked']) + { + $this->login_error = 105; + } + elseif ((preg_match("/^\\$2(a|y)\\$/", $res['password']) && CRYPT_BLOWFISH != 1) || (preg_match("/^\\$1\\$/", $res['password']) && CRYPT_MD5 != 1) || (preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && CRYPT_STD_DES != 1)) { $this->login_error = 9999; // this means password cannot be decrypted because of missing crypt methods } @@ -283,11 +305,6 @@ { $this->login_error = 1012; } - // user is enabled - elseif (!$res["enabled"]) - { - $this->login_error = 104; - } // nromal user processing else { @@ -312,6 +329,12 @@ $_SESSION["LANG"] = $res["lang_short"]; $_SESSION["DEFAULT_CHARSET"] = $res["lang_iso"]; $_SESSION["DEFAULT_LANG"] = $res["lang_short"].'_'.strtolower(str_replace('-', '', $res["lang_iso"])); + // reset any login error count for this user + if ($res['login_error_count'] > 0) + { + $q = "UPDATE edit_user SET login_error_count = 0, login_error_date = NULL WHERE edit_user_id = ".$res['edit_user_id']; + $this->db_exec($q); + } $pages = array(); $edit_page_ids = array(); // set pages access @@ -403,9 +426,24 @@ $_SESSION["UNIT"] = $unit_access; $_SESSION["UNIT_ACL_LEVEL"] = $unit_acl; $_SESSION['EAID'] = $eauid; - // load edit access list for this user } // user has permission to THIS page } // user was not enabled + if ($this->login_error) + { + // update login error count for this user + $q = "UPDATE edit_user SET login_error_count = login_error_count + 1, login_error_date = NOW WHERE edit_user_id = ".$res['edit_user_id']; + $this->db_exec($q); + if ($res['login_error_count'] + 1 > $this->max_login_error_count) + { + // do some alert reporting in case this error is too big + // if strict is set, lock this user + // this needs manual unlocking by an admin user + if ($res['strict'] && !in_array($this->username, $this->lock_deny_users)) + { + $q = "UPDATE edit_user SET locked = 1 WHERE edit_user_id = ".$res['edit_user_id']; + } + } + } } // user was not found } // if not username AND password where given // if there was an login error, show login screen @@ -421,7 +459,7 @@ // PARAMS: none // RETUNR none // DESC : for every page the user access this script checks if he is allowed to do so - private function login_check_permissions() + public function login_check_permissions() { if ($this->euid && $this->login_error != 103) { @@ -443,13 +481,15 @@ $this->permission_okay = 0; } } + // if called from public, so we can check if the permissions are ok + return $this->permission_okay; } // METHOD: login_logout_user // PARAMS: none // RETURN: none // DESC : if a user pressed on logout, destroyes session and unsets all global vars - private function login_logout_user() + public function login_logout_user() { if ($this->logout || $this->login_error) { @@ -491,7 +531,7 @@ // * if an account ACL is set, set this parallel, account ACL overrides user ACL if it applies // * if edit access ACL level is set, use this, else use page // set all base ACL levels as a list keyword -> ACL number - private function login_set_acl() + public function login_set_acl() { // set the mastser user id $this->acl['info']['euid'] = $_SESSION['EUID']; @@ -783,6 +823,7 @@ "102" => $this->l->__("Fatal Error: Login Failed - Please enter username and password"), "103" => $this->l->__("Fatal Error: You do not have the rights to access this Page"), "104" => $this->l->__("Fatal Error: Login Failed - User not enabled"), + "105" => $this->l->__("Fatal Error: Login Failed - User is locked"), "220" => $this->l->__("Fatal Error: Password change - The user could not be found"), // actually this is an illegal user, but I mask it '200' => $this->l->__("Fatal Error: Password change - Please enter username and old password"), "201" => $this->l->__("Fatal Error: Password change - The user could not be found"),