Browse Source

lock down fetching external icons or tile URLs to authenticated requests

for #8
main
Aaron Parecki 1 year ago
parent
commit
6ab7bbab61
Failed to extract signature
5 changed files with 38 additions and 11 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -1
      controllers/main.php
  3. +9
    -0
      data/static-maps.md
  4. +16
    -0
      lib/helpers.php
  5. +11
    -10
      p3k/geo/StaticMap.php

+ 1
- 0
.gitignore View File

@ -2,3 +2,4 @@
vendor/
lib/config.php
data/airports.csv
data/apikeys.txt

+ 1
- 1
controllers/main.php View File

@ -17,5 +17,5 @@ $app->map('/map/img', function() use($app) {
$params = $app->request()->params();
$app->response['Content-type'] = 'image/png';
$assetPath = dirname(__FILE__) . '/../public/map-images';
$map = p3k\geo\StaticMap\generate($params, null, $assetPath);
$map = p3k\geo\StaticMap\generate($params, null, $assetPath, is_authenticated($params));
})->via('GET','POST');

+ 9
- 0
data/static-maps.md View File

@ -40,6 +40,7 @@ Parameters can be included in either the query string or in the POST body.
* `location` - optional - Free-form text that will be geocoded to center the map. Not needed if specifying a location with the latitude and longitude parameters, or if a marker is specified.
* `marker[]` - Specify one or more markers to overlay on the map. Parameters are specified as: `key:value;`. See below for the full list of parameters.
* `path[]` - Specify one or more paths to draw on the map. See below for the full list of parameters to draw a path.
* `token` - To use external icons or tile URLs, provide an API key in the request. See below for documentation on configuring this.
## Markers
@ -110,6 +111,14 @@ Parameters can be included in either the query string or in the POST body.
* ![small-yellow-cutout](map-images/small-yellow-cutout.png) `small-yellow-cutout`
* ![small-yellow-user](map-images/small-yellow-user.png) `small-yellow-user`
## Authentication
To be able to use externally-referenced icons or tile URLs, you will need to configure API keys and provide a token in the request. This locks down the ability to fetch external resources to only trusted users of the system.
Create a file `data/apikeys.txt` and generate a random string with a tool of your choosing, and with one API key per line. Any value passed in the parameter `token` that matches the text in a line in this file will enable the request to use the restricted features that reference external URLs.
## Paths
A path is specified as a list of longitude and latitudes, as well as optional properties to specify the weight and color of the path.

+ 16
- 0
lib/helpers.php View File

@ -24,3 +24,19 @@ function k($a, $k, $default=null) {
}
}
function is_authenticated($params) {
if(!isset($params['token']))
return false;
$token_file = __DIR__.'/../data/apikeys.txt';
if(!file_exists($token_file))
return false;
$valid_tokens = array_filter(file($token_file));
if(in_array($params['token'], $valid_tokens))
return true;
return false;
}

+ 11
- 10
p3k/geo/StaticMap.php View File

@ -3,7 +3,7 @@ namespace p3k\geo\StaticMap;
use p3k\geo\WebMercator, p3k\Geocoder;
use Imagick, ImagickPixel, ImagickDraw;
function generate($params, $filename, $assetPath) {
function generate($params, $filename, $assetPath, $is_authenticated=false) {
$bounds = array(
'minLat' => 90,
@ -46,14 +46,15 @@ function generate($params, $filename, $assetPath) {
}
if(preg_match('/https?:\/\/(.+)/', $properties['icon'], $match)) {
// Looks like an external image, attempt to download it
$ch = curl_init($properties['icon']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$img = curl_exec($ch);
$properties['iconImg'] = @imagecreatefromstring($img);
if(!$properties['iconImg']) {
$properties['iconImg'] = false;
$properties['iconImg'] = false;
// Only allow external referenced icons from authenticated requests
if($is_authenticated) {
// Looks like an external image, attempt to download it
$ch = curl_init($properties['icon']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$img = curl_exec($ch);
$properties['iconImg'] = @imagecreatefromstring($img);
}
} else {
$properties['iconImg'] = imagecreatefrompng($assetPath . '/' . $properties['icon'] . '.png');
@ -252,7 +253,7 @@ function generate($params, $filename, $assetPath) {
$overlayURL = $tileServices[k($params,'basemap')][1];
else
$overlayURL = 0;
} elseif(k($params, 'basemap') == 'custom') {
} elseif(k($params, 'basemap') == 'custom' && $is_authenticated) {
$tileURL = $params['tileurl'];
$overlayURL = false;
} else {

Loading…
Cancel
Save