You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.5 KiB
133 lines
3.5 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace authkit2\Http\Controllers;
|
|
use Illuminate\Http\Request;
|
|
|
|
/**
|
|
* Methods for handling user authentication operations
|
|
*/
|
|
class AuthenticationController extends Controller
|
|
{
|
|
protected $user_flow;
|
|
|
|
public function __construct(\authkit2\Oidc\Flows\UserFlow $user_flow)
|
|
{
|
|
$this->user_flow = $user_flow;
|
|
}
|
|
|
|
/**
|
|
* Start the login flow for a user
|
|
*
|
|
* Redirects the user to the SSO service
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function login()
|
|
{
|
|
// TODO: Pass in 'previous' URL from session so we can redirect back
|
|
// if we were redirected to login from a guard?
|
|
return redirect($this->user_flow->getRedirectUrl(config('authkit.authn.openid.redirect_uri'), config('authkit.authn.scopes')));
|
|
}
|
|
|
|
/**
|
|
* Handle the response from the SSO service
|
|
*
|
|
* Exchange the code for a token and fetches basic user information.
|
|
* Attempts to log the user into this app, and creates them if they
|
|
* don't exist. Then redirects the user to the configured post_login url.
|
|
*
|
|
* @TODO fix type hint on request \/
|
|
* @param $request
|
|
* @return mixed
|
|
*/
|
|
public function callback(Request $request)
|
|
{
|
|
// Get the user class from the Laravel auth config
|
|
$user_class = config('auth.providers.users.model');
|
|
|
|
// Verify the passed in state value
|
|
$this->user_flow->validateState($request->state);
|
|
|
|
// TODO: Check for error response
|
|
|
|
// Exchange the code for a token
|
|
$token = $this->user_flow->exchangeCodeForToken(config('authkit.authn.openid.redirect_uri'), $request->code);
|
|
$user_info = $token->getUserInfo();
|
|
|
|
// Try and use the token to find the local user
|
|
$user = \Auth::loginUsingId($token->getUserId());
|
|
|
|
// If that failed
|
|
if ($user === false)
|
|
{
|
|
// User doesn't exist, create them.
|
|
$user = new $user_class();
|
|
$id_field = $user->getAuthIdentifierName();
|
|
$user->{$id_field} = $token->getUserId();
|
|
$user->name = $user_info['name'];
|
|
$user->email = $user_info['email'];
|
|
if ($user instanceof \authkit2\Models\IAuthkitUser)
|
|
{
|
|
$user->{$user->getAccessTokenName()} = $token->getAccessToken();
|
|
$user->{$user->getRefreshTokenName()} = $token->getRefreshToken();
|
|
}
|
|
else
|
|
{
|
|
$user->authkit_access_token = $token->getAccessToken();
|
|
$user->authkit_refresh_token = $token->getRefreshToken();
|
|
}
|
|
$register_event_result = event(new \authkit2\Events\UserRegistration($user));
|
|
if (sizeof($register_event_result))
|
|
{
|
|
foreach ($register_event_result as $result)
|
|
{
|
|
if ($result instanceof $user_class)
|
|
{
|
|
$user = $result;
|
|
}
|
|
}
|
|
}
|
|
if (!$user->exists)
|
|
{
|
|
$user->save();
|
|
}
|
|
\Auth::login($user);
|
|
}
|
|
else
|
|
{
|
|
$user->name = $user_info['name'];
|
|
$user->email = $user_info['email'];
|
|
if ($user instanceof \authkit2\Models\IAuthkitUser)
|
|
{
|
|
$user->{$user->getAccessTokenName()} = $token->getAccessToken();
|
|
$user->{$user->getRefreshTokenName()} = $token->getRefreshToken();
|
|
}
|
|
else
|
|
{
|
|
$user->authkit_access_token = $token->getAccessToken();
|
|
$user->authkit_refresh_token = $token->getRefreshToken();
|
|
}
|
|
$user->save();
|
|
}
|
|
|
|
event(new \authkit2\Events\UserLogin($user));
|
|
|
|
return redirect(url(config('authkit.authn.urls.post_login')));
|
|
}
|
|
|
|
/**
|
|
* Explicitly log out of this application and the SSO service
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function logout()
|
|
{
|
|
event(new \authkit2\Events\UserLogout(\Auth::user()));
|
|
// Log out locally
|
|
\Auth::logout();
|
|
// Redirect to log out remotely as well
|
|
return redirect($this->user_flow->getLogoutUrl(url(config('authkit.authn.urls.post_logout'))));
|
|
}
|
|
}
|
|
|