Basic user admin.

This commit is contained in:
James Cole 2016-04-03 07:07:17 +02:00
parent 67caf6ef1f
commit ad402021ed
10 changed files with 322 additions and 6 deletions

View File

@ -0,0 +1,33 @@
<?php
/**
* HomeController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
/**
* Class HomeController
*
* @package FireflyIII\Http\Controllers\Admin
*/
class HomeController extends Controller
{
/**
* @return mixed
*/
public function index()
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
return view('admin.index', compact('title', 'mainTitleIcon'));
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
* UserController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Log;
use Preferences;
/**
* Class UserController
*
* @package FireflyIII\Http\Controllers\Admin
*/
class UserController extends Controller
{
/**
* @param UserRepositoryInterface $repository
*/
public function index(UserRepositoryInterface $repository)
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
$subTitle = strval(trans('firefly.user_administration'));
$subTitleIcon = 'fa-users';
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
// list all users:
$all = $repository->all();
// not deleted users:
$users = $all->filter(
function (User $user) {
if (!(intval($user->blocked) === 1 && is_null($user->blocked_code))) {
return $user;
}
}
);
// add meta stuff.
$users->each(
function (User $user) use ($confirmAccount) {
// user must be logged in, then continue:
$isConfirmed = Preferences::getForUser($user, 'user_confirmed', false)->data;
if ($isConfirmed === false && $confirmAccount === true) {
$user->activated = false;
} else {
$user->activated = true;
}
}
);
return view('admin.users.index', compact('title', 'mainTitleIcon', 'subTitle', 'subTitleIcon', 'users'));
}
}

View File

@ -7,6 +7,7 @@ use FireflyIII\Http\Middleware\Authenticate;
use FireflyIII\Http\Middleware\AuthenticateTwoFactor;
use FireflyIII\Http\Middleware\Binder;
use FireflyIII\Http\Middleware\EncryptCookies;
use FireflyIII\Http\Middleware\IsAdmin;
use FireflyIII\Http\Middleware\IsConfirmed;
use FireflyIII\Http\Middleware\IsNotConfirmed;
use FireflyIII\Http\Middleware\Range;
@ -121,6 +122,25 @@ class Kernel extends HttpKernel
Range::class,
Binder::class,
],
// MUST be logged in
// MUST have 2fa
// MUST be confirmed.
// MUST have owner role
// (this group includes the other Firefly middleware)
'admin' => [
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
Authenticate::class,
AuthenticateTwoFactor::class,
IsConfirmed::class,
IsAdmin::class,
Range::class,
Binder::class,
],
'api' => [
'throttle:60,1',

View File

@ -0,0 +1,63 @@
<?php
/**
* IsAdmin.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
/**
* IsConfirmed.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;
use Closure;
use FireflyIII\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Class IsAdmin
*
* @package FireflyIII\Http\Middleware
*/
class IsAdmin
{
/**
* Handle an incoming request. User account must be confirmed for this routine to let
* the user pass.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
} else {
/** @var User $user */
$user = Auth::user();
if (!$user->hasRole('owner')) {
return redirect(route('home'));
}
}
return $next($request);
}
}

View File

@ -28,9 +28,8 @@ Route::group(
);
/**
* For other routes, it is only relevant that the user is authenticated.
* For some other routes, it is only relevant that the user is authenticated.
*/
Route::group(
['middleware' => 'user-simple-auth'], function () {
Route::get('/error', 'HomeController@displayError');
@ -389,3 +388,17 @@ Route::group(
}
);
/**
* For the admin routes, the user must be logged in and have the role of 'owner'
*/
Route::group(
['middleware' => 'admin'], function () {
// admin home
Route::get('/admin', ['uses' => 'Admin\HomeController@index', 'as' => 'admin.index']);
// user manager
Route::get('/admin/users', ['uses' => 'Admin\UserController@index', 'as' => 'admin.users']);
}
);

View File

@ -13,6 +13,7 @@ namespace FireflyIII\Repositories\User;
use FireflyIII\Models\Role;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Class UserRepository
@ -22,6 +23,14 @@ use FireflyIII\User;
class UserRepository implements UserRepositoryInterface
{
/**
* @return Collection
*/
public function all(): Collection
{
return User::orderBy('id', 'DESC')->get(['users.*']);
}
/**
* @param User $user
* @param string $role

View File

@ -12,6 +12,7 @@ namespace FireflyIII\Repositories\User;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Interface UserRepositoryInterface
@ -20,6 +21,11 @@ use FireflyIII\User;
*/
interface UserRepositoryInterface
{
/**
* @return Collection
*/
public function all(): Collection;
/**
* @param User $user
* @param string $role

View File

@ -34,20 +34,36 @@ class Preferences
return true;
}
/**
* @param $name
* @param null $default
*
* @return Preference|null
*/
public function get($name, $default = null)
{
$user = Auth::user();
if (is_null($user)) {
return $default;
}
return $this->getForUser(Auth::user(), $name, $default);
}
/**
* @param string $name
* @param string $default
*
* @return null|\FireflyIII\Models\Preference
*/
public function get($name, $default = null)
public function getForUser(User $user, $name, $default = null)
{
$fullName = 'preference' . Auth::user()->id . $name;
$fullName = 'preference' . $user->id . $name;
if (Cache::has($fullName)) {
return Cache::get($fullName);
}
$preference = Preference::where('user_id', Auth::user()->id)->where('name', $name)->first(['id', 'name', 'data_encrypted']);
$preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data_encrypted']);
if ($preference) {
Cache::forever($fullName, $preference);
@ -60,7 +76,7 @@ class Preferences
return null;
}
return $this->set($name, $default);
return $this->setForUser($user, $name, $default);
}

View File

@ -0,0 +1,27 @@
{% extends "./layout/default.twig" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'user_administration'|_ }}</h3>
</div>
<div class="box-body">
<ul>
<li><a href="{{ route('admin.users') }}">{{ 'list_all_users'|_ }}</a></li>
<!-- <li><a href="#">{{ 'user_related_settings'|_ }}</a></li> -->
</ul>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
{% endblock %}
{% block styles %}
{% endblock %}

View File

@ -0,0 +1,60 @@
{% extends "./layout/default.twig" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'all_users'|_ }}</h3>
</div>
<div class="box-body table-responsive no-padding">
<table class="table table-condensed table-sortable">
<thead>
<tr>
<th>{{ trans('list.email') }}</th>
<th>{{ trans('list.registered_at') }}</th>
<th>{{ trans('list.is_activated') }}</th>
<th>{{ trans('list.is_blocked') }}</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.email }}</td>
<td>
{{ user.created_at.formatLocalized(monthAndDayFormat) }}
{{ user.created_at.format('H:i') }}
</td>
{% if user.activated %}
<td>&nbsp;</td>
{% else %}
<td class="bg-danger"><i class="fa fa-fw fa-times"></i></td>
{% endif %}
{% if user.blocked == 1 %}
<td class="bg-danger">
{% if user.blocked_code == "" %}
<em>no reason</em>
{% else %}
{{ user.blocked_code }}
{% endif %}
</td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
{% endblock %}
{% block styles %}
{% endblock %}