it_db_record($table, $uid_field); $this->session = new it_session; $this->status = _IT_USER_STATUS_INVALID; $this->uidcookiename = _IT_USER_UID_COOKIE; $this->uid_field = $uid_field; $this->username_field = $username_field; $this->password_field = $password_field; } /** * Post processing, called by ITools after reading a database record * @access private */ function _read_post_process() { parent::_read_post_process(); /* If read succeeded, get UID. This is necessary because it's only set if a cookie is present (i.e. in web-context) */ if (isset($this->data[$this->uid_field])) $this->uid = $this->data[$this->uid_field]; /* Get username from database field */ $this->username = $this->data[$this->username_field]; } function set_session_cookie_name($sessioncookiename) { $this->sessioncookiename = $sessioncookiename; } function set_uid_cookie_name($uidcookiename) { $this->uidcookiename = $uidcookiename; } function set_domain($domain) { $this->domain = $domain; } function set_session_lifetime($lifetime) { $this->lifetime = $lifetime; } function set_login_identifier($login_identifier) { $this->login_identifier_required = true; $this->login_identifier = $login_identifier; } function _init_session() { if (!$this->sessioninitialized) { /* Using a non-standard values for session? */ if ($this->sessioncookiename) $this->session->set_cookiename($this->sessioncookiename); if (isset($this->domain)) $this->session->set_domain($this->domain); if (isset($this->lifetime)) $this->session->set_lifetime($this->lifetime); if (isset($this->secret)) $this->session->set_secret($this->secret); $this->session->init(); $this->sessioninitialized = true; } } function get_status() { if ($this->status == _IT_USER_STATUS_INVALID) { $this->_init_session(); if ($this->session->is_valid()) { $this->status = IT_USER_STATUS_SESSION; $this->_set_uid($this->session->get_uid()); $this->set_key_field($this->uid_field); $this->read($this->uid); /* username == uid means we don't have a username yet */ if ($this->username == $this->uid) $this->username = ""; } else if (isset($_COOKIE[$this->uidcookiename]) && ($this->uid = substr($_COOKIE[$this->uidcookiename], 0, 32))) { $this->set_key_field($this->uid_field); $this->read($this->uid); if ($this->username == $this->uid) $this->username = ""; if ($this->username) $this->status = IT_USER_STATUS_KNOWN; else $this->status = IT_USER_STATUS_ANONYMOUS; } else { $this->status = IT_USER_STATUS_UNKNOWN; $this->username = ''; if ($this->uid_field) $this->_set_uid($this->create_uid()); } } #debug("status $this->status"); return $this->status; } function get_username() { return $this->username; } function get_uid() { return $this->uid; } function _set_uid($uid) { $this->uid = $uid; if (!isset($_COOKIE[$this->uidcookiename]) || ($_COOKIE[$this->uidcookiename] != $uid)) { @setcookie($this->uidcookiename, $uid, _IT_USER_UID_COOKIE_LIFETIME, "/", $this->domain); $_COOKIE[$this->uidcookiename] = $uid; } } /* Return session status of this user: Is she logged in? */ function is_logged_in() { return $this->status == IT_USER_STATUS_SESSION; } /* * Try to log in user. Use get_status() to check result. * NOTE: Must not be called AFTER get_status() has been used. * @param $username User ID to login * @param $password Password to authenticate login * @param $ignorepassword True if you want to login anyway (e.g. 'su') * @return non-false if successful, false on error */ function login($username, $password, $ignorepassword = false, $withsession = true) { $result = false; $this->_init_session(); $this->workrecord = new it_db_record($this->table, $this->username_field); #debug("username '$username'"); if ($this->workrecord->read($username)) { #debug("password '$password', '" . $this->workrecord->data[$this->password_field] . "'"); if ($ignorepassword || $this->check_password($password, $this->workrecord->data[$this->password_field])) { #debug("login_identifier '$this->login_identifier'"); $this->session->set_uid($this->workrecord->data[$this->uid_field]); if ($withsession) $result = $this->session->set_valid(true, $this->login_identifier_required, $this->login_identifier); else $result = $_COOKIE[$this->uidcookiename] = $this->session->get_uid(); } #debug("result '$result'"); } if ($result && ($this->session->get_uid() == $this->workrecord->data[$this->uid_field])) $this->username = $this->workrecord->data[$this->username_field]; if ($result) $this->status = _IT_USER_STATUS_INVALID; else $this->status = IT_USER_STATUS_FAILED; return $result; } /* * Logout user. * NOTE: Must not be called AFTER get_status() has been used. */ function logout() { $this->_init_session(); $this->session->set_valid(false); } /* * Throw away all user information and restart from scratch... */ function purge() { $this->status = _IT_USER_STATUS_INVALID; $this->_set_uid($this->create_uid()); $this->username = ""; $this->session->purge(); } /* * Create user database record. * @param $tags Fields to set (uid and username are optional) * @see it_db_record */ function create($tags) { $result; /* Make sure UID is always set in database records */ if ($this->uid_field) { if (!$this->uid) $this->_set_uid($this->create_uid()); $tags[$this->uid_field] = $this->uid; } /* Create dummy but unique username if none given */ if (!$tags[$this->username_field] && !$this->data[$this->username_field]) $tags[$this->username_field] = $this->uid; if ($result = it_db_record::create($tags)) $this->_set_uid($this->data[$this->uid_field]); return $result; } /* * Create unique identifier used for anonymously users, Override if you want * different type of UIDs. * Returns newly created uid */ function create_uid() { return md5(uniqid(rand())); /* random garbage */ } /* * Create a login identifier and set session to login identifier 'secret' value * Returns a value to be put into the login
which has to be passed to * login() to create a valid session */ function create_login_identifier() { return $this->session->create_login_identifier(); } /* * Create a random password with given length. */ function create_password($length = 8, $charset = 'abcdefghjkpqrstuvwxyz23456789ABCDEFGHJKPRSTUVWXYZ') { $result = ""; mt_srand((double)microtime() * 1000000); for ($i = 0; $i < $length; $i++) $result .= substr($charset, mt_rand(0, strlen($charset) - 1), 1); return $result; } /* * Crypt the password, same function is used in check_login_status * You can use unencrypted passwords if you extend the user class and * override this function. */ function crypt_password($password) { $result = $this->table->db->safe_sql_query("SELECT PASSWORD('" . mysql_real_escape_string($password) . "')"); list($pw) = $this->table->db->fetch_array($result); return $pw; } /* * Crypt the password and compare it to cryptedpassword. */ function check_password($password, $cryptedpassword) { return $this->crypt_password($password) == $cryptedpassword; } /* * Check if cookies are enabled. * NOTE: Only works if you used create_login_identifier() on previous page */ function has_cookies() { return $this->session->has_cookies(); } /* * Check if $name would be an acceptable username */ function is_valid_username($name) { if ((strlen($name) >= 2) && (strlen($name) <= 32)) { if (!ereg('["\'\\&\$+]', $name)) return true; } return false; } /* * Check if $word would be an acceptable password */ function is_valid_password($word) { if ((strlen($word) >= 2) && (strlen($word) <= 32)) { if (!ereg('["\'\\&\$+]', $word)) return true; } return false; } /* * Sign string with current user id or session * @param $text Text to be signed * @param $withsession Sign with session if true, with uid if false * @return Signature for $text */ function create_signature($text, $withsession = true) { if ($withsession) { switch ($this->get_status()) { case IT_USER_STATUS_SESSION: $result = $this->session->create_signature($text); break; default: $result = md5("$this->secret,$text,$this->secret"); break; } } else { /* Sign with UID only */ $result = md5("$this->secret,$this->uid,$text,$this->secret"); } return $result; } /* * Check signature for string with current user id or session * @param $text Text which was signed * @param $signature Signature to be checked * @param $withsession Signed with session if true, with uid if false * @return True if signature ok, false otherwise */ function check_signature($text, $signature, $withsession = true) { if ($withsession) { switch ($this->get_status()) { case IT_USER_STATUS_SESSION: $result = $this->session->check_signature($text, $signature); break; default: $result = (md5("$this->secret,$text,$this->secret") == $signature); break; } } else { /* Sign with UID only */ $result = ($this->create_signature($text, false) == $signature); } return $result; } /* * Sign an url with parameters * @param $url URL to sign * @param $withsession Signed with session if true, with uid if false * @return Signed url */ function sign_url($url, $withsession = false) { if (strstr($url, '?')) $url .= "&$this->urlauthenticationcode=" . $this->create_signature(str_replace('&', '&', $url), $withsession); return $url; } /* * Check if url GET parameters are properly signed and not modified * @param $withsession Signed with session if true, with uid if false * @return False if url was modified */ function check_url($withsession = false) { $result = true; /* Default to true for url without parameters */ if (!empty($_SERVER['QUERY_STRING'])) { $url = ereg_replace("&?$this->urlauthenticationcode=[a-zA-Z0-9]*", '', $_SERVER['REQUEST_URI']); $result = $this->check_signature($url, $GLOBALS[$this->urlauthenticationcode], $withsession); } return $result; } } /* End class it_user */ ?>