/** * Create new view. * * @param Model_User $user * @param array $errors */ public function __construct(Model_User $user, array $errors = null) { parent::__construct(); $this->user = $user; $this->errors = $errors; $this->external = Model_User_External::factory()->find_by_user_id($this->user->id, 'facebook'); if ($this->external && $this->external->loaded()) { $this->consumer = new OAuth2_Consumer('facebook', $this->external->access_token()); } }
/** * Sign in */ public function action_in() { if (Visitor::$user) { Request::back(); } if ($_POST) { $visitor = Visitor::instance(); // Require valid user for login logging $user = Model_User::find_user($_POST['username']); // Get external account data $token = $external_user_id = null; if ($provider = Arr::get($_POST, 'external')) { $consumer = new OAuth2_Consumer($provider); $token = $consumer->get_token(); $external_user_id = Session::instance()->get('oauth2.' . $provider . '.id'); } $success = $user && $visitor->login($user, $_POST['password'], isset($_POST['remember'])); // Log login attempt Model_Login::log($success, $user ? $user : $_POST['username'], isset($_POST['password']) && $_POST['password'] != ''); if (!$success) { // Redirect to lost password page on fail Request::current()->redirect(Route::url('password')); } else { if ($token && $external_user_id) { // Connect to external account $external = Model_User_External::factory()->find_by_user_id($user->id, $provider); // Check for already connected account if ($external && $external->loaded()) { // Already connected, do nuthin' Kohana::$log->add(Log::DEBUG, 'OAuth2: Sign in, already connected accounts'); } else { Kohana::$log->add(Log::DEBUG, 'OAuth2: Sign in and connect accounts'); // Not connected, connect! $external = new Model_User_External(); $external->set_fields(array('token' => $token['access_token'], 'user_id' => $user->id, 'external_user_id' => $external_user_id, 'created' => time(), 'expires' => time() + (int) $token['expires'], 'provider' => $provider)); $external->save(); } } } } Request::back(); }
/** * Action: Redirected from 3rd party. */ public function action_redirect() { $provider = $this->consumer->get_provider(); if ($provider != 'facebook') { // Unsupported provider $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(__('We are not entirely sure what 3rd party service redirected you here'), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: Unsupported provider: :provider', array(':provider' => $provider)); return; } if ($response = Arr::get($_REQUEST, OAuth2::RESPONSE_TYPE_CODE)) { // Code received, change it to access token try { $token = $this->consumer->request_token(array(OAuth2::RESPONSE_TYPE_CODE => $response)); if (Visitor::$user) { // Already logged in $external = Model_User_External::factory()->find_by_user_id(Visitor::$user->id, $provider); if ($this->_update_token($external, $token)) { // Already paired with local user $this->request->redirect(URL::user(Visitor::$user, 'settings')); //Request::back(); } else { // Not paired with local user, do so if ($response = $this->consumer->api_call('/me', array('fields' => 'id,email'))) { // Received a response from 3rd party if ($error = Arr::get($response, 'error')) { // .. but it was an error $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(__('They said ":error"', array(':error' => HTML::chars($error->message))), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: Failed to load Facebook profile: :error', array(':error' => $error->message)); } else { // Received required information $external = new Model_User_External(); $external->set_fields(array('token' => $token['access_token'], 'user_id' => Visitor::$user->id, 'external_user_id' => Arr::get($response, 'id'), 'created' => time(), 'expires' => time() + (int) $token['expires'], 'provider' => $provider)); $external->save(); $this->request->redirect(URL::user(Visitor::$user, 'settings')); //Request::back(); } } else { // No data received, this should be handled by exceptions } } } else { // No signed in user available if ($response = $this->consumer->api_call('/me')) { // Received a response from 3rd party if ($error = Arr::get($response, 'error')) { // .. but it was an error $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(__('They said ":error"', array(':error' => HTML::chars($error->message))), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: Failed to load Facebook profile: :error', array(':error' => $error->message)); } else { // Received required information $external_user_id = Arr::get($response, 'id'); $external = Model_User_External::factory()->find_by_external_user_id($external_user_id, $provider); if ($this->_update_token($external, $token)) { // Already paired with local user, login Kohana::$log->add(Log::DEBUG, 'OAuth2: Attempting to login :external_user_id => :user_id', array(':external_user_id' => $external->external_user_id, ':user_id' => $external->user_id)); if ($this->_login($external)) { Request::back(); } Kohana::$log->add(Log::WARNING, 'OAuth2: Login failed'); } else { // Not paired with a local user, check if we have unpaired user available $email = Arr::get($response, 'email'); // Store external user id in session data, token should be stored in OAuth2 Session::instance()->set('oauth2.' . $provider . '.id', $external_user_id); if ($user = Model_User::find_user($email)) { // User with same email found, ask to sign in Kohana::$log->add(Log::DEBUG, 'OAuth2: Existing user with same email found'); $this->view->add(View_Page::COLUMN_CENTER, $this->section_signin($user, $response)); } else { // No user with same email found, start registering Kohana::$log->add(Log::DEBUG, 'OAuth2: Starting new user registration'); Session::instance()->set('oauth2.' . $provider . '.response', $response); $this->request->redirect(Route::url('sign', array('action' => 'up')) . '?provider=' . $provider); } } } } else { // No data received, this should be handled by exceptions } } } catch (OAuth2_Exception_InvalidGrant $e) { $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(HTML::chars($e->getMessage()), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: Invalid grant: :error', array(':error' => $e->getMessage())); } catch (Kohana_Exception $e) { $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(HTML::chars($e->getMessage()), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: Exception: :error', array(':error' => $e->getMessage())); } } else { $this->view->add(View_Page::COLUMN_CENTER, new View_Alert(__('Did not receive required code from 3rd party'), __('Failed to load your profile :('), View_Alert::ERROR)); Kohana::$log->add(Log::NOTICE, 'OAuth2: No code received'); } }