Skip to content

Commit

Permalink
Merge pull request #203 from cydrobolt/refactor/angularjs
Browse files Browse the repository at this point in the history
Merge in latest updates from refactor/angularjs
  • Loading branch information
cydrobolt authored Aug 15, 2016
2 parents f471005 + fafb9d3 commit 0d4d26e
Show file tree
Hide file tree
Showing 25 changed files with 793 additions and 303 deletions.
10 changes: 8 additions & 2 deletions app/Factories/LinkFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ public static function createLink($long_url, $is_secret=false, $custom_ending=nu
$link_ending = $custom_ending;
}
else {
// no custom ending
$link_ending = LinkHelper::findSuitableEnding();
if (env('SETTING_PSEUDORANDOM_ENDING')) {
// generate a pseudorandom ending
$link_ending = LinkHelper::findPseudoRandomEnding();
}
else {
// generate a counter-based ending or use existing ending if possible
$link_ending = LinkHelper::findSuitableEnding();
}
}

$link = new Link;
Expand Down
21 changes: 21 additions & 0 deletions app/Helpers/LinkHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@ static public function processPostClick($link) {
*/
}

static public function findPseudoRandomEnding() {
/**
* Return an available pseudorandom string of length _PSEUDO_RANDOM_KEY_LENGTH,
* as defined in .env
* Edit _PSEUDO_RANDOM_KEY_LENGTH in .env if you wish to increase the length
* of the pseudorandom string generated.
* @return string
*/

$pr_str = '';
$in_use = true;

while ($in_use) {
// Generate a new string until the ending is not in use
$pr_str = str_random(env('_PSEUDO_RANDOM_KEY_LENGTH'));
$in_use = LinkHelper::linkExists($pr_str);
}

return $pr_str;
}

static public function findSuitableEnding() {
/**
* Provided an in-use link ending (string),
Expand Down
24 changes: 23 additions & 1 deletion app/Http/Controllers/AjaxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ public function generateNewAPIKey(Request $request) {
// ensure that user is permitted to access the API
$user_api_enabled = $user->api_active;
if (!$user_api_enabled) {
abort(403, 'API access not authorized.');
// if the user does not have API access toggled on,
// allow only if user is an admin
self::ensureAdmin();
}
}

Expand All @@ -94,6 +96,26 @@ public function generateNewAPIKey(Request $request) {
return $user->api_key;
}

public function editAPIQuota(Request $request) {
/**
* If user is an admin, allow the user to edit the per minute API quota of
* any user.
*/

self::ensureAdmin();

$user_id = $request->input('user_id');
$new_quota = $request->input('new_quota');
$user = UserHelper::getUserById($user_id);

if (!$user) {
abort(404, 'User not found.');
}
$user->api_quota = $new_quota;
$user->save();
return "OK";
}

public function deleteUser(Request $request) {
self::ensureAdmin();

Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/SetupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ public static function performSetup(Request $request) {
$st_password_recov = $request->input('setting:password_recovery');

$st_base = $request->input('setting:base');

$st_auto_api_key = $request->input('setting:auto_api_key');
$st_anon_api = $request->input('setting:anon_api');
$st_pseudor_ending = $request->input('setting:pseudor_ending');

$mail_host = $request->input('app:smtp_server');
$mail_port = $request->input('app:smtp_port');
Expand Down Expand Up @@ -156,6 +156,7 @@ public static function performSetup(Request $request) {
'ST_BASE' => $st_base,
'ST_AUTO_API' => $st_auto_api_key,
'ST_ANON_API' => $st_anon_api,
'ST_PSEUDOR_ENDING' => $st_pseudor_ending,

'TMP_SETUP_AUTH_KEY' => $setup_auth_key
])->render();
Expand Down
2 changes: 2 additions & 0 deletions app/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@
$app->post('link_avail_check', ['as' => 'api_link_check', 'uses' => 'AjaxController@checkLinkAvailability']);
$app->post('admin/toggle_api_active', ['as' => 'api_toggle_api_active', 'uses' => 'AjaxController@toggleAPIActive']);
$app->post('admin/generate_new_api_key', ['as' => 'api_generate_new_api_key', 'uses' => 'AjaxController@generateNewAPIKey']);
$app->post('admin/edit_api_quota', ['as' => 'api_edit_quota', 'uses' => 'AjaxController@editAPIQuota']);
$app->post('admin/delete_user', ['as' => 'api_generate_new_api_key', 'uses' => 'AjaxController@deleteUser']);
$app->post('admin/toggle_link', ['as' => 'api_toggle_link', 'uses' => 'AjaxController@toggleLink']);
$app->post('admin/delete_link', ['as' => 'api_delete_link', 'uses' => 'AjaxController@deleteLink']);


/* API shorten endpoints */
$app->post('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'Api\ApiLinkController@shortenLink']);
$app->get('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'Api\ApiLinkController@shortenLink']);
Expand Down
3 changes: 2 additions & 1 deletion public/css/about.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

.license-btn {
margin-top: 30px;
width: 20%;
margin-bottom: 3em;
width: auto;
}

.logo-img {
Expand Down
7 changes: 7 additions & 0 deletions public/css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
display: inline;
}

input.api-quota {
display: inline;
width: 9em;
font-size: .85em;
height: .85em;
}

.wrap-text {
word-wrap: break-word;
}
Expand Down
4 changes: 4 additions & 0 deletions public/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@
#link-availability-status {
margin-bottom: 20px;
}

.visibility-toggler {
margin-bottom: 2em;
}
10 changes: 10 additions & 0 deletions public/css/setup.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,13 @@ body {
h4, p {
margin-top: 20px;
}

.setup-qmark {
width: 2em;
margin-left: 0.3em;
display: inline;
}

.popover-content {
text-transform: none;
}
155 changes: 155 additions & 0 deletions public/js/AdminCtrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
polr.controller('AdminCtrl', function($scope, $compile) {
$scope.syncHash = function() {
var url = document.location.toString();
if (url.match('#')) {
$('.admin-nav a[href=#' + url.split('#')[1] + ']').tab('show');
}
};

$scope.appendModal = function(html, id) {
id = esc_selector(id);

$(".ng-root").append(html);
var modal_ele = $("#" + id);

modal_ele.append(html);
modal_ele.modal();
$compile(modal_ele)($scope);

$("body").delegate("#" + id, "hidden.bs.modal", function() {
modal_ele.remove();
});
};

$scope.hideRow = function(el, msg) {
el.text(msg);
el.parent().parent().slideUp();
};

$scope.deleteUser = function($event) {
var el = $($event.target);
var user_id = el.data('user-id');

apiCall('admin/delete_user', {
'user_id': user_id,
}, function(new_status) {
$scope.hideRow(el, 'Deleted!');
});
};

$scope.deleteLink = function($event, link_ending) {
var el = $($event.target);

apiCall('admin/delete_link', {
'link_ending': link_ending,
}, function(new_status) {
$scope.hideRow(el, 'Deleted!');
});
}

$scope.generateNewAPIKey = function($event, user_id, is_dev_tab) {
var el = $($event.target);
var status_display_elem = el.prevAll('.status-display');

if (is_dev_tab) {
status_display_elem = el.parent().prev().children();
}

apiCall('admin/generate_new_api_key', {
'user_id': user_id,
}, function(new_status) {
if (status_display_elem.is('input')) {
status_display_elem.val(new_status);
} else {
status_display_elem.text(new_status);
}
});
};

$scope.toggleAPIStatus = function($event, user_id) {
var el = $($event.target);
var status_display_elem = el.prevAll('.status-display');

apiCall('admin/toggle_api_active', {
'user_id': user_id,
}, function(new_status) {
new_status = res_value_to_text(new_status);
status_display_elem.text(new_status);
});
};

$scope.toggleLink = function($event, link_ending) {
var el = $($event.target);
var curr_action = el.text();

apiCall('admin/toggle_link', {
'link_ending': link_ending,
}, function(next_action) {
toastr.success(curr_action + " was successful.", "Success");
if (next_action == 'Disable') {
el.removeClass('btn-success');
el.addClass('btn-danger');
} else {
el.removeClass('btn-danger');
el.addClass('btn-success');
}

el.text(next_action);
});
};

$scope.updateAPIQuota = function($event, user_id) {
var el = $($event.target);
var new_quota = el.prevAll('.api-quota').val();

apiCall('admin/edit_api_quota', {
'user_id': user_id,
'new_quota': parseInt(new_quota)
}, function(next_action) {
toastr.success("Quota successfully changed.", "Success");
});
}


$scope.openAPIModal = function($event, username, api_key, api_active, api_quota, user_id) {
var el = $($event.target);

var markup = $('#api-modal-template').html();

var modal_id = "api-modal-" + username;
var modal_context = {
id: modal_id,
api_key: api_key,
api_active: parseInt(api_active),
api_quota: api_quota,
user_id: user_id,
title: "API Information for " + username,
body: markup
};
var mt_html = $scope.modal_template(modal_context);
var compiled_mt = Handlebars.compile(mt_html);
mt_html = compiled_mt(modal_context);
$scope.appendModal(mt_html, modal_id);
}

$scope.init = function() {
var modal_source = $("#modal-template").html();
$scope.modal_template = Handlebars.compile(modal_source);

$('.admin-nav a').click(function(e) {
e.preventDefault();
$(this).tab('show');
});
$scope.syncHash();

$(window).on('hashchange', function() {
$scope.syncHash();
});

$("a[href^=#]").on("click", function(e) {
history.pushState({}, '', this.href);
});
}

$scope.init();
});
Loading

0 comments on commit 0d4d26e

Please sign in to comment.