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.

81 lines
2.6 KiB

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Laravel\Lumen\Routing\Controller as BaseController;
  4. use Illuminate\Http\Request;
  5. class IndieAuth extends BaseController
  6. {
  7. private function _redirectURI() {
  8. return env('BASE_URL') . 'auth/callback';
  9. }
  10. public function start(Request $request) {
  11. $me = \IndieAuth\Client::normalizeMeURL($request->input('me'));
  12. if(!$me) {
  13. return view('auth/error', ['error' => 'Invalid URL']);
  14. }
  15. $authorizationEndpoint = \IndieAuth\Client::discoverAuthorizationEndpoint($me);
  16. $tokenEndpoint = \IndieAuth\Client::discoverTokenEndpoint($me);
  17. $state = \IndieAuth\Client::generateStateParameter();
  18. session([
  19. 'auth_state' => $state,
  20. 'attempted_me' => $me,
  21. 'authorization_endpoint' => $authorizationEndpoint,
  22. 'token_endpoint' => $tokenEndpoint
  23. ]);
  24. // If the user specified only an authorization endpoint, use that
  25. if(!$authorizationEndpoint) {
  26. // Otherwise, fall back to indieauth.com
  27. $authorizationEndpoint = env('DEFAULT_AUTH_ENDPOINT');
  28. }
  29. $authorizationURL = \IndieAuth\Client::buildAuthorizationURL($authorizationEndpoint, $me, $this->_redirectURI(), env('BASE_URL'), $state);
  30. return redirect($authorizationURL);
  31. }
  32. public function callback(Request $request) {
  33. if(!session('auth_state') || !session('attempted_me')) {
  34. return view('auth/error', ['error' => 'Missing state information. Start over.']);
  35. }
  36. if($request->input('error')) {
  37. return view('auth/error', ['error' => $request->input('error')]);
  38. }
  39. if(session('auth_state') != $request->input('state')) {
  40. return view('auth/error', ['error' => 'State did not match. Start over.']);
  41. }
  42. $tokenEndpoint = false;
  43. if(session('token_endpoint')) {
  44. $tokenEndpoint = session('token_endpoint');
  45. } else if(session('authorization_endpoint')) {
  46. $authorizationEndpoint = session('authorization_endpoint');
  47. } else {
  48. $authorizationEndpoint = env('DEFAULT_AUTH_ENDPOINT');
  49. }
  50. if($tokenEndpoint) {
  51. $token = \IndieAuth\Client::getAccessToken($tokenEndpoint, $request->input('code'), session('attempted_me'), $this->_redirectURI(), env('BASE_URL'), $request->input('state'));
  52. } else {
  53. $token = \IndieAuth\Client::verifyIndieAuthCode($authorizationEndpoint, $request->input('code'), session('attempted_me'), $this->_redirectURI(), env('BASE_URL'), $request->input('state'));
  54. }
  55. if($token && array_key_exists('me', $token)) {
  56. session()->flush();
  57. session(['me' => $token['me']]);
  58. }
  59. return redirect('/');
  60. }
  61. public function logout(Request $request) {
  62. session()->flush();
  63. return redirect('/');
  64. }
  65. }