<?php class Auth_Controller extends Base_Controller { public $restful = true; public function __construct() { $this->filter( 'before', 'guest' )->except( array( 'logout', 'validate' ) ); // Note: We may not always require CSRF on login for system based logins so ignore it here. $this->filter( 'before', 'csrf' )->on( 'post' )->except( array( 'login' ) ); } /** * No direct access needed * * @return NULL */ public function get_index() { return Redirect::to( 'home' ); } /** * Verify login information and authenticate the client * * @param array * @return Redirect */ public function post_login( $data = NULL ) { if( !empty( $data ) ) // Directly set the data so we can use it as normal Input::$input = $data; else // If this is a non-system call require CSRF $this->filter( 'before', 'csrf' ); $rules = array( 'email_address' => 'required|email', 'password' => 'required|min:6', ); // Validate all input $validator = Validator::make( Input::all(), $rules ); // Send them back with errors if( ! $validator->valid() ) return Redirect::to( 'home' )->with( 'errors', $validator->errors ); // Add errors to the view // Attempt to authenticate if( Auth::attempt( Input::get( 'email_address' ), Input::get( 'password' ) ) ) { // Trigger log in event. Locker::trigger_event( 1, 'logged in', Auth::user()->id ); // Send them to their locker return Redirect::to( 'locker' ); } return Redirect::to( 'home' ); } /** * Handle logout requests by cleaning up the session * * @return Redirect */ public function get_logout() { // Trigger log out event Locker::trigger_event( 1, 'logged out', Auth::user()->id ); // Destory the session Auth::logout(); // Send them home return Redirect::to( 'home' ); } /** * Handle redirect from FB and save the users profile data. * * @return Redirect */ public function get_fb() { // Re-build object $facebook = new Facebook\SDK( array( 'appId' => Config::get( 'facebook.app_id' ), 'secret' => Config::get( 'facebook.secret' ), 'cookie' => true ) ); // Auth request params $params = array( 'scope' => Config::get( 'facebook.scope' ), 'redirect_uri' => Config::get( 'facebook.redirect_uri' ), ); // Build the FB user $user = $facebook->getUser(); if( $user ) { // Request FB profile data $fb_user = $facebook->api( '/me' ); } // Something went wrong if( ! $fb_user ) return Redirect::to( 'home' )->with( 'errors', 'Unable to connect with Facebook.' ); // Restucture FB data to our own $lk_user['first_name'] = $fb_user['first_name']; $lk_user['last_name'] = $fb_user['last_name']; $lk_user['email_address'] = $fb_user['email']; $lk_user['nickname'] = $fb_user['username']; if( $fb_user['gender'] === 'male' ) $lk_user['gender'] = 1; else $lk_user['gender'] = 0; // Reverse the encrypted password $lk_user['password'] = Crypter::decrypt( Session::get( 'password' ) ); // This is for compatability with post_register() validation $lk_user['password_confirmation'] = $lk_user['password']; // Flag from_facebook $lk_user['from_facebook']; // Remove the session password Session::forget( 'password' ); // Register the user, do not require email validation $this->post_register( $lk_user, false ); return Redirect::to( 'home' ); } /** * Choose a password to use with FB profile data. * POST will have the users password in it and redirect to FB for auth request. * * @return Redirect */ public function post_fb() { // Give a form to set a password $rules = array( 'password' => 'required|confirmed|min:6', ); // Validate all input $validator = Validator::make( Input::all(), $rules ); // Send them back with errors if( ! $validator->valid() ) return Redirect::to( 'home' )->with( 'errors', $validator->errors ); // Add errors to the view // Store the password temporary in our session, use some encryption in case non-SSL Session::put( 'password', Crypter::encrypt( Input::get( 'password' ) ) ); // Re-build object $facebook = new Facebook\SDK( array( 'appId' => Config::get( 'facebook.app_id' ), 'secret' => Config::get( 'facebook.secret' ), 'cookie' => true ) ); // Auth request params $params = array( 'scope' => Config::get( 'facebook.scope' ), 'redirect_uri' => Config::get( 'facebook.redirect_uri' ), ); return Redirect::to( $facebook->getLoginUrl( $params ) ); } /** * Validate registration data for our system * * @param array * @param boolean * @return Redirect with array */ public function post_register( $data = NULL, $email_confirm = true ) { if( !empty( $data ) ) Input::$input = $data; $rules = array( 'first_name' => 'required|alpha|max:80', 'last_name' => 'required|alpha|max:120', 'gender' => 'required|in:0,1', 'email_address' => 'required|email|unique:users', 'password' => 'required|confirmed|min:6' ); // Validate all input $validator = Validator::make( Input::all(), $rules ); // Send them back with errors if( ! $validator->valid() ) return Redirect::to( 'home' ) ->with( 'errors', $validator->errors ) ->with_input( 'except', array( 'password', 'password_confirm' ) ); // Add errors to the view // Create a new user $user = new User; // Fill in the details $user->fill( Input::all() ); // Filter unused fields. unset( $user->password_confirmation ); unset( $user->csrf_token ); // Hash the password $user->password = Hash::make( $user->password ); // Require e-mail confirmation if( ! $mail_confirm ) { // Invalidate the account $user->validated = 0; // Save the user so we can grab their ID. $user->save(); // Generate a validate key $user->validation_code = Str::random( array_get( $arguments, 0, 32 ) ); $mailer = IoC::resolve( 'mailer' ); $message = Swift_Message::newInstance( 'Welcome to Yoursite.com' ) ->setFrom( array( Config::get( 'email.from' ) => Config::get( 'email.name' ) ) ) ->setTo( array( $user->email_address => $user->first_name . ' ' . $user->last_name ) ) ->setBody( '<html>'. '<body>'. '<h2>Welcome to Yoursite.com</h2>'. '<p>You need to confirm your e-mail in order to participate.</p>'. '<p>Please <a href="http://www.yoursite.com/auth/validate/' . $user->id. '/'. htmlentities( $user->validation_code ) . '">click here</a>.</p>'. '</body>'. '</html>', 'text/html' // Mark the content-type as HTML ) ; $result = $mailer->send($message); } else $user->validated = 1; // Send to the database $user->save(); $_POST['csrf_token'] = Session::token(); // Try to authenticate by passing the data to the login object. $this->post_login( Input::all() ); return Redirect::to( 'home' ); } /** * Validate email_address * * @return redirect */ public function get_validate( $id, $code ) { $key = html_entity_decode( $code ); $validation_code = DB::table( 'users' )->where( 'id', '=', $id )->only( 'validation_code' ); if( $validation_code === $key ) { $affected = DB::table( 'users' ) ->where( 'id', '=', $id ) ->update( array( 'validated' => 1, 'validation_code' => NULL, // Clear the validation code so we do waste space ) ); } else return Redirect::to( 'home' )->with( 'errors', 'Invalid validation code.' ); // Notify the user it worked Session::flash( 'notice', 'You have confirmed your e-mail.' ); return Redirect::to( 'home' ); } }