Merge branch 'feature/better-places' into develop

This commit is contained in:
Jonny Barnes 2016-09-23 16:56:29 +01:00
commit 5ffcee06c0
7 changed files with 208 additions and 87 deletions

View file

@ -204,34 +204,37 @@ class MicropubClientController extends Controller
*/
public function postNewPlace(Request $request)
{
if ($request->session()->has('token') === false) {
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);
if (! $micropubEndpoint) {
return (new Response(json_encode([
return response()->json([
'error' => true,
'message' => 'Could not determine the micropub endpoint.',
]), 400))
->header('Content-Type', 'application/json');
'error_description' => 'Could not determine the micropub endpoint.',
], 400);
}
$place = $this->postPlaceRequest($request, $micropubEndpoint, $token);
if ($place === false) {
return (new Response(json_encode([
return response()->json([
'error' => true,
'message' => 'Unable to create the new place',
]), 400))
->header('Content-Type', 'application/json');
'error_description' => 'Unable to create the new place',
], 400);
}
return (new Response(json_encode([
return response()->json([
'url' => $place,
'name' => $request->input('place-name'),
'latitude' => $request->input('place-latitude'),
'longitude' => $request->input('place-longitude'),
]), 200))
->header('Content-Type', 'application/json');
]);
}
/**
@ -263,7 +266,7 @@ class MicropubClientController extends Controller
'headers' => $headers,
]);
} catch (ClientException $e) {
//not sure yet...
return false;
}
if ($response->getStatusCode() == 201) {
return $response->getHeader('Location')[0];
@ -285,12 +288,22 @@ class MicropubClientController extends Controller
$latitude,
$longitude
) {
if ($request->session()->has('token') === false) {
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);
if (! $micropubEndpoint) {
return;
return response()->json([
'error' => true,
'error_description' => 'No known endpoint',
], 400);
}
try {
@ -299,7 +312,10 @@ class MicropubClientController extends Controller
'query' => ['q' => 'geo:' . $latitude . ',' . $longitude],
]);
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
return;
return response()->json([
'error' => true,
'error_description' => 'The endpoint returned a non-good response',
], 400);
}
return (new Response($response->getBody(), 200))

View file

@ -57,54 +57,43 @@ class MicropubController extends Controller
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);
$content = <<<EOD
{
"response": "created",
"location": "$note->longurl"
} catch (Exception $exception) {
return response()->json(['error' => true], 400);
}
EOD;
return (new Response($content, 201))
->header('Location', $note->longurl)
->header('Content-Type', 'application/json');
return response()->json([
'response' => 'created',
'location' => $note->longurl
], 201)->header('Location', $note->longurl);
}
if ($request->input('h') == 'card' || $request->input('type')[0] == 'h-card') {
try {
$place = $this->placeService->createPlace($request);
$content = <<<EOD
{
"response": "created",
"location": "$place->longurl"
} catch (Exception $exception) {
return response()->json(['error' => true], 400);
}
EOD;
return (new Response($content, 201))
->header('Location', $place->longurl)
->header('Content-Type', 'application/json');
return response()->json([
'response' => 'created',
'location' => $place->longurl
], 201)->header('Location', $place->longurl);
}
}
}
$content = <<<'EOD'
{
"response": "error",
"error": "invalid_token",
"error_description": "The token provided is not valid or does not have the necessary scope",
}
EOD;
return (new Response($content, 400))
->header('Content-Type', 'application/json');
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
'error_description' => 'The token provided is not valid or does not have the necessary scope'
], 400);
}
$content = <<<'EOD'
{
"response": "error",
"error": "no_token",
"error_description": "No OAuth token sent with request"
}
EOD;
return (new Response($content, 400))
->header('Content-Type', 'application/json');
return response()->json([
'response' => 'error',
'error' => 'no_token',
'error_description' => 'No OAuth token sent with request'
], 400);
}
/**

View file

@ -4,9 +4,7 @@ namespace App;
use DB;
use Illuminate\Database\Eloquent\Model;
use Phaza\LaravelPostgis\Geometries\Point;
use MartinBean\Database\Eloquent\Sluggable;
use Phaza\LaravelPostgis\Geometries\Polygon;
use Phaza\LaravelPostgis\Eloquent\PostgisTrait;
class Place extends Model
@ -33,8 +31,8 @@ class Place extends Model
* @var array
*/
protected $postgisFields = [
'location' => Point::class,
'polygon' => Polygon::class,
'location',
'polygon',
];
/**

View file

@ -16,21 +16,26 @@ class PlaceService
*/
public function createPlace(Request $request)
{
//well either have latitude and longitude sent together in a
//geo-url (micropub), or seperatley (/admin)
if ($request->input('geo') !== null) {
$parts = explode(':', $request->input('geo'));
if ($request->header('Content-Type') == 'application/json') {
$name = $request->input('properties.name');
$description = $request->input('properties.description') ?? null;
$geo = $request->input('properties.geo');
} else {
$name = $request->input('name');
$description = $request->input('description');
$geo = $request->input('geo');
}
$parts = explode(':', $geo);
$latlng = explode(',', $parts[1]);
$latitude = $latlng[0];
$longitude = $latlng[1];
}
if ($request->input('latitude') !== null) {
$latitude = $request->input('latitude');
$longitude = $request->input('longitude');
}
$place = new Place();
$place->name = $request->input('name');
$place->description = $request->input('description');
$place->name = $name;
$place->description = $description;
$place->location = new Point((float) $latitude, (float) $longitude);
$place->save();

View file

@ -12,11 +12,11 @@ if ('geolocation' in navigator) {
function getLocation() {
navigator.geolocation.getCurrentPosition(function (position) {
//the locate button has been clicked so add the places/map
addPlaces(position.coords.latitude, position.coords.longitude);
addPlacesMap(position.coords.latitude, position.coords.longitude);
});
}
function addPlaces(latitude, longitude) {
function addPlacesMap(latitude, longitude) {
//get the nearby places
fetch('/places/near/' + latitude + '/' + longitude, {
credentials: 'same-origin',
@ -24,6 +24,10 @@ function addPlaces(latitude, longitude) {
}).then(function (response) {
return response.json();
}).then(function (j) {
if (j.error == true) {
alertify.reset();
alertify.error(j.error_description);
}
if (j.length > 0) {
var i;
var places = [];
@ -195,17 +199,13 @@ function addMap(latitude, longitude, places) {
method: 'post',
body: formData
})
.then(function (response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response);
} else {
return Promise.reject(new Error(response.statusText));
}
})
.then(function (response) {
return response.json();
})
.then(function (placeJson) {
if (placeJson.error == true) {
throw new Error(placeJson.error_description);
}
//create the slug from the url
var urlParts = placeJson.split('/');
var slug = urlParts.pop();
@ -247,7 +247,8 @@ function addMap(latitude, longitude, places) {
//make selected
selectPlace(slug);
}).catch(function (placeError) {
console.error(placeError);
alertify.reset();
alertify.error(placeError);
});
});
});

View file

@ -1,4 +1,4 @@
/* global L */
/* global L, alertify */
if ('geolocation' in navigator) {
var button = document.querySelector('#locate');
if (button.addEventListener) {
@ -12,11 +12,11 @@ if ('geolocation' in navigator) {
function getLocation() {
navigator.geolocation.getCurrentPosition(function (position) {
//the locate button has been clicked so add the places/map
addPlaces(position.coords.latitude, position.coords.longitude);
addPlacesMap(position.coords.latitude, position.coords.longitude);
});
}
function addPlaces(latitude, longitude) {
function addPlacesMap(latitude, longitude) {
//get the nearby places
fetch('/places/near/' + latitude + '/' + longitude, {
credentials: 'same-origin',
@ -24,6 +24,10 @@ function addPlaces(latitude, longitude) {
}).then(function (response) {
return response.json();
}).then(function (j) {
if (j.error == true) {
alertify.reset();
alertify.error(j.error_description);
}
if (j.length > 0) {
var i;
var places = [];
@ -195,17 +199,13 @@ function addMap(latitude, longitude, places) {
method: 'post',
body: formData
})
.then(function (response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response);
} else {
return Promise.reject(new Error(response.statusText));
}
})
.then(function (response) {
return response.json();
})
.then(function (placeJson) {
if (placeJson.error == true) {
throw new Error(placeJson.error_description);
}
//create the slug from the url
var urlParts = placeJson.split('/');
var slug = urlParts.pop();
@ -247,7 +247,8 @@ function addMap(latitude, longitude, places) {
//make selected
selectPlace(slug);
}).catch(function (placeError) {
console.error(placeError);
alertify.reset();
alertify.error(placeError);
});
});
});

View file

@ -116,6 +116,103 @@ class MicropubTest extends TestCase
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
)->seeJson([
'response' => 'created'
])->assertResponseStatus(201);
}
public function testMicropubJSONRequestCreateNewNoteWithoutToken()
{
$faker = \Faker\Factory::create();
$note = $faker->text;
$this->json(
'POST',
$this->appurl . '/api/post',
[
'type' => ['h-entry'],
'properties' => [
'content' => [$note],
],
]
)->seeJson([
'response' => 'error',
'error' => 'no_token'
])->assertResponseStatus(400);
}
public function testMicropubJSONRequestCreateNewNoteWithInvalidToken()
{
$faker = \Faker\Factory::create();
$note = $faker->text;
$this->json(
'POST',
$this->appurl . '/api/post',
[
'type' => ['h-entry'],
'properties' => [
'content' => [$note],
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getInvalidToken()]
)->seeJson([
'response' => 'error',
'error' => 'invalid_token'
]);
}
public function testMicropubJSONRequestCreateNewPlace()
{
$faker = \Faker\Factory::create();
$this->json(
'POST',
$this->appurl . '/api/post',
[
'type' => ['h-card'],
'properties' => [
'name' => $faker->name,
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
)->seeJson([
'response' => 'created'
])->assertResponseStatus(201);
}
public function testMicropubJSONRequestCreateNewPlaceWithoutToken()
{
$faker = \Faker\Factory::create();
$this->json(
'POST',
$this->appurl . '/api/post',
[
'type' => ['h-entry'],
'properties' => [
'name' => $faker->name,
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
],
]
)->seeJson([
'response' => 'error',
'error' => 'no_token'
])->assertResponseStatus(400);
}
public function testMicropubJSONRequestCreateNewPlaceWithInvalidToken()
{
$faker = \Faker\Factory::create();
$this->json(
'POST',
$this->appurl . '/api/post',
[
'type' => ['h-entry'],
'properties' => [
'name' => $faker->name,
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
],
],
['HTTP_Authorization' => 'Bearer ' . $this->getInvalidToken()]
)->seeJson([
'response' => 'error',
'error' => 'invalid_token'
]);
}
@ -132,4 +229,18 @@ class MicropubTest extends TestCase
return $token;
}
private function getInvalidToken()
{
$signer = new Sha256();
$token = (new Builder())
->set('client_id', 'https://quill.p3k.io')
->set('me', 'https://jonnybarnes.localhost')
->set('scope', 'view')
->set('issued_at', time())
->sign($signer, env('APP_KEY'))
->getToken();
return $token;
}
}