2016-05-19 15:01:28 +01:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use App\Services\TokenService;
|
|
|
|
|
use App\Services\IndieAuthService;
|
|
|
|
|
|
|
|
|
|
class IndieAuthController extends Controller
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* This service isolates the IndieAuth Client code.
|
|
|
|
|
*/
|
|
|
|
|
protected $indieAuthService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The Token handling service.
|
|
|
|
|
*/
|
|
|
|
|
protected $tokenService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Inject the dependencies.
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Services\IndieAuthService $indieAuthService
|
2017-03-01 20:59:09 +00:00
|
|
|
|
* @param \App\Services\TokenService $tokenService
|
2016-05-19 15:01:28 +01:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(
|
|
|
|
|
IndieAuthService $indieAuthService = null,
|
|
|
|
|
TokenService $tokenService = null
|
|
|
|
|
) {
|
|
|
|
|
$this->indieAuthService = $indieAuthService ?? new IndieAuthService();
|
|
|
|
|
$this->tokenService = $tokenService ?? new TokenService();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Begin the indie auth process. This method ties in to the login page
|
|
|
|
|
* from our micropub client. Here we then query the user’s homepage
|
|
|
|
|
* for their authorisation endpoint, and redirect them there with a
|
|
|
|
|
* unique secure state value.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return \Illuminate\Routing\RedirectResponse redirect
|
|
|
|
|
*/
|
2017-02-16 15:35:25 +00:00
|
|
|
|
public function start(Request $request)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
{
|
|
|
|
|
$authorizationEndpoint = $this->indieAuthService->getAuthorizationEndpoint(
|
2017-03-01 20:59:09 +00:00
|
|
|
|
$request->input('me')
|
2016-05-19 15:01:28 +01:00
|
|
|
|
);
|
2017-03-01 20:59:09 +00:00
|
|
|
|
if ($authorizationEndpoint !== null) {
|
2016-05-19 15:01:28 +01:00
|
|
|
|
$authorizationURL = $this->indieAuthService->buildAuthorizationURL(
|
|
|
|
|
$authorizationEndpoint,
|
2017-03-01 20:59:09 +00:00
|
|
|
|
$request->input('me')
|
2016-05-19 15:01:28 +01:00
|
|
|
|
);
|
|
|
|
|
if ($authorizationURL) {
|
|
|
|
|
return redirect($authorizationURL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-01 20:59:09 +00:00
|
|
|
|
return redirect(route('micropub-client'))->with('error', 'Unable to determine authorisation endpoint');
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Once they have verified themselves through the authorisation endpint
|
|
|
|
|
* the next step is retreiveing a token from the token endpoint.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Rrequest $request
|
|
|
|
|
* @return \Illuminate\Routing\RedirectResponse redirect
|
|
|
|
|
*/
|
2017-02-16 15:35:25 +00:00
|
|
|
|
public function callback(Request $request)
|
2016-05-19 15:01:28 +01:00
|
|
|
|
{
|
|
|
|
|
if ($request->session()->get('state') != $request->input('state')) {
|
2017-03-01 20:59:09 +00:00
|
|
|
|
return redirect(route('micropub-client'))->with(
|
|
|
|
|
'error',
|
|
|
|
|
'Invalid <code>state</code> value returned from indieauth server'
|
2016-05-19 15:01:28 +01:00
|
|
|
|
);
|
|
|
|
|
}
|
2017-03-01 20:59:09 +00:00
|
|
|
|
$tokenEndpoint = $this->indieAuthService->getTokenEndpoint($request->input('me'));
|
2017-02-16 15:35:25 +00:00
|
|
|
|
if ($tokenEndpoint === false) {
|
2017-03-01 20:59:09 +00:00
|
|
|
|
return redirect(route('micropub-client'))->with(
|
|
|
|
|
'error',
|
|
|
|
|
'Unable to determine token endpoint'
|
|
|
|
|
);
|
2017-02-16 15:35:25 +00:00
|
|
|
|
}
|
2016-05-19 15:01:28 +01:00
|
|
|
|
$data = [
|
|
|
|
|
'endpoint' => $tokenEndpoint,
|
|
|
|
|
'code' => $request->input('code'),
|
|
|
|
|
'me' => $request->input('me'),
|
2017-02-16 15:35:25 +00:00
|
|
|
|
'redirect_url' => route('indieauth-callback'),
|
|
|
|
|
'client_id' => route('micropub-client'),
|
2016-05-19 15:01:28 +01:00
|
|
|
|
'state' => $request->input('state'),
|
|
|
|
|
];
|
2017-03-01 20:59:09 +00:00
|
|
|
|
$token = $this->indieAuthService->getAccessToken($data);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
|
|
|
|
|
if (array_key_exists('access_token', $token)) {
|
|
|
|
|
$request->session()->put('me', $token['me']);
|
|
|
|
|
$request->session()->put('token', $token['access_token']);
|
|
|
|
|
|
2017-02-16 15:35:25 +00:00
|
|
|
|
return redirect(route('micropub-client'));
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-01 20:59:09 +00:00
|
|
|
|
return redirect(route('micropub-client'))->with(
|
|
|
|
|
'error',
|
|
|
|
|
'Unable to get a token from the endpoint'
|
|
|
|
|
);
|
2017-02-16 15:35:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Log out the user, flush an session data, and overwrite any cookie data.
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Routing\RedirectResponse redirect
|
|
|
|
|
*/
|
|
|
|
|
public function logout(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$request->session()->flush();
|
|
|
|
|
|
|
|
|
|
return redirect(route('micropub-client'))->cookie('me', 'loggedout', 1);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If the user has auth’d via IndieAuth, issue a valid token.
|
|
|
|
|
*
|
|
|
|
|
* @param \Illuminate\Http\Request $request
|
|
|
|
|
* @return \Illuminate\Http\Response
|
|
|
|
|
*/
|
|
|
|
|
public function tokenEndpoint(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$authData = [
|
|
|
|
|
'code' => $request->input('code'),
|
|
|
|
|
'me' => $request->input('me'),
|
|
|
|
|
'redirect_url' => $request->input('redirect_uri'),
|
|
|
|
|
'client_id' => $request->input('client_id'),
|
|
|
|
|
'state' => $request->input('state'),
|
|
|
|
|
];
|
2017-03-01 20:59:09 +00:00
|
|
|
|
$auth = $this->indieAuthService->verifyIndieAuthCode($authData);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
if (array_key_exists('me', $auth)) {
|
|
|
|
|
$scope = $auth['scope'] ?? '';
|
|
|
|
|
$tokenData = [
|
|
|
|
|
'me' => $request->input('me'),
|
|
|
|
|
'client_id' => $request->input('client_id'),
|
|
|
|
|
'scope' => $auth['scope'],
|
|
|
|
|
];
|
|
|
|
|
$token = $this->tokenService->getNewToken($tokenData);
|
|
|
|
|
$content = http_build_query([
|
|
|
|
|
'me' => $request->input('me'),
|
|
|
|
|
'scope' => $scope,
|
|
|
|
|
'access_token' => $token,
|
|
|
|
|
]);
|
|
|
|
|
|
2017-02-16 15:35:25 +00:00
|
|
|
|
return response($content)
|
|
|
|
|
->header('Content-Type', 'application/x-www-form-urlencoded');
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
$content = 'There was an error verifying the authorisation code.';
|
|
|
|
|
|
2017-02-16 15:35:25 +00:00
|
|
|
|
return response($content, 400);
|
2016-05-19 15:01:28 +01:00
|
|
|
|
}
|
|
|
|
|
}
|