2016-03-25 01:18:05 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Auth;
|
|
|
|
|
|
|
|
use Validator;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
2016-12-01 02:04:15 -08:00
|
|
|
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
2016-03-25 19:26:22 -07:00
|
|
|
use App\Models\Setting;
|
2016-07-13 05:50:24 -07:00
|
|
|
use App\Models\Ldap;
|
2016-03-25 19:26:22 -07:00
|
|
|
use App\Models\User;
|
2016-03-25 01:18:05 -07:00
|
|
|
use Auth;
|
|
|
|
use Config;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
use Input;
|
|
|
|
use Redirect;
|
|
|
|
use Log;
|
|
|
|
use View;
|
2016-10-29 05:50:55 -07:00
|
|
|
use PragmaRX\Google2FA\Google2FA;
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-07-13 05:50:24 -07:00
|
|
|
|
|
|
|
|
2016-04-07 13:21:09 -07:00
|
|
|
/**
|
|
|
|
* This controller handles authentication for the user, including local
|
|
|
|
* database users and LDAP users.
|
|
|
|
*
|
|
|
|
* @todo Move LDAP methods into user model for better separation of concerns.
|
|
|
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
|
|
* @version v1.0
|
|
|
|
*/
|
2016-03-25 01:18:05 -07:00
|
|
|
class AuthController extends Controller
|
|
|
|
{
|
|
|
|
|
2016-12-01 02:04:15 -08:00
|
|
|
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
|
2016-03-25 01:18:05 -07:00
|
|
|
|
|
|
|
// This tells the auth controller to use username instead of email address
|
|
|
|
protected $username = 'username';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Where to redirect users after login / registration.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $redirectTo = '/';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new authentication controller instance.
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function __construct()
|
|
|
|
{
|
2016-10-29 05:50:55 -07:00
|
|
|
$this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
|
2016-03-25 01:18:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-01 02:13:00 -08:00
|
|
|
function showLoginForm()
|
2016-03-25 01:18:05 -07:00
|
|
|
{
|
|
|
|
if (Auth::check()) {
|
|
|
|
return redirect()->intended('dashboard');
|
|
|
|
}
|
|
|
|
return View::make('auth.login');
|
|
|
|
}
|
|
|
|
|
2016-12-01 02:25:53 -08:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
private function login_via_ldap(Request $request)
|
|
|
|
{
|
|
|
|
LOG::debug("Binding user to LDAP.");
|
|
|
|
$ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
|
|
|
|
if(!$ldap_user) {
|
|
|
|
LOG::debug("LDAP user ".$request->input('username')." not found in LDAP or could not bind");
|
|
|
|
throw new \Exception("Could not find user in LDAP directory");
|
|
|
|
} else {
|
|
|
|
LOG::debug("LDAP user ".$request->input('username')." successfully bound to LDAP");
|
|
|
|
}
|
|
|
|
|
2016-12-01 00:29:45 -08:00
|
|
|
// Check if the user already exists in the database and was imported via LDAP
|
|
|
|
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->where('ldap_import','=',1)->first();
|
2016-10-29 05:50:55 -07:00
|
|
|
LOG::debug("Local auth lookup complete");
|
|
|
|
|
|
|
|
// The user does not exist in the database. Try to get them from LDAP.
|
|
|
|
// If user does not exist and authenticates successfully with LDAP we
|
|
|
|
// will create it on the fly and sign in with default permissions
|
|
|
|
if (!$user) {
|
|
|
|
LOG::debug("Local user ".Input::get('username')." does not exist");
|
|
|
|
LOG::debug("Creating local user ".Input::get('username'));
|
|
|
|
|
|
|
|
if ($user = Ldap::createUserFromLdap($ldap_user)) { //this handles passwords on its own
|
|
|
|
LOG::debug("Local user created.");
|
|
|
|
} else {
|
|
|
|
LOG::debug("Could not create local user.");
|
|
|
|
throw new \Exception("Could not create local user");
|
|
|
|
}
|
|
|
|
// If the user exists and they were imported from LDAP already
|
|
|
|
} else {
|
|
|
|
LOG::debug("Local user ".$request->input('username')." exists in database. Updating existing user against LDAP.");
|
|
|
|
|
|
|
|
$ldap_attr = Ldap::parseAndMapLdapAttributes($ldap_user);
|
|
|
|
|
|
|
|
if (Setting::getSettings()->ldap_pw_sync=='1') {
|
|
|
|
$user->password = bcrypt($request->input('password'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$user->email = $ldap_attr['email'];
|
|
|
|
$user->first_name = $ldap_attr['firstname'];
|
|
|
|
$user->last_name = $ldap_attr['lastname'];
|
|
|
|
$user->save();
|
|
|
|
} // End if(!user)
|
|
|
|
return $user;
|
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Account sign in form processing.
|
|
|
|
*
|
|
|
|
* @return Redirect
|
|
|
|
*/
|
2016-07-13 05:50:24 -07:00
|
|
|
public function login(Request $request)
|
2016-03-25 01:18:05 -07:00
|
|
|
{
|
|
|
|
$validator = $this->validator(Input::all());
|
|
|
|
|
|
|
|
if ($validator->fails()) {
|
2016-04-28 21:06:41 -07:00
|
|
|
return redirect()->back()->withInput()->withErrors($validator);
|
2016-03-25 01:18:05 -07:00
|
|
|
}
|
2016-12-01 02:04:15 -08:00
|
|
|
|
|
|
|
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
|
|
|
// the login attempts for this application. We'll key this by the username and
|
|
|
|
// the IP address of the client making these requests into this application.
|
|
|
|
$throttles = $this->isUsingThrottlesLoginsTrait();
|
|
|
|
$this->maxLoginAttempts = config('auth.throttle.max_attempts');
|
|
|
|
$this->lockoutTime = config('auth.throttle.lockout_duration');
|
|
|
|
|
|
|
|
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
|
|
|
|
$this->fireLockoutEvent($request);
|
|
|
|
|
|
|
|
return $this->sendLockoutResponse($request);
|
|
|
|
}
|
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
$user = null;
|
2016-11-30 20:39:43 -08:00
|
|
|
|
2016-03-25 01:18:05 -07:00
|
|
|
// Should we even check for LDAP users?
|
2016-03-25 19:26:22 -07:00
|
|
|
if (Setting::getSettings()->ldap_enabled=='1') {
|
2016-03-25 01:18:05 -07:00
|
|
|
LOG::debug("LDAP is enabled.");
|
2016-07-13 05:50:24 -07:00
|
|
|
try {
|
2016-10-29 05:50:55 -07:00
|
|
|
$user = $this->login_via_ldap($request);
|
|
|
|
Auth::login($user, true);
|
2016-11-30 20:39:43 -08:00
|
|
|
|
|
|
|
// If the user was unable to login via LDAP, log the error and let them fall through to
|
|
|
|
// local authentication.
|
2016-07-13 05:50:24 -07:00
|
|
|
} catch (\Exception $e) {
|
2016-11-30 20:39:43 -08:00
|
|
|
LOG::error("There was an error authenticating the LDAP user: ".$e->getMessage());
|
2016-07-13 05:50:24 -07:00
|
|
|
}
|
2016-10-29 05:50:55 -07:00
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
// If the user wasn't authenticated via LDAP, skip to local auth
|
|
|
|
if(!$user) {
|
|
|
|
LOG::debug("Authenticating user against database.");
|
|
|
|
// Try to log the user in
|
|
|
|
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
|
2016-12-01 02:04:15 -08:00
|
|
|
|
|
|
|
if ($throttles && ! $lockedOut) {
|
|
|
|
$this->incrementLoginAttempts($request);
|
|
|
|
}
|
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
LOG::debug("Local authentication failed.");
|
|
|
|
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
|
2016-12-01 02:04:15 -08:00
|
|
|
} else {
|
|
|
|
if ($throttles) {
|
|
|
|
$this->clearLoginAttempts($request);
|
|
|
|
}
|
2016-10-29 05:50:55 -07:00
|
|
|
}
|
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
// Get the page we were before
|
|
|
|
$redirect = \Session::get('loginRedirect', 'home');
|
2016-07-13 05:50:24 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
// Unset the page we were before from the session
|
|
|
|
\Session::forget('loginRedirect');
|
2016-07-13 05:50:24 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
// Redirect to the users page
|
|
|
|
return redirect()->to($redirect)->with('success', trans('auth/message.signin.success'));
|
|
|
|
}
|
2016-07-13 05:50:24 -07:00
|
|
|
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
/**
|
|
|
|
* Two factor enrollment page
|
|
|
|
*
|
|
|
|
* @return Redirect
|
|
|
|
*/
|
|
|
|
public function getTwoFactorEnroll()
|
|
|
|
{
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
if (!Auth::check()) {
|
|
|
|
return redirect()->route('login')->with('error', 'You must be logged in.');
|
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
$user = Auth::user();
|
|
|
|
$google2fa = app()->make('PragmaRX\Google2FA\Contracts\Google2FA');
|
2016-07-14 23:49:32 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
if ($user->two_factor_secret=='') {
|
2016-10-31 11:20:31 -07:00
|
|
|
$user->two_factor_secret = $google2fa->generateSecretKey(32);
|
2016-10-29 05:50:55 -07:00
|
|
|
$user->save();
|
|
|
|
}
|
2016-07-14 23:49:32 -07:00
|
|
|
|
2016-08-04 14:29:28 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
$google2fa_url = $google2fa->getQRCodeGoogleUrl(
|
2016-10-31 22:34:57 -07:00
|
|
|
urlencode(Setting::getSettings()->site_name),
|
2016-11-11 20:09:22 -08:00
|
|
|
urlencode($user->username),
|
2016-10-29 05:50:55 -07:00
|
|
|
$user->two_factor_secret
|
|
|
|
);
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
return View::make('auth.two_factor_enroll')->with('google2fa_url',$google2fa_url);
|
2016-08-04 14:29:28 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
/**
|
|
|
|
* Two factor code form page
|
|
|
|
*
|
|
|
|
* @return Redirect
|
|
|
|
*/
|
|
|
|
public function getTwoFactorAuth() {
|
|
|
|
return View::make('auth.two_factor');
|
|
|
|
}
|
2016-03-25 01:18:05 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
/**
|
|
|
|
* Two factor code submission
|
|
|
|
*
|
|
|
|
* @return Redirect
|
|
|
|
*/
|
|
|
|
public function postTwoFactorAuth(Request $request) {
|
2016-08-04 14:29:28 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
if (!Auth::check()) {
|
|
|
|
return redirect()->route('login')->with('error', 'You must be logged in.');
|
2016-03-25 01:18:05 -07:00
|
|
|
}
|
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
$user = Auth::user();
|
|
|
|
$secret = $request->get('two_factor_secret');
|
|
|
|
$google2fa = app()->make('PragmaRX\Google2FA\Contracts\Google2FA');
|
|
|
|
$valid = $google2fa->verifyKey($user->two_factor_secret, $secret);
|
2016-08-04 14:29:28 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
if ($valid) {
|
|
|
|
$user->two_factor_enrolled = 1;
|
|
|
|
$user->save();
|
|
|
|
$request->session()->put('2fa_authed', 'true');
|
|
|
|
return redirect()->route('home')->with('success', 'You are logged in!');
|
|
|
|
}
|
2016-08-04 14:29:28 -07:00
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
return redirect()->route('two-factor')->with('error', 'Invalid two-factor code');
|
2016-03-25 01:18:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-10-29 05:50:55 -07:00
|
|
|
|
2016-03-25 01:18:05 -07:00
|
|
|
/**
|
|
|
|
* Logout page.
|
|
|
|
*
|
|
|
|
* @return Redirect
|
|
|
|
*/
|
2016-10-29 05:50:55 -07:00
|
|
|
public function logout(Request $request)
|
2016-03-25 01:18:05 -07:00
|
|
|
{
|
2016-10-29 05:50:55 -07:00
|
|
|
$request->session()->forget('2fa_authed');
|
2016-03-25 01:18:05 -07:00
|
|
|
Auth::logout();
|
2016-10-29 05:50:55 -07:00
|
|
|
return redirect()->route('login')->with('success', 'You have successfully logged out!');
|
2016-03-25 01:18:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a validator for an incoming registration request.
|
|
|
|
*
|
|
|
|
* @param array $data
|
|
|
|
* @return \Illuminate\Contracts\Validation\Validator
|
|
|
|
*/
|
|
|
|
protected function validator(array $data)
|
|
|
|
{
|
|
|
|
return Validator::make($data, [
|
|
|
|
'username' => 'required',
|
|
|
|
'password' => 'required',
|
|
|
|
]);
|
|
|
|
}
|
2016-12-01 02:04:15 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the login lockout error message.
|
|
|
|
*
|
|
|
|
* @param int $seconds
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getLockoutErrorMessage($seconds)
|
|
|
|
{
|
|
|
|
return \Lang::has('auth/message.throttle')
|
|
|
|
? \Lang::get('auth/message.throttle', ['seconds' => $seconds])
|
|
|
|
: 'Too many login attempts. Please try again in '.$seconds.' seconds.';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-03-25 01:18:05 -07:00
|
|
|
}
|