1
0
mirror of https://github.com/cydrobolt/polr.git synced 2024-11-09 11:42:28 +01:00

Implement secret URLs

This commit is contained in:
Chaoyi Zha 2015-11-06 18:47:57 -05:00
parent a844d92ffa
commit f36791039c
4 changed files with 62 additions and 9 deletions

View File

@ -45,10 +45,27 @@ class LinkHelper {
return false;
}
else {
return true;
return $link->short_url;
}
}
static public function longLinkExists($long_url) {
/**
* Provided a long link (string),
* check whether the link is in the DB.
* @return boolean
*/
$link = Link::where('long_url', $long_url)
->first();
if ($link == null) {
return false;
}
else {
return $link->short_url;
}
}
static public function findSuitableEnding() {
/**
* Provided an in-use link ending (string),

View File

@ -20,6 +20,14 @@ class LinkController extends Controller {
return redirect()->route('index');
}
private function formatAndRender($link_ending, $secret_ending=False) {
$short_url = env('APP_PROTOCOL') . env('APP_ADDRESS') . '/' . $link_ending;
if ($secret_ending) {
$short_url .= '/' . $secret_ending;
}
return view('shorten_result', ['short_url' => $short_url]);
}
public function performShorten(Request $request) {
$this->request = $request;
@ -35,8 +43,10 @@ class LinkController extends Controller {
looks like a shortened URL.');
}
if ($is_secret) {
// TODO if secret label as custom and don't return on lookup
if (!$is_secret && $existing_link = LinkHelper::longLinkExists($long_url)) {
// if link is not specified as secret, is non-custom, and
// already exists in Polr, lookup the value and return
return $this->formatAndRender($existing_link);
}
if ($custom_ending) {
@ -61,6 +71,7 @@ class LinkController extends Controller {
}
$link = new Link;
$link->short_url = $link_ending;
$link->long_url = $long_url;
@ -72,13 +83,19 @@ class LinkController extends Controller {
$link->creator = $creator;
}
$link->save();
$short_url = env('APP_PROTOCOL') . env('APP_ADDRESS') . "/" . $link_ending;
return view('shorten_result', ['short_url' => $short_url]);
if ($is_secret) {
$rand_bytes_num = intval(env('POLR_SECRET_BYTES'));
$rand_bytes = openssl_random_pseudo_bytes($rand_bytes_num);
$secret_key = bin2hex($rand_bytes);
$link->secret_key = $secret_key;
}
public function performRedirect(Request $request, $short_url) {
$link->save();
return $this->formatAndRender($link_ending, $secret_key);
}
public function performRedirect(Request $request, $short_url, $secret_key=false) {
$link = Link::where('short_url', $short_url)
->first();
@ -86,12 +103,29 @@ class LinkController extends Controller {
return abort(404);
}
if ($link['disabled'] == 1) {
$link_secret_key = $link->secret_key;
if ($link->disabled == 1) {
return view('error', [
'message' => 'Sorry, but this link has been disabled by an administrator.'
]);
}
if ($link_secret_key) {
if (!$secret_key) {
// if we do not receieve a secret key
// when we are expecting one, return a 404
return abort(404);
}
else {
if ($link_secret_key != $secret_key) {
// a secret key is provided, but it is incorrect
return abort(404);
}
}
}
$long_url = $link->long_url;
return redirect()->to($long_url);
}

View File

@ -20,7 +20,9 @@ $app->get('/login', ['as' => 'login', 'uses' => 'UserController@displayLoginPage
$app->get('/about', ['as' => 'about', 'uses' => 'StaticPageController@displayAbout']);
$app->get('/signup', ['as' => 'signup', 'uses' => 'UserController@displaySignupPage']);
$app->get('/admin', ['as' => 'admin', 'uses' => 'AdminController@displayAdminPage']);
$app->get('/{short_link}', ['uses' => 'LinkController@performRedirect']);
$app->get('/{short_url}', ['uses' => 'LinkController@performRedirect']);
$app->get('/{short_url}/{secret_key}', ['uses' => 'LinkController@performRedirect']);
/* POST endpoints */

View File

@ -8,7 +8,7 @@
<h1 class='title'>{{env('APP_NAME')}}</h1>
<form method='POST' action='/shorten' role='form'>
<input type='text' class='form-control long-link-input' placeholder='http://' value='http://' name='link-url' />
<input type='text' autocomplete="off" class='form-control long-link-input' placeholder='http://' value='http://' name='link-url' />
<div id='options'>
<div class='btn-group btn-toggle visibility-toggler' data-toggle='buttons'>
<label class='btn btn-primary btn-sm active'>