Squashed commit of the following:

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
This commit is contained in:
Jonny Barnes 2017-04-21 16:38:39 +01:00
parent 75a2ba74b3
commit f9a133e727
32 changed files with 1259 additions and 753 deletions

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers;
use App\Services\IndieAuthService;
use App\IndieWebUser;
use IndieAuth\Client as IndieClient;
use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Http\{Request, Response};
@ -10,20 +10,13 @@ use GuzzleHttp\Exception\{ClientException, ServerException};
class MicropubClientController extends Controller
{
/**
* The IndieAuth service container.
*/
protected $indieAuthService;
/**
* Inject the dependencies.
*/
public function __construct(
IndieAuthService $indieAuthService = null,
IndieClient $indieClient = null,
GuzzleClient $guzzleClient = null
) {
$this->indieAuthService = $indieAuthService ?? new IndieAuthService();
$this->guzzleClient = $guzzleClient ?? new GuzzleClient();
$this->indieClient = $indieClient ?? new IndieClient();
}
@ -37,8 +30,11 @@ class MicropubClientController extends Controller
public function create(Request $request)
{
$url = $request->session()->get('me');
$syndication = $request->session()->get('syndication');
$mediaEndpoint = $request->session()->get('media-endpoint');
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'));
@ -56,19 +52,17 @@ class MicropubClientController extends Controller
return back();
}
$mediaEndpoint = $request->session()->get('media-endpoint');
if ($mediaEndpoint == null) {
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
if ($user->mediaEndpoint == null || $user->token == null) {
return back();
}
$token = $request->session()->get('token');
$mediaURLs = [];
foreach ($request->file('file') as $file) {
try {
$response = $this->guzzleClient->request('POST', $mediaEndpoint, [
$response = $this->guzzleClient->request('POST', $user->mediaEndpoint, [
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Authorization' => 'Bearer ' . $user->token,
],
'multipart' => [
[
@ -109,27 +103,142 @@ class MicropubClientController extends Controller
*/
public function store(Request $request)
{
$domain = $request->session()->get('me');
$token = $request->session()->get('token');
$url = normalize_url($request->session()->get('me'));
$user = IndieWebUser::where('me', $url)->firstOrFail();
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint(
$domain,
$this->indieClient
);
if ($user->token == null) {
return redirect(route('micropub-client'))->with('error', 'You havent requested a token yet');
}
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
if (! $micropubEndpoint) {
return redirect(route('micropub-client'))->with('error', 'Unable to determine micropub API endpoint');
}
$response = $this->postNoteRequest($request, $micropubEndpoint, $token);
$headers = [
'Authorization' => 'Bearer ' . $user->token,
];
if ($response->getStatusCode() == 201) {
$request->session()->forget('media-links');
$location = $response->getHeader('Location');
if (is_array($location)) {
return redirect($location[0]);
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.'
);
}
return redirect($location);
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 didnt create the note.');
@ -143,26 +252,100 @@ class MicropubClientController extends Controller
*/
public function config(Request $request)
{
$data['me'] = $request->session()->get('me');
$data['token'] = $request->session()->get('token');
$data['syndication'] = $request->session()->get('syndication') ?? 'none defined';
$data['media-endpoint'] = $request->session()->get('media-endpoint') ?? 'none defined';
//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'));
}
/**
* Query the micropub endpoint and store response in the session.
* 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> didnt 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)
{
$domain = $request->session()->get('me');
$token = $request->session()->get('token');
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint($domain);
if ($micropubEndpoint !== null) {
$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],
@ -172,96 +355,35 @@ class MicropubClientController extends Controller
return back();
}
$body = (string) $response->getBody();
$data = json_decode($body, true);
$syndication = $this->parseSyndicationTargets($body);
$request->session()->put('syndication', $syndication);
if (array_key_exists('syndicate-to', $data)) {
$user->syndication = json_encode($data['syndicate-to']);
}
$mediaEndpoint = $this->parseMediaEndpoint($body);
$request->session()->put('media-endpoint', $mediaEndpoint);
if (array_key_exists('media-endpoint', $data)) {
$user->mediaEndpoint = $data['media-endpoint'];
}
$user->save();
return back();
}
}
/**
* This method performs the actual POST request.
* Update the syntax setting.
*
* @param \Illuminate\Http\Request $request
* @param string The Micropub endpoint to post to
* @param string The token to authenticate the request with
* @return \GuzzleHttp\Response $response | \Illuminate\RedirectFactory redirect
* @param Illuminate\Http\Request $request
* @return Illuminate\Http\RedirectResponse
* @todo validate input
*/
private function postNoteRequest(
Request $request,
$micropubEndpoint,
$token
) {
$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,
];
}
}
$headers = [
'Authorization' => 'Bearer ' . $token,
];
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.'
);
}
public function updateSyntax(Request $request)
{
$user = IndieWebUser::where('me', $request->session()->get('me'))->firstOrFail();
$user->syntax = $request->syntax;
$user->save();
return $response;
return redirect(route('micropub-config'));
}
/**
@ -272,16 +394,17 @@ class MicropubClientController extends Controller
*/
public function newPlace(Request $request)
{
if ($request->session()->has('token') === false) {
$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);
}
$domain = $request->session()->get('me');
$token = $request->session()->get('token');
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint($domain, $this->indieClient);
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
if (! $micropubEndpoint) {
return response()->json([
'error' => true,
@ -289,13 +412,27 @@ class MicropubClientController extends Controller
], 400);
}
$place = $this->postPlaceRequest($request, $micropubEndpoint, $token);
if ($place === false) {
$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,
@ -305,44 +442,6 @@ class MicropubClientController extends Controller
]);
}
/**
* Actually make a micropub request to make a new place.
*
* @param \Illuminate\Http\Request $request
* @param string The Micropub endpoint to post to
* @param string The token to authenticate the request with
* @param \GuzzleHttp\Client $client
* @return \GuzzleHttp\Response $response | \Illuminate\RedirectFactory redirect
*/
private function postPlaceRequest(
Request $request,
$micropubEndpoint,
$token
) {
$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 ' . $token,
];
try {
$response = $this->guzzleClient->request('POST', $micropubEndpoint, [
'form_params' => $formParams,
'headers' => $headers,
]);
} catch (ClientException $e) {
return false;
}
if ($response->getStatusCode() == 201) {
return $response->getHeader('Location')[0];
}
return false;
}
/**
* Make a request to the micropub endpoint requesting any nearby places.
*
@ -351,16 +450,17 @@ class MicropubClientController extends Controller
*/
public function nearbyPlaces(Request $request)
{
if ($request->session()->has('token') === false) {
$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);
}
$domain = $request->session()->get('me');
$token = $request->session()->get('token');
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint($domain, $this->indieClient);
$micropubEndpoint = $this->indieClient->discoverMicropubEndpoint($url);
if (! $micropubEndpoint) {
return response()->json([
@ -375,7 +475,7 @@ class MicropubClientController extends Controller
$query .= ';u=' . $request->input('u');
}
$response = $this->guzzleClient->get($micropubEndpoint, [
'headers' => ['Authorization' => 'Bearer ' . $token],
'headers' => ['Authorization' => 'Bearer ' . $user->token],
'query' => ['q' => $query],
]);
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
@ -390,30 +490,34 @@ class MicropubClientController extends Controller
}
/**
* Parse the syndication targets retreived from a cookie, to a form that can
* be used in a view.
* Parse the syndication targets JSON into a an array.
*
* @param string $syndicationTargets
* @param string|null
* @return array|null
*/
private function parseSyndicationTargets($syndicationTargets = null)
{
if ($syndicationTargets === null) {
if ($syndicationTargets === null || $syndicationTargets === '') {
return;
}
$syndicateTo = [];
$data = json_decode($syndicationTargets, true);
if (array_key_exists('syndicate-to', $data)) {
foreach ($data['syndicate-to'] as $syn) {
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'],
];
}
}
if (count($syndicateTo) > 0) {
return $syndicateTo;
}
return $syndicateTo;
}
/**