Browse Source

Add support for IndieAuth authorization for the micropub endpoint

pull/19/head
Eddie Hinkle 6 years ago
parent
commit
2b983da4b4
3 changed files with 133 additions and 11 deletions
  1. +115
    -0
      compass/app/Http/Controllers/Controller.php
  2. +3
    -0
      compass/app/Http/routes.php
  3. +15
    -11
      compass/resources/views/settings.blade.php

+ 115
- 0
compass/app/Http/Controllers/Controller.php View File

@ -200,4 +200,119 @@ class Controller extends BaseController
}
}
public function micropubStart(Request $request, $dbName) {
$me = \IndieAuth\Client::normalizeMeURL($request->input('me'));
if(!$me) {
return view('auth/error', ['error' => 'Invalid URL']);
}
$state = \IndieAuth\Client::generateStateParameter();
$authorizationEndpoint = \IndieAuth\Client::discoverAuthorizationEndpoint($me);
// Isolate session variables to this variable only
session([$dbName => [
'auth_state' => $state,
'attempted_me' => $me,
'authorization_endpoint' => $authorizationEndpoint
]]);
// If the user specified only an authorization endpoint, use that
if(!$authorizationEndpoint) {
// Otherwise, fall back to indieauth.com
$authorizationEndpoint = env('DEFAULT_AUTH_ENDPOINT');
}
$authorizationURL = \IndieAuth\Client::buildAuthorizationURL($authorizationEndpoint, $me, $this->_databaseRedirectURI($dbName), env('BASE_URL'), $state, 'create');
return redirect($authorizationURL);
}
public function micropubCallback(Request $request, $dbName) {
$settingsSession = session($dbName);
// Start all error checking
if(!$settingsSession['auth_state'] || !$settingsSession['attempted_me']) {
return view('auth/error', ['error' => 'Missing state information. Start over.']);
}
if($request->input('error')) {
return view('auth/error', ['error' => $request->input('error')]);
}
if($settingsSession['auth_state'] != $request->input('state')) {
return view('auth/error', ['error' => 'State did not match. Start over.']);
}
// Verify that the database exists and doesn't have micropub already
$db = DB::table('databases')
->where('name','=',$dbName)
->first();
if (!$db) {
return view('auth/error', ['error' => 'Database requested does not exist']);
}
if (!empty($db->micropub_token)) {
return view('auth/error', ['error' => 'Database already is connected to a micropub endpoint. Please remove the existing endpoint first.']);
}
$tokenEndpoint = \IndieAuth\Client::discoverTokenEndpoint($settingsSession['attempted_me']);
if (empty($tokenEndpoint)) {
return view('auth/error', ['error' => 'Could not find user\'s token endpoint']);
}
$token = \IndieAuth\Client::getAccessToken($tokenEndpoint, $request->input('code'), $settingsSession['attempted_me'], $this->_databaseRedirectURI($dbName), env('BASE_URL'));
if($token && array_key_exists('me', $token)) {
// forget the current db settings session
session()->forget($dbName);
if (!array_key_exists('access_token', $token)) {
return view('auth/error', ['error' => 'Could not find access_token']);
}
if (!array_key_exists('scope', $token) || strpos($token['scope'], 'create') === false) {
return view('auth/error', ['error' => 'You were not granted a create scope']);
}
$micropubEndpoint = \IndieAuth\Client::discoverMicropubEndpoint($token['me']);
$micropubToken = $token['access_token'];
DB::table('databases')->where('id', $db->id)
->update([
'micropub_endpoint' => $micropubEndpoint,
'micropub_token' => $micropubToken
]);
} else {
return view('auth/error', ['error' => 'No url id found']);
}
return redirect('/settings/'.$db->name);
}
public function removeMicropub(Request $request, $dbName) {
$db = DB::table('databases')
->where('name','=',$dbName)
->first();
if (!$db) {
return view('auth/error', ['error' => 'Database requested does not exist']);
}
DB::table('databases')->where('id', $db->id)
->update([
'micropub_endpoint' => '',
'micropub_token' => ''
]);
return redirect('/settings/'.$db->name);
}
private function _databaseRedirectURI($dbName) {
return env('BASE_URL') . 'settings/' . $dbName . '/auth/callback';
}
}

+ 3
- 0
compass/app/Http/routes.php View File

@ -10,6 +10,9 @@ $app->get('/auth/logout', 'IndieAuth@logout');
$app->get('/map/{name:[A-Za-z0-9]+}', 'Controller@map');
$app->get('/settings/{name:[A-Za-z0-9]+}', 'Controller@settings');
$app->post('/settings/{name:[A-Za-z0-9]+}', 'Controller@updateSettings');
$app->post('/settings/{name:[A-Za-z0-9]+}/auth/start', 'Controller@micropubStart');
$app->get('/settings/{name:[A-Za-z0-9]+}/auth/callback', 'Controller@micropubCallback');
$app->get('/settings/{name:[A-Za-z0-9]+}/auth/remove', 'Controller@removeMicropub');
$app->post('/database/create', 'Controller@createDatabase');
$app->get('/api/query', 'Api@query');

+ 15
- 11
compass/resources/views/settings.blade.php View File

@ -86,22 +86,26 @@
<h2>Realtime Micropub Export</h2>
<p>Enter a Micropub endpoint and token below and any trips that are written to this database will be sent to the endpoint as well.</p>
<div class="panel">
<form action="/settings/{{ $database->name }}" method="post" class="ui form">
@if (empty($database->micropub_token))
<p>Authorize Compass with a micropub endpoint and any trips that are written to this database will be sent to that endpoint as well.</p>
<form action="/settings/{{ $database->name }}/auth/start" method="post" class="ui form">
<div class="field">
<label for="micropub_endpoint">Micropub Endpoint</label>
<input name="micropub_endpoint" type="url" placeholder="http://example.com/micropub" class="pure-input-1" value="{{ $database->micropub_endpoint }}">
<label for="micropub_endpoint">web sign-in</label>
<input name="me" type="url" placeholder="http://example.com/" class="pure-input-1" value="">
</div>
<div class="field">
<label for="micropub_token">Access Token</label>
<input name="micropub_token" type="text" placeholder="" class="pure-input-1" value="{{ $database->micropub_token }}">
</div>
<button type="submit" class="ui button primary">Save</button>
<button type="submit" class="ui button primary">Connect</button>
</form>
@else
<form action="/settings/{{ $database->name }}/auth/remove" method="get" class="ui form">
<div class="field">
<p>You are currently posting to <strong>{{$database->micropub_endpoint}}</strong>. Any trips that are written to this database will be sent to that endpoint as well.</p>
</div>
<button type="submit" class="ui button primary">Disconnect</button>
</form>
@endif
</div>
<br>

Loading…
Cancel
Save