Extended the user admin.

This commit is contained in:
James Cole
2016-10-15 07:11:53 +02:00
parent 6e4f2c0c8a
commit ac968dd6cd
9 changed files with 763 additions and 480 deletions

View File

@@ -78,5 +78,41 @@ class UserController extends Controller
}
/**
* @param UserRepositoryInterface $repository
* @param User $user
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show(UserRepositoryInterface $repository, User $user)
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
$subTitle = strval(trans('firefly.single_user_administration', ['email' => $user->email]));
$subTitleIcon = 'fa-user';
$defaultIp = '0.0.0.0';
$registration = Preferences::getForUser($user, 'registration_ip_address', $defaultIp)->data;
$confirmation = Preferences::getForUser($user, 'confirmation_ip_address', $defaultIp)->data;
$registrationHost = '';
$confirmationHost = '';
if ($registration != $defaultIp) {
$registrationHost = gethostbyaddr($registration);
}
if ($confirmation != $defaultIp) {
$confirmationHost = gethostbyaddr($confirmation);
}
$information = $repository->getUserData($user);
return view(
'admin.users.show',
compact(
'title', 'mainTitleIcon', 'subTitle', 'subTitleIcon', 'information',
'user', 'registration', 'confirmation', 'registrationHost', 'confirmationHost'
)
);
}
}

View File

@@ -25,6 +25,7 @@ use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\User;
/**
* HOME
@@ -115,6 +116,13 @@ Breadcrumbs::register(
}
);
Breadcrumbs::register(
'admin.users.show', function (BreadCrumbGenerator $breadcrumbs, User $user) {
$breadcrumbs->parent('admin.users');
$breadcrumbs->push(trans('firefly.single_user_administration', ['email' => $user->email]), route('admin.users.show', $user->id));
}
);
Breadcrumbs::register(
'admin.users.domains', function (BreadCrumbGenerator $breadcrumbs) {
$breadcrumbs->parent('admin.index');

View File

@@ -14,9 +14,11 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\User;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Role;
use FireflyIII\User;
use Illuminate\Support\Collection;
use Preferences;
/**
* Class UserRepository
@@ -56,4 +58,59 @@ class UserRepository implements UserRepositoryInterface
{
return $this->all()->count();
}
/**
* Return basic user information.
*
* @param User $user
*
* @return array
*/
public function getUserData(User $user): array
{
$return = [];
// two factor:
$is2faEnabled = Preferences::getForUser($user, 'twoFactorAuthEnabled', false)->data;
$has2faSecret = !is_null(Preferences::getForUser($user, 'twoFactorAuthSecret'));
$return['has_2fa'] = false;
if ($is2faEnabled && $has2faSecret) {
$return['has_2fa'] = true;
}
// is user activated?
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
$isConfirmed = Preferences::getForUser($user, 'user_confirmed', false)->data;
$return['is_activated'] = true;
if ($isConfirmed === false && $confirmAccount === true) {
$return['is_activated'] = false;
}
$return['is_admin'] = $user->hasRole('owner');
$return['blocked'] = intval($user->blocked) === 1;
$return['blocked_code'] = $user->blocked_code;
$return['accounts'] = $user->accounts()->count();
$return['journals'] = $user->transactionJournals()->count();
$return['transactions'] = $user->transactions()->count();
$return['attachments'] = $user->attachments()->count();
$return['attachments_size'] = $user->attachments()->sum('size');
$return['bills'] = $user->bills()->count();
$return['categories'] = $user->categories()->count();
$return['budgets'] = $user->budgets()->count();
$return['budgets_with_limits'] = BudgetLimit
::distinct()
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->where('amount', '>', 0)
->whereNull('budgets.deleted_at')
->where('budgets.user_id', $user->id)->get(['budget_limits.budget_id'])->count();
$return['export_jobs'] = $user->exportJobs()->count();
$return['export_jobs_success'] = $user->exportJobs()->where('status', 'export_downloaded')->count();
$return['import_jobs'] = $user->exportJobs()->count();
$return['import_jobs_success'] = $user->exportJobs()->where('status', 'import_complete')->count();
$return['rule_groups'] = $user->ruleGroups()->count();
$return['rules'] = $user->rules()->count();
$return['tags'] = $user->tags()->count();
return $return;
}
}

View File

@@ -31,6 +31,15 @@ interface UserRepositoryInterface
*/
public function all(): Collection;
/**
* Return basic user information.
*
* @param User $user
*
* @return array
*/
public function getUserData(User $user): array;
/**
* Gives a user a role.
*

View File

@@ -280,7 +280,7 @@ return [
'pref_home_show_deposits' => 'Show deposits on the home screen',
'pref_home_show_deposits_info' => 'The home screen already shows your expense accounts. Should it also show your revenue accounts?',
'pref_home_do_show_deposits' => 'Yes, show them',
'successful_count' => 'of which :count successful',
'transaction_page_size_title' => 'Page size',
'transaction_page_size_help' => 'Any list of transactions shows at most this many transactions',
'transaction_page_size_label' => 'Page size',
@@ -735,7 +735,15 @@ return [
'setting_single_user_mode' => 'Single user mode',
'setting_single_user_mode_explain' => 'By default, Firefly III only accepts one (1) registration: you. This is a security measure, preventing others from using your instance unless you allow them to. Future registrations are blocked. When you uncheck this box, others can use your instance as wel, assuming they can reach it (when it is connected to the internet).',
'store_configuration' => 'Store configuration',
'single_user_administration' => 'User administration for :email',
'hidden_fields_preferences' => 'Not all fields are visible right now. You must enable them in your <a href=":link">settings</a>.',
'user_data_information' => 'User data',
'user_information' => 'User information',
'total_size' => 'total size',
'budget_or_budgets' => 'budget(s)',
'budgets_with_limits' => 'budget(s) with configured amount',
'rule_or_rules' => 'rule(s)',
'rulegroup_or_groups' => 'rule group(s)',
// split a transaction:
'transaction_meta_data' => 'Transaction meta-data',

View File

@@ -25,6 +25,7 @@ return [
'matchedOn' => 'Matched on',
'matchesOn' => 'Matched on',
'account_type' => 'Account type',
'created_at' => 'Created at',
'new_balance' => 'New balance',
'account' => 'Account',
'matchingAmount' => 'Amount',
@@ -71,4 +72,15 @@ return [
'blocked_code' => 'Block code',
'domain' => 'Domain',
'registration_attempts' => 'Registration attempts',
'accounts_count' => 'Number of accounts',
'journals_count' => 'Number of journals',
'attachments_count' => 'Number of attachments',
'bills_count' => 'Number of bills',
'categories_count' => 'Number of categories',
'export_jobs_count' => 'Number of export jobs',
'import_jobs_count' => 'Number of import jobs',
'budget_count' => 'Number of budgets',
'rule_and_groups_count' => 'Number of rules and rule groups',
'tags_count' => 'Number of tags',
];

View File

@@ -35,7 +35,8 @@
</div>
</td>
<td>#{{ user.id }}</td>
<td>{{ user.email }}</td>
<td>
<a href="{{ route('admin.users.show',user.id) }}">{{ user.email }}</a></td>
<td>
{{ user.created_at.formatLocalized(monthAndDayFormat) }}
{{ user.created_at.format('H:i') }}

View File

@@ -0,0 +1,151 @@
{% extends "./layout/default.twig" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, user) }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'user_information'|_ }}</h3>
</div>
<div class="box-body table-responsive">
<table class="table table-striped table-bordered">
<tbody>
<tr>
<td>{{ trans('list.id') }}</td>
<td>#{{ user.id }}</td>
</tr>
<tr>
<td>{{ trans('list.email') }}</td>
<td><a href="mailto:{{ user.email }}">{{ user.email }}</a>
<td>
</tr>
<tr>
<td>{{ trans('list.created_at') }}</td>
<td>
{{ user.created_at.formatLocalized(monthAndDayFormat) }}
{{ user.created_at.format('H:i') }}</td>
</tr>
<tr>
<td>{{ trans('list.registered_from') }}</td>
<td>{{ registration }} ({{ registrationHost }})</td>
</tr>
<tr>
<td>{{ trans('list.confirmed_from') }}</td>
<td>{{ confirmation }} ({{ confirmationHost }})</td>
</tr>
<tr>
<td>{{ trans('list.is_admin') }}</td>
<td>
{% if information.is_admin %}
<small class="text-success"><i class="fa fa-fw fa-check"></i></small> Yes
{% else %}
<small class="text-danger"><i class="fa fa-fw fa-times"></i></small> No
{% endif %}
</td>
</tr>
<tr>
<td>{{ trans('list.has_two_factor') }}</td>
<td>
{% if information.has_2fa %}
<small class="text-success"><i class="fa fa-fw fa-check"></i></small> Yes
{% else %}
<small class="text-danger"><i class="fa fa-fw fa-times"></i></small> No
{% endif %}
</td>
</tr>
<tr>
<td>{{ trans('list.is_activated') }}</td>
<td>
{% if information.activated %}
<small class="text-success"><i class="fa fa-fw fa-check"></i></small> Yes
{% else %}
<small class="text-danger"><i class="fa fa-fw fa-times"></i></small> No
{% endif %}
</td>
</tr>
<tr>
<td>{{ trans('list.is_blocked') }}</td>
<td>
{% if information.blocked == 1 %}
<small class="text-danger"><i class="fa fa-fw fa-check" title="{{ 'yes'|_ }}"></i></small> Yes:
{% if information.blocked_code == "" %}
<em>~</em>
{% else %}
{{ information.blocked_code }}
{% endif %}
{% else %}
<small class="text-success"><i class="fa fa-fw fa-times" title="{{ 'no'|_ }}"></i></small> No
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'user_data_information'|_ }}</h3>
</div>
<div class="box-body table-responsive">
<table class="table table-striped table-bordered">
<tr>
<td>{{ trans('list.accounts_count') }}</td>
<td>{{ information.accounts }}</td>
</tr>
<tr>
<td>{{ trans('list.journals_count') }}</td>
<td>{{ information.journals }} ({{ information.transactions }} {{ trans('firefly.transactions') }})</td>
</tr>
<tr>
<td>{{ trans('list.attachments_count') }}</td>
<td>{{ information.attachments }} ({{ trans('firefly.total_size') }}: {{ information.attachments_size|filesize }})</td>
</tr>
<tr>
<td>{{ trans('list.bills_count') }}</td>
<td>{{ information.bills }}</td>
</tr>
<tr>
<td>{{ trans('list.categories_count') }}</td>
<td>{{ information.categories }}</td>
</tr>
<tr>
<td>{{ trans('list.export_jobs_count') }}</td>
<td>{{ information.export_jobs }}, {{ trans('firefly.successful_count', {count: information.export_jobs_success}) }}
<!-- of which x successful --></td>
</tr>
<tr>
<td>{{ trans('list.import_jobs_count') }}</td>
<td>{{ information.import_jobs }}, {{ trans('firefly.successful_count', {count: information.import_jobs_success}) }}
<!-- of which x successful --></td>
</tr>
<tr>
<td>{{ trans('list.budget_count') }}</td>
<td>{{ information.budgets }} {{ trans('firefly.budget_or_budgets') }},
{{ information.budgets_with_limits }} {{ trans('firefly.budgets_with_limits') }}</td>
</tr>
<tr>
<td>{{ trans('list.rule_and_groups_count') }}</td>
<td>
{{ information.rules }} {{ 'rule_or_rules'|_ }} {{ 'in'|_ }} {{ information.rule_groups }}
{{ 'rulegroup_or_groups'|_ }}
</td>
</tr>
<tr>
<td>{{ trans('list.tags_count') }}</td>
<td>{{ information.tags }} tags</td>
</tr>
</table>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -435,6 +435,7 @@ Route::group(
// user manager
Route::get('/admin/users', ['uses' => 'Admin\UserController@index', 'as' => 'admin.users']);
Route::get('/admin/users/edit/{user}', ['uses' => 'Admin\UserController@edit', 'as' => 'admin.users.edit']);
Route::get('/admin/users/show/{user}', ['uses' => 'Admin\UserController@show', 'as' => 'admin.users.show']);
// user domains:
Route::get('/admin/domains', ['uses' => 'Admin\DomainController@domains', 'as' => 'admin.users.domains']);