mirror of
https://github.com/cydrobolt/polr.git
synced 2024-11-09 11:42:28 +01:00
Merge branch 'master' of https://github.com/ashazar/polr into ashazar-master
This commit is contained in:
commit
d52e78f475
@ -4,9 +4,10 @@ namespace App\Factories;
|
||||
use Hash;
|
||||
use App\Models\User;
|
||||
use App\Helpers\CryptoHelper;
|
||||
use App\Helpers\UserHelper;
|
||||
|
||||
class UserFactory {
|
||||
public static function createUser($username, $email, $password, $active=0, $ip='127.0.0.1', $api_key=false, $api_active=0) {
|
||||
public static function createUser($username, $email, $password, $active=0, $ip='127.0.0.1', $api_key=false, $api_active=0, $role='') {
|
||||
$hashed_password = Hash::make($password);
|
||||
|
||||
$recovery_key = CryptoHelper::generateRandomHex(50);
|
||||
@ -17,6 +18,8 @@ class UserFactory {
|
||||
$user->recovery_key = $recovery_key;
|
||||
$user->active = $active;
|
||||
$user->ip = $ip;
|
||||
$role = ($role == '') ? UserHelper::UserRole('DEFAULT') : $role;
|
||||
$user->role = $role;
|
||||
|
||||
$user->api_key = $api_key;
|
||||
$user->api_active = $api_active;
|
||||
|
@ -105,4 +105,16 @@ class UserHelper {
|
||||
return self::getUserBy('email', $email, $inactive);
|
||||
}
|
||||
|
||||
public static function getUserRoles() { // Return Array: list of user roles
|
||||
return array(
|
||||
'ADMIN' => 'admin',
|
||||
'DEFAULT' => '',
|
||||
);
|
||||
}
|
||||
|
||||
public static function UserRole($role) {
|
||||
$userRoles = self::getUserRoles();
|
||||
|
||||
return $userRoles[$role];
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ class AdminController extends Controller {
|
||||
|
||||
return view('admin', [
|
||||
'role' => $role,
|
||||
'admin_role' => UserHelper::UserRole('ADMIN'),
|
||||
'user_roles' => UserHelper::getUserRoles(),
|
||||
'api_key' => $user->api_key,
|
||||
'api_active' => $user->api_active,
|
||||
'api_quota' => $user->api_quota,
|
||||
|
@ -5,6 +5,7 @@ use Yajra\Datatables\Facades\Datatables;
|
||||
|
||||
use App\Models\Link;
|
||||
use App\Models\User;
|
||||
use App\Helpers\UserHelper;
|
||||
|
||||
class AdminPaginationController extends Controller {
|
||||
/**
|
||||
@ -16,15 +17,48 @@ class AdminPaginationController extends Controller {
|
||||
public function paginateAdminUsers(Request $request) {
|
||||
self::ensureAdmin();
|
||||
|
||||
$admin_users = User::select(['username', 'email', 'created_at', 'active', 'api_key', 'api_active', 'api_quota', 'id']);
|
||||
$admin_users = User::select(['username', 'email', 'created_at', 'active', 'api_key', 'api_active', 'api_quota', 'role', 'id']);
|
||||
return Datatables::of($admin_users)
|
||||
->addColumn('api_action', function ($user) {
|
||||
// Add "API Info" action button
|
||||
return '<a class="activate-api-modal btn btn-sm btn-info"
|
||||
ng-click="openAPIModal($event, \'' . $user->username . '\', \'' . $user->api_key . '\', \'' . $user->api_active . '\', \'' . $user->api_quota . '\', \'' . $user->id . '\')">
|
||||
ng-click="openAPIModal($event, \'' . $user->username . '\', \'' . $user->id . '\')" id="api_info_btn_' . $user->id . '" data-api-active="' . $user->api_active . '" data-api-key="' . $user->api_key . '" data-api-quota="' . $user->api_quota . '">
|
||||
API info
|
||||
</a>';
|
||||
})
|
||||
->addColumn('toggle_active', function ($user) {
|
||||
// Toggle User Active status
|
||||
$btn_class = '';
|
||||
if (session('username') == $user->username) {
|
||||
$btn_class = ' disabled';
|
||||
}
|
||||
|
||||
if ($user->active) {
|
||||
$active_text = 'Active';
|
||||
$btn_color_class = ' btn-success';
|
||||
}
|
||||
else {
|
||||
$active_text = 'Inactive';
|
||||
$btn_color_class = ' btn-danger';
|
||||
}
|
||||
|
||||
return '<a class="btn btn-sm status-display' . $btn_color_class . $btn_class . '" ng-click="toggleUserActiveStatus($event)" '
|
||||
. 'data-user-id="' . $user->id . '">' . $active_text . '</a>';
|
||||
})
|
||||
->addColumn('change_role', function ($user) {
|
||||
// Add "Change Role" Select Box
|
||||
if (session('username') == $user->username) {
|
||||
return 'ADMIN';
|
||||
}
|
||||
$selectrole = '<select onchange="changeUserRole($(this));" id="user_roles" data-user-id=\'' . $user->id . '\' style="width: 100%; height: 85%;">';
|
||||
foreach (UserHelper::getUserRoles() as $role_text => $role_val) {
|
||||
$selectrole .= '<option value="' . $role_val . '"';
|
||||
if ($user->role == $role_val) $selectrole .= ' selected';
|
||||
$selectrole .= '>' . $role_text . '</option>';
|
||||
}
|
||||
$selectrole .= '</select>';
|
||||
return $selectrole;
|
||||
})
|
||||
->addColumn('delete', function ($user) {
|
||||
// Add "Delete" action button
|
||||
$btn_class = '';
|
||||
|
@ -6,6 +6,7 @@ use App\Helpers\LinkHelper;
|
||||
use App\Helpers\CryptoHelper;
|
||||
use App\Helpers\UserHelper;
|
||||
use App\Models\User;
|
||||
use App\Factories\UserFactory;
|
||||
|
||||
class AjaxController extends Controller {
|
||||
/**
|
||||
@ -116,6 +117,61 @@ class AjaxController extends Controller {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
public function toggleUserActive(Request $request) {
|
||||
self::ensureAdmin();
|
||||
|
||||
$user_id = $request->input('user_id');
|
||||
$user = UserHelper::getUserById($user_id, true);
|
||||
|
||||
if (!$user) {
|
||||
abort(404, 'User not found.');
|
||||
}
|
||||
$current_status = $user->active;
|
||||
|
||||
if ($current_status == 1) {
|
||||
$new_status = 0;
|
||||
}
|
||||
else {
|
||||
$new_status = 1;
|
||||
}
|
||||
|
||||
$user->active = $new_status;
|
||||
$user->save();
|
||||
|
||||
return $user->active;
|
||||
}
|
||||
|
||||
public function changeUserRole(Request $request) {
|
||||
self::ensureAdmin();
|
||||
|
||||
$user_id = $request->input('user_id');
|
||||
$role = $request->input('role');
|
||||
$user = UserHelper::getUserById($user_id, true);
|
||||
|
||||
if (!$user) {
|
||||
abort(404, 'User not found.');
|
||||
}
|
||||
|
||||
$user->role = $role;
|
||||
$user->save();
|
||||
|
||||
return "OK";
|
||||
}
|
||||
|
||||
public function addNewUser(Request $request) {
|
||||
self::ensureAdmin();
|
||||
|
||||
$ip = $request->ip();
|
||||
$user_name = $request->input('user_name');
|
||||
$user_password = $request->input('user_password');
|
||||
$user_email = $request->input('user_email');
|
||||
$user_role = $request->input('user_role');
|
||||
|
||||
UserFactory::createUser($user_name, $user_email, $user_password, 1, $ip, false, 0, $user_role);
|
||||
|
||||
return "OK";
|
||||
}
|
||||
|
||||
public function deleteUser(Request $request) {
|
||||
self::ensureAdmin();
|
||||
|
||||
|
@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
use App\Helpers\CryptoHelper;
|
||||
use App\Models\User;
|
||||
use App\Helpers\UserHelper;
|
||||
use App\Factories\UserFactory;
|
||||
use Cache;
|
||||
|
||||
@ -97,7 +98,7 @@ class SetupController extends Controller {
|
||||
$acct_username = $request->input('acct:username');
|
||||
$acct_email = $request->input('acct:email');
|
||||
$acct_password = $request->input('acct:password');
|
||||
$acct_group = "admin";
|
||||
$acct_group = UserHelper::UserRole('ADMIN');
|
||||
|
||||
// if true, only logged in users can shorten
|
||||
$st_shorten_permission = $request->input('setting:shorten_permission');
|
||||
@ -214,9 +215,7 @@ class SetupController extends Controller {
|
||||
return redirect(route('setup'))->with('error', 'Could not create database. Perhaps some credentials were incorrect?');
|
||||
}
|
||||
|
||||
$user = UserFactory::createUser($setup_finish_args->acct_username, $setup_finish_args->acct_email, $setup_finish_args->acct_password, 1, $request->ip());
|
||||
$user->role = 'admin';
|
||||
$user->save();
|
||||
$user = UserFactory::createUser($setup_finish_args->acct_username, $setup_finish_args->acct_email, $setup_finish_args->acct_password, 1, $request->ip(), false, 0, UserHelper::UserRole('ADMIN'));
|
||||
|
||||
return view('setup_thanks')->with('success', 'Set up completed! Thanks for using Polr!');
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ $app->get('/', ['as' => 'index', 'uses' => 'IndexController@showIndexPage']);
|
||||
$app->get('/logout', ['as' => 'logout', 'uses' => 'UserController@performLogoutUser']);
|
||||
$app->get('/login', ['as' => 'login', 'uses' => 'UserController@displayLoginPage']);
|
||||
$app->get('/about', ['as' => 'about', 'uses' => 'StaticPageController@displayAbout']);
|
||||
$app->get('/signup', ['as' => 'signup', 'uses' => 'UserController@displaySignupPage']);
|
||||
if (env('POLR_ALLOW_ACCT_CREATION'))
|
||||
$app->get('/signup', ['as' => 'signup', 'uses' => 'UserController@displaySignupPage']);
|
||||
$app->get('/lost_password', ['as' => 'lost_password', 'uses' => 'UserController@displayLostPasswordPage']);
|
||||
$app->get('/activate/{username}/{recovery_key}', ['as' => 'activate', 'uses' => 'UserController@performActivation']);
|
||||
$app->get('/reset_password/{username}/{recovery_key}', ['as' => 'reset_password', 'uses' => 'UserController@performPasswordReset']);
|
||||
@ -31,7 +32,8 @@ $app->get('/{short_url}/{secret_key}', ['uses' => 'LinkController@performRedirec
|
||||
/* POST endpoints */
|
||||
|
||||
$app->post('/login', ['as' => 'plogin', 'uses' => 'UserController@performLogin']);
|
||||
$app->post('/signup', ['as' => 'psignup', 'uses' => 'UserController@performSignup']);
|
||||
if (env('POLR_ALLOW_ACCT_CREATION'))
|
||||
$app->post('/signup', ['as' => 'psignup', 'uses' => 'UserController@performSignup']);
|
||||
$app->post('/shorten', ['as' => 'pshorten', 'uses' => 'LinkController@performShorten']);
|
||||
$app->post('/lost_password', ['as' => 'plost_password', 'uses' => 'UserController@performSendPasswordResetCode']);
|
||||
$app->post('/reset_password/{username}/{recovery_key}', ['as' => 'preset_password', 'uses' => 'UserController@performPasswordReset']);
|
||||
@ -44,6 +46,9 @@ $app->group(['prefix' => '/api/v2', 'namespace' => 'App\Http\Controllers'], func
|
||||
$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/toggle_user_active', ['as' => 'api_generate_new_api_key', 'uses' => 'AjaxController@toggleUserActive']);
|
||||
$app->post('admin/change_user_role', ['as' => 'api_generate_new_api_key', 'uses' => 'AjaxController@changeUserRole']);
|
||||
$app->post('admin/add_new_user', ['as' => 'api_generate_new_api_key', 'uses' => 'AjaxController@addNewUser']);
|
||||
$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']);
|
||||
|
@ -27,9 +27,10 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
{className: 'wrap-text', data: 'username', name: 'username'},
|
||||
{className: 'wrap-text', data: 'email', name: 'email'},
|
||||
{data: 'created_at', name: 'created_at'},
|
||||
{data: 'active', name: 'active'},
|
||||
|
||||
{data: 'toggle_active', name: 'toggle_active'},
|
||||
{data: 'api_action', name: 'api_action', orderable: false, searchable: false},
|
||||
{data: 'change_role', name: 'change_role'},
|
||||
{data: 'delete', name: 'delete', orderable: false, searchable: false}
|
||||
]
|
||||
}, datatables_config));
|
||||
@ -86,10 +87,105 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
el.parent().parent().slideUp();
|
||||
};
|
||||
|
||||
$scope.toggleUserActiveStatus = function($event) {
|
||||
var el = $($event.target);
|
||||
var user_id = el.data('user-id');
|
||||
|
||||
apiCall('admin/toggle_user_active', {
|
||||
'user_id': user_id,
|
||||
}, function(new_status) {
|
||||
var text = (new_status == 1) ? 'Active' : 'Inactive';
|
||||
el.text(text);
|
||||
if (el.hasClass('btn-success')) {
|
||||
el.removeClass('btn-success').addClass('btn-danger');
|
||||
}
|
||||
else {
|
||||
el.removeClass('btn-danger').addClass('btn-success');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggleNewUserBox = function($event) {
|
||||
var el = $($event.target);
|
||||
$('#add_user_box').toggle();
|
||||
if (el.text() == 'Add New User') {
|
||||
el.text('Cancel');
|
||||
$('#new_user_name').focus();
|
||||
}
|
||||
else {
|
||||
el.text('Add New User');
|
||||
$scope.resetNewUserFields();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.resetNewUserFields = function() {
|
||||
$('#new_user_name').val('');
|
||||
$('#new_user_password').val('');
|
||||
$('#new_user_email').val('');
|
||||
$("#new_user_role").val($("#new_user_role option:first").val());
|
||||
$('#new_user_status').text('');
|
||||
$('#new_user_status').css('color', '#000');
|
||||
};
|
||||
|
||||
$scope.checkNewUserFiels = function() {
|
||||
var user_name = $('#new_user_name').val();
|
||||
var user_password = $('#new_user_password').val();
|
||||
var user_email = $('#new_user_email').val();
|
||||
|
||||
if (user_name.trim() == '' || user_password.trim() == '' || user_email.trim() == '') return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$scope.addNewUser = function($event) {
|
||||
const status_error1 = 'Fields cannot be empty !';
|
||||
const status_error2 = 'Unknown Error !';
|
||||
const status_ok = 'New User added !\nPlease refresh page to see all users.';
|
||||
|
||||
var user_name = $('#new_user_name').val();
|
||||
var user_password = $('#new_user_password').val();
|
||||
var user_email = $('#new_user_email').val();
|
||||
var user_role = $('#new_user_role').val();
|
||||
|
||||
if (!$scope.checkNewUserFiels()) {
|
||||
$('#new_user_status').text(status_error1);
|
||||
$('#new_user_status').css('color', '#f00');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
apiCall('admin/add_new_user', {
|
||||
'user_name': user_name,
|
||||
'user_password': user_password,
|
||||
'user_email': user_email,
|
||||
'user_role': user_role,
|
||||
}, function(result) {
|
||||
if (result == 'OK') {
|
||||
$('#new_user_status').text(status_ok).css('color', '#325d88').hide();
|
||||
$('#new_user_status').fadeIn('normal', function() {
|
||||
$(this).delay(3000).fadeOut('slow', function() {
|
||||
$('#add_user_box').toggle();
|
||||
$('#add_user_btn').text('Add New User');
|
||||
$('#new_user_status').show();
|
||||
$scope.resetNewUserFields();
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
$('#new_user_status').text(status_error2);
|
||||
$('#new_user_status').css('color', '#f00');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Delete user
|
||||
$scope.deleteUser = function($event) {
|
||||
var el = $($event.target);
|
||||
var user_id = el.data('user-id');
|
||||
var user_name = el.data('user-name');
|
||||
|
||||
var confirmation = confirm("User '" + user_name + "' will be deleted.\nAre you sure?");
|
||||
if (!confirmation) return;
|
||||
|
||||
apiCall('admin/delete_user', {
|
||||
'user_id': user_id,
|
||||
@ -126,6 +222,7 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
} else {
|
||||
status_display_elem.text(new_status);
|
||||
}
|
||||
$('a#api_info_btn_' + user_id).attr('data-api-key', new_status);
|
||||
});
|
||||
};
|
||||
|
||||
@ -137,6 +234,7 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
apiCall('admin/toggle_api_active', {
|
||||
'user_id': user_id,
|
||||
}, function(new_status) {
|
||||
$('a#api_info_btn_' + user_id).attr('data-api-active', new_status);
|
||||
new_status = res_value_to_text(new_status);
|
||||
status_display_elem.text(new_status);
|
||||
});
|
||||
@ -172,13 +270,18 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
'user_id': user_id,
|
||||
'new_quota': parseInt(new_quota)
|
||||
}, function(next_action) {
|
||||
$('a#api_info_btn_' + user_id).attr('data-api-quota', new_quota);
|
||||
toastr.success("Quota successfully changed.", "Success");
|
||||
});
|
||||
};
|
||||
|
||||
// Open user API settings menu
|
||||
$scope.openAPIModal = function($event, username, api_key, api_active, api_quota, user_id) {
|
||||
$scope.openAPIModal = function($event, username, user_id) {
|
||||
var el = $($event.target);
|
||||
|
||||
api_active = $('a#api_info_btn_' + user_id).attr('data-api-active');
|
||||
api_key = $('a#api_info_btn_' + user_id).attr('data-api-key');
|
||||
api_quota = $('a#api_info_btn_' + user_id).attr('data-api-quota');
|
||||
|
||||
var markup = $('#api-modal-template').html();
|
||||
|
||||
@ -222,3 +325,24 @@ polr.controller('AdminCtrl', function($scope, $compile) {
|
||||
|
||||
$scope.init();
|
||||
});
|
||||
|
||||
function changeUserRole(what) {
|
||||
var user_id = what.attr('data-user-id');
|
||||
var role = what.val();
|
||||
|
||||
apiCall('admin/change_user_role', {
|
||||
'user_id': user_id,
|
||||
'role': role,
|
||||
}, function(result) {
|
||||
if (result == 'OK') {
|
||||
var parent_td = what.parent();
|
||||
var add = '<div id="role_changed_' + user_id + '" style="display: none; color: #fff; background: #0a0; font-weight: bold; text-align: center;">Changed</div>';
|
||||
parent_td.append(add);
|
||||
$('#role_changed_' + user_id).fadeIn('normal', function() {
|
||||
$(this).delay(1000).fadeOut('slow', function() {
|
||||
$('#role_changed_' + user_id).remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
<li role='presentation' aria-controls="links" class='admin-nav-item'><a href='#links'>Links</a></li>
|
||||
<li role='presentation' aria-controls="settings" class='admin-nav-item'><a href='#settings'>Settings</a></li>
|
||||
|
||||
@if ($role == 'admin')
|
||||
@if ($role == $admin_role)
|
||||
<li role='presentation' class='admin-nav-item'><a href='#admin'>Admin</a></li>
|
||||
@endif
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@if ($role == 'admin')
|
||||
@if ($role == $admin_role)
|
||||
<div role="tabpanel" class="tab-pane" id="admin">
|
||||
<h3>Links</h3>
|
||||
@include('snippets.link_table', [
|
||||
@ -54,7 +54,8 @@
|
||||
|
||||
<h3>Users</h3>
|
||||
@include('snippets.user_table', [
|
||||
'table_id' => 'admin_users_table'
|
||||
'table_id' => 'admin_users_table',
|
||||
'roles' => $user_roles
|
||||
])
|
||||
|
||||
</div>
|
||||
|
@ -1,3 +1,31 @@
|
||||
<div style="margin-bottom: 30px;">
|
||||
<a ng-click="toggleNewUserBox($event)" id="add_user_btn" class='btn btn-primary btn-sm status-display'>Add New User</a>
|
||||
<div id="add_user_box" style="display: none; margin-top: 10px;">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th width="20%">Username</th>
|
||||
<th width="20%">Password</th>
|
||||
<th width="20%">Email</th>
|
||||
<th width="10%">Role</th>
|
||||
<th width="10%"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input id="new_user_name" /></td>
|
||||
<td><input id="new_user_password" /></td>
|
||||
<td><input id="new_user_email" /></td>
|
||||
<td>
|
||||
<select id="new_user_role" style="width: 100%; height: 85%;">
|
||||
@foreach ($roles as $role_text => $role_val)
|
||||
<option value="{{$role_val}}">{{$role_text}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</td>
|
||||
<td><a ng-click="addNewUser($event)" class='btn btn-primary btn-sm status-display' style="padding-left: 15px; padding-right: 15px;">Add</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="new_user_status" style="text-align: center;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="{{$table_id}}" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -6,6 +34,7 @@
|
||||
<th>Created At</th>
|
||||
<th>Activated</th>
|
||||
<th>API</th>
|
||||
<th>Role</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
Loading…
Reference in New Issue
Block a user