jonnybarnes.uk/app/Http/Controllers/MicropubController.php

204 lines
7.6 KiB
PHP
Raw Normal View History

2016-05-19 15:01:28 +01:00
<?php
namespace App\Http\Controllers;
use App\Place;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Services\NoteService;
use App\Services\TokenService;
use App\Services\PlaceService;
class MicropubController extends Controller
{
/**
* The Token service container.
*/
protected $tokenService;
/**
* The Note service container.
*/
protected $noteService;
/**
* The Place service container.
*/
protected $placeService;
/**
* Inject the dependencies.
2016-05-19 15:01:28 +01:00
*/
public function __construct(
TokenService $tokenService = null,
NoteService $noteService = null,
PlaceService $placeService = null
) {
$this->tokenService = $tokenService ?? new TokenService();
$this->noteService = $noteService ?? new NoteService();
$this->placeService = $placeService ?? new PlaceService();
}
/**
* This function receives an API request, verifies the authenticity
* then passes over the info to the relavent Service class.
*
* @param \Illuminate\Http\Request request
* @return \Illuminate\Http\Response
*/
public function post(Request $request)
{
$httpAuth = $request->header('Authorization');
if (preg_match('/Bearer (.+)/', $httpAuth, $match)) {
$token = $match[1];
$tokenData = $this->tokenService->validateToken($token);
if ($tokenData->hasClaim('scope')) {
$scopes = explode(' ', $tokenData->getClaim('scope'));
if (array_search('post', $scopes) !== false) {
$clientId = $tokenData->getClaim('client_id');
if (($request->input('h') == 'entry') || ($request->input('type')[0] == 'h-entry')) {
try {
$note = $this->noteService->createNote($request, $clientId);
} catch (Exception $exception) {
return response()->json(['error' => true], 400);
}
return response()->json([
'response' => 'created',
2016-09-23 16:58:50 +01:00
'location' => $note->longurl,
], 201)->header('Location', $note->longurl);
2016-05-19 15:01:28 +01:00
}
if ($request->input('h') == 'card' || $request->input('type')[0] == 'h-card') {
try {
$place = $this->placeService->createPlace($request);
} catch (Exception $exception) {
return response()->json(['error' => true], 400);
}
2016-05-19 15:01:28 +01:00
return response()->json([
'response' => 'created',
2016-09-23 16:58:50 +01:00
'location' => $place->longurl,
], 201)->header('Location', $place->longurl);
2016-05-19 15:01:28 +01:00
}
}
}
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
2016-09-23 16:58:50 +01:00
'error_description' => 'The token provided is not valid or does not have the necessary scope',
], 400);
2016-05-19 15:01:28 +01:00
}
return response()->json([
'response' => 'error',
'error' => 'no_token',
2016-09-23 16:58:50 +01:00
'error_description' => 'No OAuth token sent with request',
], 400);
2016-05-19 15:01:28 +01:00
}
/**
* A GET request has been made to `api/post` with an accompanying
* token, here we check wether the token is valid and respond
* appropriately. Further if the request has the query parameter
* synidicate-to we respond with the known syndication endpoints.
*
* @todo Move the syndication endpoints into a .env variable
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function getEndpoint(Request $request)
{
$httpAuth = $request->header('Authorization');
if (preg_match('/Bearer (.+)/', $httpAuth, $match)) {
$token = $match[1];
$valid = $this->tokenService->validateToken($token);
if ($valid === null) {
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
2016-10-03 18:04:50 +01:00
'error_description' => 'The provided token did not pass validation',
], 400);
2016-05-19 15:01:28 +01:00
}
//we have a valid token, is `syndicate-to` set?
if ($request->input('q') === 'syndicate-to') {
return response()->json([
'syndicate-to' => [[
'uid' => 'https://twitter.com/jonnybarnes',
'name' => 'jonnybarnes on Twitter',
'service' => [
'name' => 'Twitter',
'url' => 'https://twitter.com',
'photo' => 'https://upload.wikimedia.org/wikipedia/en/9/9f/Twitter_bird_logo_2012.svg',
],
'user' => [
'name' => 'jonnybarnes',
'url' => 'https://twitter.com/jonnybarnes',
'photo' => 'https://pbs.twimg.com/profile_images/1853565405/jmb-bw.jpg',
],
]],
2016-05-19 15:01:28 +01:00
]);
}
//nope, how about a geo URL?
if (substr($request->input('q'), 0, 4) === 'geo:') {
Squashed commit of the following: commit e7f1c4c84579b959fe2997ff4d2315ee53acfe9a Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Sep 29 11:22:44 2016 +0100 Add latest change, fix spelling errors in rest of changelog commit 637b5107b557f1c2a56327a40b3d7b4b7297fa29 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 21:13:06 2016 +0100 Add a test for uncertainty parameter commit 5e7504b323debf9c91e0cca428b4dca7dda0789d Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 21:11:12 2016 +0100 Format the ternaty operator correctly commit 19c978a5ac59cd7dfdceee9a8f1aaa6539d8ac66 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 20:46:19 2016 +0100 Fix typo commit d4e5b5fc384d0ccd715ea28a51821f958f6c2caa Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 20:41:23 2016 +0100 Add paraphanalia commit a96f104894de6c06dc5e41044482de2355cb4965 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 20:35:17 2016 +0100 Add the geolocation uncertainty to nearby places request commit 0f6d5649e2f3316040d7453f5fcc96ac1f0ac783 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 20:34:38 2016 +0100 Use a query parameter for geolocation uncertainty commit a9147a074315fabb0d76e5991b34a70b2143761c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 19:58:08 2016 +0100 Make use of uncertainty parameter when finding nearby places commit bad384b5d8be3ea8905d8f6ca3c20f448869853d Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Sep 28 19:28:42 2016 +0100 Support sending uncertainty value to micropub endpoint
2016-09-29 11:28:31 +01:00
preg_match_all(
'/([0-9\.\-]+)/',
$request->input('q'),
$matches
);
$distance = (count($matches[0]) == 3) ? 100 * $matches[0][2] : 1000;
$places = Place::near($matches[0][0], $matches[0][1], $distance);
foreach ($places as $place) {
$place->uri = config('app.url') . '/place/' . $place->slug;
}
2016-05-19 15:01:28 +01:00
return response()->json([
'response' => 'places',
2016-07-04 16:23:54 +01:00
'places' => $places,
]);
2016-05-19 15:01:28 +01:00
}
2016-07-04 15:35:17 +01:00
//nope, ho about a config query?
if ($request->input('q') == 'config') {
return response()->json([
'syndicate-to' => [[
'uid' => 'https://twitter.com/jonnybarnes',
'name' => 'jonnybarnes on Twitter',
'service' => [
'name' => 'Twitter',
'url' => 'https://twitter.com',
'photo' => 'https://upload.wikimedia.org/wikipedia/en/9/9f/Twitter_bird_logo_2012.svg',
],
'user' => [
'name' => 'jonnybarnes',
'url' => 'https://twitter.com/jonnybarnes',
'photo' => 'https://pbs.twimg.com/profile_images/1853565405/jmb-bw.jpg',
],
]],
]);
}
2016-05-19 15:01:28 +01:00
//nope, just return the token
return response()->json([
'response' => 'token',
'token' => [
'me' => $valid->getClaim('me'),
'scope' => $valid->getClaim('scope'),
'client_id' => $valid->getClaim('client_id'),
],
2016-05-19 15:01:28 +01:00
]);
}
$content = 'No OAuth token sent with request.';
2016-07-04 16:23:54 +01:00
$content = <<<'EOD'
{
"response": "error",
"error": "no_token",
"error_description": "No token provided with request"
}
EOD;
2016-05-19 15:01:28 +01:00
return (new Response($content, 400))
->header('Content-Type', 'application/json');
2016-05-19 15:01:28 +01:00
}
}