commit 1eecb177b6d5aed8fd7ced14ba5a3fb8d528521b Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 16:19:29 2017 +0100 Fix some Style issues commit 490ca7b8e90b08ad1e59714e09ba49a853cb753e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 16:06:13 2017 +0100 Run check on POST as well GET methods commit fb588798ce4e6548a0e0be8ec00673b24a41fe40 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 16:04:47 2017 +0100 Check for exceptions when validating token commit da2ce1a2893c03ae058c07361d860f4e509ac0ee Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:57:27 2017 +0100 Go back to doing all dusk tests commit c34fbf519a0cc528c49e8d5d9628a8891540c294 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:53:17 2017 +0100 Don’t check for error message now commit bd48859f7faf279296c0a15f2f6b18f83a951ebd Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:49:23 2017 +0100 Escape the facade call with backslash commit fcb405d8caf0d23cb70abb67da35cc68e2e86e4f Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:43:19 2017 +0100 Regenerate the token within dusk commit 8732f100a075742802447e65a2ba56b7cc69149a Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:36:39 2017 +0100 Slight refactor of token verification commit cb0ec39bba5765d55ad024fe3d73ad81877034da Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:29:46 2017 +0100 Stupid forgetting to root the namespace commit 1f2b309d7e77ff195ac8a4aa2f755044d15b4b92 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:22:54 2017 +0100 Try throwing my own exception commit 41dab30389cd04746051b8552e605eb3693ad0f1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:12:18 2017 +0100 Checked headers commit 5eb12543adf999c4887a1e63b8d174fb7321202b Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:08:37 2017 +0100 Don’t catch exceptions commit 71dbf8d08a7eed9f3795f06811431b7a3c2ddd6c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 15:00:22 2017 +0100 Log headers for request commit 1109a394456dd07375ccfab5a8436a902f3b27ce Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:54:19 2017 +0100 Add laravels own logs to the artifacts commit f6cd9ee81385bf4366e0e59fc6c34c9b56b6e52c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:38:18 2017 +0100 Log error commit dadf3b3150c74d2199a87a529151d55fc1e67394 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:33:14 2017 +0100 Look for different error message commit 9df2d1b831e6c65283fb5438967f4517752c31ac Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:24:15 2017 +0100 Look for different error message commit 090736735fe3cc5fb4076b77730f7e39bc92d80c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:14:14 2017 +0100 Just checking error message commit 6a766b1bc4af3dd0e335b3f57287086a6e528340 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:08:16 2017 +0100 Look for error message commit a399af496a440e30a0c0a1d4050121b3e491e968 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 14:00:29 2017 +0100 Simpler setup of php error log commit 3472c48ed50466c2d150e727cb6c1e43b1298d4c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 13:45:11 2017 +0100 Set the php error log commit 978c17f33e2d9c3dd5166744aef924bf21483737 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 13:37:04 2017 +0100 Set the php-fpm error log commit 0e3407a4781f83bf3c516578a4594eff92b9d4d8 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 13:18:45 2017 +0100 Save a token for the user commit 951fe7966e18ac9e38526b6dfdc4a75fd4d68a0c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 12:56:49 2017 +0100 Use the right phrase commit faedc802a46c35b3b9264348ebbd895f4d2b3895 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 12:41:03 2017 +0100 Easier phrase to find in log commit 71b3c905bb4be0943254e51604af1293cc63cd0f Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 12:35:07 2017 +0100 Check we are logged in commit fd6e3c79f13b9aada395a53b367e316936787298 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 12:20:14 2017 +0100 Cleanup output commit 231ac5868070f232f5bd455f0d6070621da9ae91 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 21 12:00:36 2017 +0100 Try pausing test before running second check commit 754cbafacdb8dd46db2eee699b8e23009c7d0bf5 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Apr 20 13:15:10 2017 +0100 Temporary fix for TLS issues on travis-ci and sensiolab’s security checker commit 8e03bba917ca9ba951bac5197e0008ae7188e19a Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 19 21:24:51 2017 +0100 Use less strict check on no auth endpoint being found commit 91ee495ae1302f269febdd0e14ecbe81222b1014 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 19 21:23:44 2017 +0100 Use newer scope values in token commit 989a242b4ff271f4ac6ee0873dc2924506c0efcf Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Apr 18 22:30:53 2017 +0100 Missed some array syntax commit 92d11c9a62c2a122b4fef62da8af6bf4be23288d Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Apr 18 22:21:43 2017 +0100 Fix some styleci issues commit 3a3aa8daca981561594cf3fb542c3e240b174013 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Apr 18 21:50:31 2017 +0100 Allow client to send request with JSON syntax, cleanup a but of other code commit dcc3baf2dc554175fdd1de408cb4f7170a6540d4 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Apr 18 21:47:51 2017 +0100 composer update commit b89dbb6b7a4940b5eed30727f0bd67bc382d98bc Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Apr 14 09:50:39 2017 +0100 wip commit 87eb63dc9570f6822324d665bc1658cfcb446554 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Apr 13 18:44:15 2017 +0100 Allow the syntax for the endpoint to be set in the config page commit 9595a0b68e4b51d77c18e63f9940026aa1325475 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Apr 13 17:17:34 2017 +0100 Use better scope values in command commit 08e2223a8d56984df826c1cd876f58b00cce8faf Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 21:53:44 2017 +0100 Get media uploads working again commit 4c0d6861324c23afe4145c4ff9a46d8a1ecc10e9 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 21:09:16 2017 +0100 Show syndication targets properlu in client form and config page commit 63939316a0818c8dfa8cba9919b231c2fdad5821 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 21:08:40 2017 +0100 Update prism, recompress assets commit 74902237cb227e05386135fb0e2d5330b65e1c4e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 17:58:41 2017 +0100 Better presentation of syndication targets commit 345cda342051af406d6616a9162a75af625a64e0 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 17:47:12 2017 +0100 yarn upgrade commit 17de68cc8f26cc472b009bf42942778fac75c890 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Wed Apr 12 17:42:49 2017 +0100 composer update commit 7da78294dfdda8c68fc411ab03db65f101c7fc4c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:34:56 2017 +0100 Move to using indieauth-client-php client directly, add code to get new tokens commit 0020596b52c1590936d12ec9c458b7e70a06bc8e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:31:40 2017 +0100 Add routes for retreiving a new token commit ee0a6763f037629e2a97fa8536c84cbffbbbd7e2 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:30:33 2017 +0100 Show syndication targets as an unformated json string commit 765d032fa883db834a005f61dc553b3b0ef9ee8e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:29:21 2017 +0100 Add a migratin for the indieweb users commit 3a5c458f132cf6c308c2e83eb57c61ae64cc2b48 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:28:51 2017 +0100 Add a normlize_url helper function commit fb71bd6418e7903b7d50a90dd600a82a8af03d38 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 10 18:27:41 2017 +0100 Add a token to the users table commit 56df9e8aa453394f8b83e8f6a28cc41c66d172f1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 3 09:18:06 2017 +0100 Set default values for config screen commit 0df8217a82cac91c3129acc492b73d6e8cb69b44 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 3 09:17:14 2017 +0100 Use the helper function to normalize URLs commit d5f882972ec43e766ae7b9288b1ab3645dd471cf Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 3 09:15:41 2017 +0100 In a dev environment automatically log in as the pre-created user commit 2c3379d0e560226a4db181e7d45ce02b575990ae Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 3 09:14:13 2017 +0100 Add a default user of me commit 5c955803a8218c477e2f2b126811e6bed5f20379 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Apr 3 09:13:08 2017 +0100 Add a helpers file, currently only has a function to normalize URLs commit ae052d305c835952c83602d305cfdb08d5be975e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Mar 31 16:08:30 2017 +0100 Allow a user to register/login with his domain commit 638ab8085f18c1bdf9c036c0272a8e88079013f5 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Mar 28 16:51:42 2017 +0100 Work on allowing people to “register” for the client
540 lines
18 KiB
PHP
540 lines
18 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers;
|
||
|
||
use App\IndieWebUser;
|
||
use IndieAuth\Client as IndieClient;
|
||
use GuzzleHttp\Client as GuzzleClient;
|
||
use Illuminate\Http\{Request, Response};
|
||
use GuzzleHttp\Exception\{ClientException, ServerException};
|
||
|
||
class MicropubClientController extends Controller
|
||
{
|
||
/**
|
||
* Inject the dependencies.
|
||
*/
|
||
public function __construct(
|
||
IndieClient $indieClient = null,
|
||
GuzzleClient $guzzleClient = null
|
||
) {
|
||
$this->guzzleClient = $guzzleClient ?? new GuzzleClient();
|
||
$this->indieClient = $indieClient ?? new IndieClient();
|
||
}
|
||
|
||
/**
|
||
* Display the new notes form.
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\View\Factory view
|
||
*/
|
||
public function create(Request $request)
|
||
{
|
||
$url = $request->session()->get('me');
|
||
if ($url) {
|
||
$indiewebUser = IndieWebUser::where('me', $url)->first();
|
||
}
|
||
$syndication = $this->parseSyndicationTargets($indiewebUser->syndication);
|
||
$mediaEndpoint = $indiewebUser->mediaEndpoint ?? null;
|
||
$mediaURLs = $request->session()->get('media-links');
|
||
|
||
return view('micropub.create', compact('url', 'syndication', 'mediaEndpoint', 'mediaURLs'));
|
||
}
|
||
|
||
/**
|
||
* Process an upload to the media endpoint.
|
||
*
|
||
* @param Illuminate\Http\Request $request
|
||
* @return Illuminate\Http\Response
|
||
*/
|
||
public function processMedia(Request $request)
|
||
{
|
||
if ($request->hasFile('file') == false) {
|
||
return back();
|
||
}
|
||
|
||
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
|
||
if ($user->mediaEndpoint == null || $user->token == null) {
|
||
return back();
|
||
}
|
||
|
||
$mediaURLs = [];
|
||
foreach ($request->file('file') as $file) {
|
||
try {
|
||
$response = $this->guzzleClient->request('POST', $user->mediaEndpoint, [
|
||
'headers' => [
|
||
'Authorization' => 'Bearer ' . $user->token,
|
||
],
|
||
'multipart' => [
|
||
[
|
||
'name' => 'file',
|
||
'contents' => fopen($file->path(), 'r'),
|
||
'filename' => $file->getClientOriginalName(),
|
||
],
|
||
],
|
||
]);
|
||
} catch (ClientException | ServerException $e) {
|
||
continue;
|
||
}
|
||
|
||
$mediaURLs[] = $response->getHeader('Location')[0];
|
||
}
|
||
|
||
$storedMediaURLs = $request->session()->get('media-links') ?? [];
|
||
$mediaURLsToSave = array_merge($storedMediaURLs, $mediaURLs);
|
||
$request->session()->put('media-links', $mediaURLsToSave);
|
||
|
||
return redirect(route('micropub-client'));
|
||
}
|
||
|
||
public function clearLinks(Request $request)
|
||
{
|
||
$request->session()->forget('media-links');
|
||
|
||
return redirect(route('micropub-client'));
|
||
}
|
||
|
||
/**
|
||
* Post the notes content to the relavent micropub API endpoint.
|
||
*
|
||
* @todo make sure this works with multiple syndication targets
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return mixed
|
||
*/
|
||
public function store(Request $request)
|
||
{
|
||
$url = normalize_url($request->session()->get('me'));
|
||
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
||
|
||
if ($user->token == null) {
|
||
return redirect(route('micropub-client'))->with('error', 'You haven’t requested a token yet');
|
||
}
|
||
|
||
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
||
if (! $micropubEndpoint) {
|
||
return redirect(route('micropub-client'))->with('error', 'Unable to determine micropub API endpoint');
|
||
}
|
||
|
||
$headers = [
|
||
'Authorization' => 'Bearer ' . $user->token,
|
||
];
|
||
|
||
if ($user->syntax == 'html') {
|
||
$multipart = [
|
||
[
|
||
'name' => 'h',
|
||
'contents' => 'entry',
|
||
],
|
||
[
|
||
'name' => 'content',
|
||
'contents' => $request->input('content'),
|
||
],
|
||
];
|
||
if ($request->hasFile('photo')) {
|
||
$photos = $request->file('photo');
|
||
foreach ($photos as $photo) {
|
||
$multipart[] = [
|
||
'name' => 'photo[]',
|
||
'contents' => fopen($photo->path(), 'r'),
|
||
'filename' => $photo->getClientOriginalName(),
|
||
];
|
||
}
|
||
}
|
||
if ($request->input('in-reply-to') != '') {
|
||
$multipart[] = [
|
||
'name' => 'in-reply-to',
|
||
'contents' => $request->input('in-reply-to'),
|
||
];
|
||
}
|
||
if ($request->input('mp-syndicate-to')) {
|
||
foreach ($request->input('mp-syndicate-to') as $syn) {
|
||
$multipart[] = [
|
||
'name' => 'mp-syndicate-to[]',
|
||
'contents' => $syn,
|
||
];
|
||
}
|
||
}
|
||
if ($request->input('location')) {
|
||
if ($request->input('location') !== 'no-location') {
|
||
$multipart[] = [
|
||
'name' => 'location',
|
||
'contents' => $request->input('location'),
|
||
];
|
||
}
|
||
}
|
||
if ($request->input('media')) {
|
||
foreach ($request->input('media') as $media) {
|
||
$multipart[] = [
|
||
'name' => 'photo[]',
|
||
'contents' => $media,
|
||
];
|
||
}
|
||
}
|
||
try {
|
||
$response = $this->guzzleClient->post($micropubEndpoint, [
|
||
'multipart' => $multipart,
|
||
'headers' => $headers,
|
||
]);
|
||
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
||
return redirect(route('micropub-client'))->with(
|
||
'error',
|
||
'There was a bad response from the micropub endpoint.'
|
||
);
|
||
}
|
||
|
||
if ($response->getStatusCode() == 201) {
|
||
$request->session()->forget('media-links');
|
||
$location = $response->getHeader('Location');
|
||
if (is_array($location)) {
|
||
return redirect($location[0]);
|
||
}
|
||
|
||
return redirect($location);
|
||
}
|
||
}
|
||
|
||
if ($user->syntax == 'json') {
|
||
$json = [];
|
||
$json['type'] = ['h-entry'];
|
||
$json['properties'] = ['content' => [$request->input('content')]];
|
||
|
||
if ($request->input('in-reply-to') != '') {
|
||
$json['properties']['in-reply-to'] = [$request->input('in-reply-to')];
|
||
}
|
||
if ($request->input('mp-syndicate-to')) {
|
||
foreach ($request->input('mp-syndicate-to') as $syn) {
|
||
$json['properties']['mp-syndicate-to'] = [$syn];
|
||
}
|
||
}
|
||
if ($request->input('location')) {
|
||
if ($request->input('location') !== 'no-location') {
|
||
$json['properties']['location'] = [$request->input('location')];
|
||
}
|
||
}
|
||
if ($request->input('media')) {
|
||
$json['properties']['photo'] = [];
|
||
foreach ($request->input('media') as $media) {
|
||
$json['properties']['photo'][] = $media;
|
||
}
|
||
}
|
||
|
||
try {
|
||
$response = $this->guzzleClient->post($micropubEndpoint, [
|
||
'json' => $json,
|
||
'headers' => $headers,
|
||
]);
|
||
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
||
return redirect(route('micropub-client'))->with(
|
||
'error',
|
||
'There was a bad response from the micropub endpoint.'
|
||
);
|
||
}
|
||
|
||
if ($response->getStatusCode() == 201) {
|
||
$request->session()->forget('media-links');
|
||
$location = $response->getHeader('Location');
|
||
if (is_array($location)) {
|
||
return redirect($location[0]);
|
||
}
|
||
|
||
return redirect($location);
|
||
}
|
||
}
|
||
|
||
return redirect(route('micropub-client'))->with('error', 'Endpoint didn’t create the note.');
|
||
}
|
||
|
||
/**
|
||
* Show currently stored configuration values.
|
||
*
|
||
* @param Illuminate\Http\Request $request
|
||
* @return view
|
||
*/
|
||
public function config(Request $request)
|
||
{
|
||
//default values
|
||
$data = [
|
||
'me' => '',
|
||
'token' => 'none',
|
||
'syndication' => 'none defined',
|
||
'media-endpoint' => 'none defined',
|
||
'syntax' => 'html',
|
||
];
|
||
if ($request->session()->has('me')) {
|
||
$data['me'] = normalize_url($request->session()->get('me'));
|
||
$user = IndieWebUser::where('me', $request->session()->get('me'))->first();
|
||
$data['token'] = $user->token ?? 'none defined';
|
||
$data['syndication'] = $user->syndication ?? 'none defined';
|
||
$data['media-endpoint'] = $user->mediaEndpoint ?? 'none defined';
|
||
$data['syntax'] = $user->syntax;
|
||
}
|
||
|
||
return view('micropub.config', compact('data'));
|
||
}
|
||
|
||
/**
|
||
* Get a new token.
|
||
*
|
||
* @param Illuminate\Http\Request $request
|
||
* @return view
|
||
*/
|
||
public function getNewToken(Request $request)
|
||
{
|
||
if ($request->session()->has('me')) {
|
||
$url = normalize_url($request->session()->get('me'));
|
||
$authozationEndpoint = $this->indieClient->discoverAuthorizationEndpoint($url);
|
||
if ($authozationEndpoint) {
|
||
$state = bin2hex(random_bytes(16));
|
||
$request->session()->put('state', $state);
|
||
$authorizationURL = $this->indieClient->buildAuthorizationURL(
|
||
$authozationEndpoint,
|
||
$url,
|
||
route('micropub-client-get-new-token-callback'), // redirect_uri
|
||
route('micropub-client'), //client_id
|
||
$state,
|
||
'create update' // scope needs to be a setting
|
||
);
|
||
|
||
return redirect($authorizationURL);
|
||
}
|
||
|
||
return back();
|
||
}
|
||
|
||
return back();
|
||
}
|
||
|
||
/**
|
||
* The callback for getting a token.
|
||
*/
|
||
public function getNewTokenCallback(Request $request)
|
||
{
|
||
if ($request->input('state') !== $request->session()->get('state')) {
|
||
return route('micropub-client')->with('error', 'The <code>state</code> didn’t match.');
|
||
}
|
||
$tokenEndpoint = $this->indieClient->discoverTokenEndpoint(normalize_url($request->input('me')));
|
||
if ($tokenEndpoint) {
|
||
$token = $this->indieClient->getAccessToken(
|
||
$tokenEndpoint,
|
||
$request->input('code'),
|
||
$request->input('me'),
|
||
route('micropub-client-get-new-token-callback'), // redirect_uri
|
||
route('micropub-client'), // client_id
|
||
$request->input('state')
|
||
);
|
||
if (array_key_exists('access_token', $token)) {
|
||
$url = normalize_url($token['me']);
|
||
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
||
$user->token = $token['access_token'];
|
||
$user->save();
|
||
|
||
return redirect('micropub-config');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Query the micropub endpoint and store response.
|
||
*
|
||
* @param Illuminate\Http\Request $request
|
||
* @return redirect
|
||
*/
|
||
public function queryEndpoint(Request $request)
|
||
{
|
||
$url = normalize_url($request->session()->get('me'));
|
||
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
||
$token = $user->token;
|
||
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
||
if ($micropubEndpoint) {
|
||
try {
|
||
$response = $this->guzzleClient->get($micropubEndpoint, [
|
||
'headers' => ['Authorization' => 'Bearer ' . $token],
|
||
'query' => 'q=config',
|
||
]);
|
||
} catch (ClientException | ServerException $e) {
|
||
return back();
|
||
}
|
||
$body = (string) $response->getBody();
|
||
$data = json_decode($body, true);
|
||
|
||
if (array_key_exists('syndicate-to', $data)) {
|
||
$user->syndication = json_encode($data['syndicate-to']);
|
||
}
|
||
|
||
if (array_key_exists('media-endpoint', $data)) {
|
||
$user->mediaEndpoint = $data['media-endpoint'];
|
||
}
|
||
$user->save();
|
||
|
||
return back();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Update the syntax setting.
|
||
*
|
||
* @param Illuminate\Http\Request $request
|
||
* @return Illuminate\Http\RedirectResponse
|
||
* @todo validate input
|
||
*/
|
||
public function updateSyntax(Request $request)
|
||
{
|
||
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
|
||
$user->syntax = $request->syntax;
|
||
$user->save();
|
||
|
||
return redirect(route('micropub-config'));
|
||
}
|
||
|
||
/**
|
||
* Create a new place.
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return mixed
|
||
*/
|
||
public function newPlace(Request $request)
|
||
{
|
||
$url = normalize_url($request->session()->get('me'));
|
||
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
||
|
||
if ($user->token === null) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'No known token',
|
||
], 400);
|
||
}
|
||
|
||
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
||
if (! $micropubEndpoint) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'Could not determine the micropub endpoint.',
|
||
], 400);
|
||
}
|
||
|
||
$formParams = [
|
||
'h' => 'card',
|
||
'name' => $request->input('place-name'),
|
||
'description' => $request->input('place-description'),
|
||
'geo' => 'geo:' . $request->input('place-latitude') . ',' . $request->input('place-longitude'),
|
||
];
|
||
$headers = [
|
||
'Authorization' => 'Bearer ' . $user->token,
|
||
];
|
||
try {
|
||
$response = $this->guzzleClient->request('POST', $micropubEndpoint, [
|
||
'form_params' => $formParams,
|
||
'headers' => $headers,
|
||
]);
|
||
} catch (ClientException $e) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'Unable to create the new place',
|
||
], 400);
|
||
}
|
||
$place = $response->getHeader('Location')[0];
|
||
|
||
return response()->json([
|
||
'uri' => $place,
|
||
'name' => $request->input('place-name'),
|
||
'latitude' => $request->input('place-latitude'),
|
||
'longitude' => $request->input('place-longitude'),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Make a request to the micropub endpoint requesting any nearby places.
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\Response
|
||
*/
|
||
public function nearbyPlaces(Request $request)
|
||
{
|
||
$url = normalize_url($request->session()->get('me'));
|
||
$user = IndieWebUser::where('me', $url)->firstOrFail();
|
||
|
||
if ($user->token === null) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'No known token',
|
||
], 400);
|
||
}
|
||
|
||
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
|
||
|
||
if (! $micropubEndpoint) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'No known endpoint',
|
||
], 400);
|
||
}
|
||
|
||
try {
|
||
$query = 'geo:' . $request->input('latitude') . ',' . $request->input('longitude');
|
||
if ($request->input('u') !== null) {
|
||
$query .= ';u=' . $request->input('u');
|
||
}
|
||
$response = $this->guzzleClient->get($micropubEndpoint, [
|
||
'headers' => ['Authorization' => 'Bearer ' . $user->token],
|
||
'query' => ['q' => $query],
|
||
]);
|
||
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
||
return response()->json([
|
||
'error' => true,
|
||
'error_description' => 'The endpoint ' . $micropubEndpoint . ' returned a non-good response',
|
||
], 400);
|
||
}
|
||
|
||
return response($response->getBody(), 200)
|
||
->header('Content-Type', 'application/json');
|
||
}
|
||
|
||
/**
|
||
* Parse the syndication targets JSON into a an array.
|
||
*
|
||
* @param string|null
|
||
* @return array|null
|
||
*/
|
||
private function parseSyndicationTargets($syndicationTargets = null)
|
||
{
|
||
if ($syndicationTargets === null || $syndicationTargets === '') {
|
||
return;
|
||
}
|
||
$syndicateTo = [];
|
||
$data = json_decode($syndicationTargets, true);
|
||
if (array_key_exists('uid', $data)) {
|
||
$syndicateTo[] = [
|
||
'target' => $data['uid'],
|
||
'name' => $data['name'],
|
||
];
|
||
}
|
||
foreach ($data as $syn) {
|
||
if (array_key_exists('uid', $syn)) {
|
||
$syndicateTo[] = [
|
||
'target' => $syn['uid'],
|
||
'name' => $syn['name'],
|
||
];
|
||
}
|
||
}
|
||
|
||
return $syndicateTo;
|
||
}
|
||
|
||
/**
|
||
* Parse the media-endpoint retrieved from querying a micropub endpoint.
|
||
*
|
||
* @param string|null
|
||
* @return string
|
||
*/
|
||
private function parseMediaEndpoint($queryResponse = null)
|
||
{
|
||
if ($queryResponse === null) {
|
||
return;
|
||
}
|
||
|
||
$data = json_decode($queryResponse, true);
|
||
if (array_key_exists('media-endpoint', $data)) {
|
||
return $data['media-endpoint'];
|
||
}
|
||
}
|
||
}
|