public function token() { if ($this->get_method() != 'POST') { $this->send_response(405, NULL, '请求的方法不存在'); } $data = $this->get_data(); $zone_code = isset($data['zone_code']) ? $data['zone_code'] : ''; $mobile = isset($data['mobile']) ? $data['mobile'] : ''; $code = isset($data['code']) ? $data['code'] : ''; if (!international::check_is_valid($zone_code, $mobile)) { $this->send_response(400, NULL, Kohana::lang('authorization.mobile_invalid')); } $username = $this->model->get_full_mobile($zone_code, $mobile); if (!$this->is_test_mobile($mobile)) { if (!$this->model->check_verify_code($username, $code)) { $this->send_response(400, NULL, Kohana::lang('authorization.code_invalid')); } } $user = $this->model->get_user_by_mobile($zone_code, $mobile); if ($user) { $id = $user['id']; } else { $regip = $this->get_ip(); $id = $this->model->create_user($zone_code, $mobile, '', $regip); } $token = $this->model->create_token(3600, TRUE, array('zone_code' => $zone_code, 'mobile' => $mobile, 'id' => (int) $id)); if ($user) { $token['name'] = $user['username']; $token['avatar'] = sns::getavatar($user['id']); } $this->send_response(200, $token); }
/** * Logs a user in using the RiverID method. * * @param string username * @param string password * @param boolean enable auto-login * @param string email * @param object a riverid object, not required * @return boolean */ public function login_riverid($user, $password, $remember, $email, $riverid = false) { // First check for exemptions if (!is_object($user)) { // Load the user $user = ORM::factory('user', $user); } if (isset($user->id) and in_array($user->id, kohana::config('riverid.exempt'))) { // Looks like this is an exempted account return $this->login_standard($user, $password, $remember); } // Get down to business since there were no exemptions if ($riverid == false) { $riverid = new RiverID(); $riverid->email = $email; $riverid->password = $password; } $is_registered = $riverid->is_registered(); // See if the request even fired off. if ($riverid->error) { throw new Exception($riverid->error[0]); } if ($is_registered == true) { // RiverID is registered on RiverID Server if ($riverid->authenticated != true) { // Attempt to sign in if our riverid object hasn't already authenticated $riverid->signin(); } if ($riverid->authenticated == true) { // Correct email/pass // Collect the RiverID user_id and connect that with a user in the local system $user = User_Model::get_user_by_river_id($riverid->user_id); if (!$user->id) { // User not found locally with that RiverID, we need to see if they are already registered // and convert their account or add them as a new user to the system // This may be a brand new user, but we need to figure out if // the email has already been registered $user = User_Model::get_user_by_email($riverid->email); if (!$user->id) { // Email isn't in our system, create a new user. $user = User_Model::create_user($riverid->email, $riverid->password, $riverid->user_id); } else { // Email already exists. Put the RiverID on that account. $user->riverid = $riverid->user_id; $user->save(); } } else { // We authenticated and we matched a RiverID, lets just makes sure the email // addresses are both up to date if ($user->email != $riverid->email) { // We don't have a match for this user account. We need to see if we should // be updating this account by first checking to see if another account // already uses this email address $user_check = User_Model::get_user_by_email($riverid->email); if (!$user_check->id) { $user->email = $riverid->email; $user->username = $riverid->email; $user->save(); } else { // Conflicting accounts // TODO: Figure out what to do when we need to update an email address on // one account but it's already in use on another. } } } // Now that we have our user account tied to their RiverID, approve their authentication return $this->perform_login($user, $remember, $riverid); } else { // Incorrect email/pass, but registered on RiverID. Failed login. if ($riverid->error) { throw new Exception($riverid->error[0]); } return FALSE; } } else { // Email is not registerd on RiverID Server, could be registered locally // First see if they used the correct user/pass on their local account $user = User_Model::get_user_by_email($riverid->email); if (!$user->id) { // User doesn't exist locally or on RiverID. Fail login. if ($riverid->error) { throw new Exception($riverid->error[0]); } return FALSE; } else { // User exists locally but doesn't yet exist on the RiverID server // Check if they got the password correct if ($user->has(ORM::factory('role', 'login')) and User_Model::check_password($user->id, $password, TRUE)) { // Correct password! Create RiverID account $riverid->register(); // If something went wrong with registration, catch it here if ($riverid->error) { throw new Exception($riverid->error[0]); } // Our user is now registered, let's assign the riverid user to the db. $user->riverid = $riverid->user_id; // Now lets sign them in $riverid->signin(); // If something went wrong with signin, catch it here if ($riverid->error) { throw new Exception($riverid->error[0]); } return $this->perform_login($user, $remember, $riverid); } else { // Incorrect user/pass. Fail login. if ($riverid->error) { throw new Exception($riverid->error[0]); } return FALSE; } } } }
public function index($user_id = 0) { // Set messages to display on the login page for the user $message = FALSE; $message_class = 'login_error'; $auth = Auth::instance(); // If already logged in redirect to user account page $insufficient_role = FALSE; if ($auth->logged_in()) { // Redirect users to the relevant dashboard if ($auth->logged_in('login')) { url::redirect($auth->get_user()->dashboard()); } $insufficient_role = TRUE; $message_class = 'login_error'; $message = Kohana::lang('ui_main.insufficient_role'); } // setup and initialize form field names $form = array('action' => '', 'username' => '', 'password' => '', 'password_again' => '', 'name' => '', 'email' => '', 'resetemail' => '', 'confirmation_email' => ''); // copy the form as errors, so the errors will be stored with keys corresponding to the form field names $errors = $form; $form_error = FALSE; $openid_error = FALSE; $success = FALSE; $change_pw_success = FALSE; $new_confirm_email_form = FALSE; $action = isset($_POST["action"]) ? $_POST["action"] : ""; // Override success variable if change_pw_success GET var is set if (isset($_GET["change_pw_success"])) { $change_pw_success = TRUE; $message_class = 'login_success'; $message = Kohana::lang('ui_main.password_changed_successfully'); } // Show send new confirm email form if (isset($_GET["new_confirm_email"])) { $new_confirm_email_form = TRUE; $message_class = 'login_error'; $message = Kohana::lang('ui_main.must_confirm_email_address'); } // Show send new confirm email form if (isset($_GET["confirmation_failure"])) { $new_confirm_email_form = TRUE; $message_class = 'login_error'; $message = Kohana::lang('ui_main.confirm_email_failed'); } // Show that confirming the email address was a success if (isset($_GET["confirmation_success"])) { $message_class = 'login_success'; $message = Kohana::lang('ui_main.confirm_email_successful'); } // Is this a password reset request? We need to show the password reset form if it is if (isset($_GET["reset"])) { $this->template->token = $this->uri->segment(4); $this->template->changeid = $this->uri->segment(3); } // Regular Form Post for Signin // check, has the form been submitted, if so, setup validation if ($_POST and isset($_POST["action"]) and $_POST["action"] == "signin") { // START: Signin Process $post = Validation::factory($_POST); $post->pre_filter('trim'); $post->add_rules('username', 'required'); $post->add_rules('password', 'required'); if ($post->validate(FALSE)) { // Sanitize $_POST data removing all inputs without rules $postdata_array = $post->safe_array(); // Flip this flag to flase to skip the login $valid_login = TRUE; // Load the user $user = ORM::factory('user', $postdata_array['username']); $remember = isset($post->remember) ? TRUE : FALSE; // Allow a login with username or email address, but we need to figure out which is // which so we can pass the appropriate variable on login. Mostly used for RiverID $email = $postdata_array['username']; if (valid::email($email) == FALSE) { // Invalid Email, we need to grab it from the user account instead $email = $user->email; if (valid::email($email) == FALSE and kohana::config('riverid.enable') == TRUE) { // We don't have any valid email for this user. // Only skip login if we are authenticating with RiverID. $valid_login = FALSE; } } // Auth Login requires catching exceptions to properly show errors try { $login = $auth->login($user, $postdata_array['password'], $remember, $email); // Attempt a login if ($login and $valid_login) { // Action::user_login - User Logged In Event::run('ushahidi_action.user_login', $user); // Exists Redirect to Dashboard url::redirect($user->dashboard()); } else { // If user isn't confirmed, redirect to resend confirmation page if (Kohana::config('settings.require_email_confirmation') and ORM::factory('user', $user)->confirmed == 0) { url::redirect("login?new_confirm_email"); } // Generic Error if exception not passed $post->add_error('password', 'login error'); } } catch (Exception $e) { $error_message = $e->getMessage(); // We use a "custom" message because of RiverID. $post->add_error('password', $error_message); } // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any // We need to already have created an error message file, for Kohana to use // Pass the error message file name to the errors() method $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any // We need to already have created an error message file, for Kohana to use // Pass the error message file name to the errors() method $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } // END: Signin Process } elseif ($_POST and isset($_POST["action"]) and $_POST["action"] == "new") { // START: New User Process $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); $post->add_rules('password', 'required', 'length[' . kohana::config('auth.password_length') . ']', 'alpha_dash'); $post->add_rules('name', 'required', 'length[3,100]'); $post->add_rules('email', 'required', 'email', 'length[4,64]'); $post->add_callbacks('username', array($this, 'username_exists_chk')); $post->add_callbacks('email', array($this, 'email_exists_chk')); // If Password field is not blank if (!empty($post->password)) { $post->add_rules('password', 'required', 'length[' . kohana::config('auth.password_length') . ']', 'alpha_dash', 'matches[password_again]'); } //pass the post object to any plugins that care to know. Event::run('ushahidi_action.users_add_login_form', $post); if ($post->validate()) { $riverid_id = false; if (kohana::config('riverid.enable') == true) { $riverid = new RiverID(); $riverid->email = $post->email; $riverid->password = $post->password; $riverid->register(); $riverid_id = $riverid->user_id; } $user = User_Model::create_user($post->email, $post->password, $riverid_id, $post->name); //pass the new user on to any plugins that care to know Event::run('ushahidi_action.user_edit', $user); // Send Confirmation email $email_sent = $this->_send_email_confirmation($user); if ($email_sent) { $message_class = 'login_success'; $message = Kohana::lang('ui_main.login_confirmation_sent'); } else { $message_class = 'login_success'; $message = Kohana::lang('ui_main.login_account_creation_successful'); } $success = TRUE; $action = ""; } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } // END: New User Process } elseif ($_POST and isset($_POST["action"]) and $_POST["action"] == "forgot") { // START: Forgot Password Process $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); $post->add_callbacks('resetemail', array($this, 'email_exists_chk')); if ($post->validate()) { $user = ORM::factory('user', $post->resetemail); // Existing User?? if ($user->loaded) { $email_sent = FALSE; // Determine which reset method to use. The options are to use the RiverID server // or to use the normal method which just resets the password locally. if (Kohana::config('riverid.enable') == TRUE and !empty($user->riverid)) { // Reset on RiverID Server $secret_link = url::site('login/index/' . $user->id . '/%token%?reset'); $message = $this->_email_resetlink_message($user->name, $secret_link); $riverid = new RiverID(); $riverid->email = $post->resetemail; $email_sent = $riverid->requestpassword($message); } else { // Reset locally $secret = $user->forgot_password_token(); $secret_link = url::site('login/index/' . $user->id . '/' . urlencode($secret) . '?reset'); $email_sent = $this->_email_resetlink($post->resetemail, $user->name, $secret_link); } if ($email_sent == TRUE) { $message_class = 'login_success'; $message = Kohana::lang('ui_main.login_confirmation_sent'); } else { $message_class = 'login_error'; $message = Kohana::lang('ui_main.unable_send_email'); } $success = TRUE; $action = ""; } } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } // END: Forgot Password Process } elseif ($_POST and isset($_POST["action"]) and $_POST["action"] == "changepass") { // START: Password Change Process $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); $post->add_rules('token', 'required'); $post->add_rules('changeid', 'required'); $post->add_rules('password', 'required', 'length[' . Kohana::config('auth.password_length') . ']', 'alpha_dash'); $post->add_rules('password', 'required', 'length[' . Kohana::config('auth.password_length') . ']', 'alpha_dash', 'matches[password_again]'); if ($post->validate()) { $success = $this->_new_password($post->changeid, $post->password, $post->token); if ($success == TRUE) { // We don't need to see this page anymore if we were successful. We want to go // to the login form and let the user know that they were successful at // changing their password url::redirect("login?change_pw_success"); exit; } $post->add_error('token', 'invalid'); // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } // END: Password Change Process } elseif ($_POST and isset($_POST["action"]) and $_POST["action"] == "resend_confirmation") { // START: Confirmation Email Resend Process $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); $post->add_callbacks('confirmation_email', array($this, 'email_exists_chk')); if ($post->validate()) { $user = ORM::factory('user', $post->confirmation_email); if ($user->loaded) { // Send Confirmation email $email_sent = $this->_send_email_confirmation($user); if ($email_sent) { $message_class = 'login_success'; $message = Kohana::lang('ui_main.login_confirmation_sent'); $success = TRUE; } else { $message_class = 'login_error'; $message = Kohana::lang('ui_main.unable_send_email'); $success = FALSE; } } else { // ERROR: User doesn't exist $message_class = 'login_error'; $message = Kohana::lang('ui_main.login_email_doesnt_exist'); $success = FALSE; } } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::merge($errors, $post->errors('auth')); $form_error = TRUE; } } // Only if we allow OpenID, should we even try this if (Kohana::config('config.allow_openid') == TRUE) { // START: OpenID Shenanigans // OpenID Post try { $openid = new OpenID(); // Retrieve the Name (if available) and Email $openid->required = array("namePerson", "contact/email"); if (!$openid->mode) { if (isset($_POST["openid_identifier"])) { $openid->identity = $_POST["openid_identifier"]; header("Location: " . $openid->authUrl()); } } elseif ($openid->mode == "cancel") { $openid_error = TRUE; $message_class = 'login_error'; $message = "You have canceled authentication!"; } else { if ($openid->validate()) { // Does User Exist? $openid_user = ORM::factory("openid")->where("openid", $openid->identity)->find(); if ($openid_user->loaded and $openid_user->user) { // First log all other sessions out $auth->logout(); // Initiate Ushahidi side login + AutoLogin $auth->force_login($openid_user->user->username); // Exists Redirect to Dashboard url::redirect($user->dashboard()); } else { // Does this openid have the required email?? $new_openid = $openid->getAttributes(); if (!isset($new_openid["contact/email"]) or empty($new_openid["contact/email"])) { $openid_error = TRUE; $message_class = 'login_error'; $message = $openid->identity . " has not been logged in. No Email Address Found."; } else { // Create new User and save OpenID $user = ORM::factory("user"); // But first... does this email address already exist // in the system? if ($user->email_exists($new_openid["contact/email"])) { $openid_error = TRUE; $message_class = 'login_error'; $message = $new_openid["contact/email"] . " is already registered in our system."; } else { $username = "******" . time(); // Random User Name from TimeStamp - can be changed later $password = text::random("alnum", 16); // Create Random Strong Password // Name Available? $user->name = (isset($new_openid["namePerson"]) and !empty($new_openid["namePerson"])) ? $new_openid["namePerson"] : $username; $user->username = $username; $user->password = $password; $user->email = $new_openid["contact/email"]; // Add New Roles $user->add(ORM::factory('role', 'login')); $user->add(ORM::factory('role', 'member')); $user->save(); // Save OpenID and Association $openid_user->user_id = $user->id; $openid_user->openid = $openid->identity; $openid_user->openid_email = $new_openid["contact/email"]; $openid_user->openid_server = $openid->server; $openid_user->openid_date = date("Y-m-d H:i:s"); $openid_user->save(); // Initiate Ushahidi side login + AutoLogin $auth->login($username, $password, TRUE); // Redirect to Dashboard url::redirect($user->dashboard()); } } } } else { $openid_error = TRUE; $message_class = 'login_error'; $message = $openid->identity . "has not been logged in."; } } } catch (ErrorException $e) { $openid_error = TRUE; $message_class = 'login_error'; $message = $e->getMessage(); } // END: OpenID Shenanigans } // Set the little badge under the form informing users that their logins are being managed // by an external service. $this->template->riverid_information = ''; if (kohana::config('riverid.enable') == TRUE) { $riverid = new RiverID(); $this->template->riverid_information = Kohana::lang('ui_main.riverid_information', $riverid->name); $this->template->riverid_url = $riverid->url; } $this->template->errors = $errors; $this->template->success = $success; $this->template->change_pw_success = $change_pw_success; $this->template->form = $form; $this->template->form_error = $form_error; $this->template->new_confirm_email_form = $new_confirm_email_form; // Message to user $this->template->message_class = $message_class; $this->template->message = $message; // This just means the user isn't a member or an admin, so they have nowhere to go, but they are logged in. $this->template->insufficient_role = $insufficient_role; $this->template->site_name = Kohana::config('settings.site_name'); $this->template->site_tagline = Kohana::config('settings.site_tagline'); // Javascript Header $this->template->js = new View('login/login_js'); $this->template->js->action = $action; // Header Nav $header_nav = new View('header_nav'); $this->template->header_nav = $header_nav; $this->template->header_nav->loggedin_user = FALSE; if (isset(Auth::instance()->get_user()->id)) { // Load User $this->template->header_nav->loggedin_role = Auth::instance()->get_user()->dashboard(); $this->template->header_nav->loggedin_user = Auth::instance()->get_user(); } $this->template->header_nav->site_name = Kohana::config('settings.site_name'); }