diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index e91ae8f676..82fd0a0195 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -52,6 +52,7 @@ class UsersController extends Controller 'users.phone', 'users.state', 'users.two_factor_enrolled', + 'users.two_factor_optin', 'users.updated_at', 'users.username', 'users.zip', diff --git a/app/Http/Transformers/UsersTransformer.php b/app/Http/Transformers/UsersTransformer.php index 569b3b56af..49755db7dc 100644 --- a/app/Http/Transformers/UsersTransformer.php +++ b/app/Http/Transformers/UsersTransformer.php @@ -53,6 +53,8 @@ class UsersTransformer 'permissions' => $user->decodePermissions(), 'activated' => ($user->activated =='1') ? true : false, 'two_factor_activated' => ($user->two_factor_active()) ? true : false, + 'two_factor_enrolled' => ($user->two_factor_active_and_enrolled()) ? true : false, + 'assets_count' => (int) $user->assets_count, 'licenses_count' => (int) $user->licenses_count, 'accessories_count' => (int) $user->accessories_count, diff --git a/app/Models/User.php b/app/Models/User.php index 15e29657d7..edc5883ef1 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -389,7 +389,11 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo } /** - * Check whether two-factor authorization is required and the user has activated it + * Check whether two-factor authorization is requiredfor this user + * + * 0 = 2FA disabled + * 1 = 2FA optional + * 2 = 2FA universally required * * @author [A. Gianotto] [] * @since [v4.0] @@ -398,10 +402,45 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo */ public function two_factor_active () { - if (Setting::getSettings()->two_factor_enabled !='0') { - if (($this->two_factor_optin =='1') && ($this->two_factor_enrolled)) { - return true; - } + // If the 2FA is optional and the user has opted in + if ((Setting::getSettings()->two_factor_enabled =='1') && ($this->two_factor_optin =='1')) + { + return true; + } + // If the 2FA is required for everyone so is implicitly active + elseif (Setting::getSettings()->two_factor_enabled =='2') + { + return true; + } + + return false; + + } + + /** + * Check whether two-factor authorization is required and the user has activated it + * and enrolled a device + * + * 0 = 2FA disabled + * 1 = 2FA optional + * 2 = 2FA universally required + * + * @author [A. Gianotto] [] + * @since [v4.6.14] + * + * @return bool + */ + public function two_factor_active_and_enrolled () { + + // If the 2FA is optional and the user has opted in and is enrolled + if ((Setting::getSettings()->two_factor_enabled =='1') && ($this->two_factor_optin =='1') && ($this->two_factor_enrolled =='1')) + { + return true; + } + // If the 2FA is required for everyone and the user has enrolled + elseif ((Setting::getSettings()->two_factor_enabled =='2') && ($this->two_factor_enrolled)) + { + return true; } return false; diff --git a/app/Presenters/UserPresenter.php b/app/Presenters/UserPresenter.php index 0d49852263..aa5d3f268c 100644 --- a/app/Presenters/UserPresenter.php +++ b/app/Presenters/UserPresenter.php @@ -226,14 +226,14 @@ class UserPresenter extends Presenter [ "field" => "two_factor_enrolled", "searchable" => false, - "sortable" => false, + "sortable" => true, "switchable" => true, "title" => trans('admin/users/general.two_factor_enrolled'), "visible" => false, 'formatter' => 'trueFalseFormatter' ], [ - "field" => "two_factor_active", + "field" => "two_factor_activated", "searchable" => false, "sortable" => false, "switchable" => true, @@ -246,7 +246,7 @@ class UserPresenter extends Presenter "searchable" => false, "sortable" => true, "switchable" => true, - "title" => trans('general.activated'), + "title" => trans('general.login_enabled'), "visible" => true, 'formatter' => 'trueFalseFormatter' ], diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index ea339cf9a7..ae2bcf0a44 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -221,4 +221,5 @@ 'zip' => 'Zip', 'noimage' => 'No image uploaded or image not found.', 'token_expired' => 'Your form session has expired. Please try again.', + 'login_enabled' => 'Login Enabled', ]; diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index 0a79aa27f1..5c87eb361c 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -127,22 +127,22 @@ @if (!is_null($user->company)) - + @endif - + - + - + - + @endif @if ($user->employee_num) - + @endif @if ($user->manager) - + - + @endif @if ($user->phone) - + @endif @if ($user->userloc) - + @@ -210,14 +210,14 @@ @endif @if ($user->last_login) - + @endif @if (!is_null($user->department)) - + @endif @@ -227,6 +227,45 @@ @endif + + + + + + @if ($user->activated=='1') + + + + + + + + + + @endif + +
{{ trans('general.company') }}{{ trans('general.company') }} {{ $user->company->name }}
{{ trans('admin/users/table.name') }}{{ trans('admin/users/table.name') }} {{ $user->present()->fullName() }}
{{ trans('admin/users/table.username') }}{{ trans('admin/users/table.username') }} {{ $user->username }}
{{ trans('general.groups') }}{{ trans('general.groups') }} @if ($user->groups->count() > 0) @foreach ($user->groups as $group) @@ -164,21 +164,21 @@ @if ($user->jobtitle)
{{ trans('admin/users/table.job') }}{{ trans('admin/users/table.job') }} {{ $user->jobtitle }}
{{ trans('admin/users/table.employee_num') }}{{ trans('admin/users/table.employee_num') }} {{ $user->employee_num }}
{{ trans('admin/users/table.manager') }}{{ trans('admin/users/table.manager') }} {{ $user->manager->getFullNameAttribute() }} @@ -188,21 +188,21 @@ @if ($user->email)
{{ trans('admin/users/table.email') }}{{ trans('admin/users/table.email') }} {{ $user->email }}
{{ trans('admin/users/table.phone') }}{{ trans('admin/users/table.phone') }} {{ $user->phone }}
{{ trans('admin/users/table.location') }}{{ trans('admin/users/table.location') }} {{ link_to_route('locations.show', $user->userloc->name, [$user->userloc->id]) }}
{{ trans('general.last_login') }}{{ trans('general.last_login') }} {{ \App\Helpers\Helper::getFormattedDateObject($user->last_login, 'datetime', false) }}
{{ trans('general.department') }}{{ trans('general.department') }} {{ $user->department->name }}
{{ $user->created_at->format('F j, Y h:iA') }}
{{ trans('general.login_enabled') }}{{ ($user->activated=='1') ? trans('general.yes') : trans('general.no') }}
{{ trans('admin/users/general.two_factor_active') }}{{ ($user->two_factor_active()) ? trans('general.yes') : trans('general.no') }}
{{ trans('admin/users/general.two_factor_enrolled') }} +
+
+ {{ ($user->two_factor_active_and_enrolled()) ? trans('general.yes') : trans('general.no') }} +
+ + @if ((Auth::user()->isSuperUser()) && ($snipeSettings->two_factor_enabled!='0')) +
+ {{ trans('admin/settings/general.two_factor_reset') }} + + + + + + + +

{{ trans('admin/settings/general.two_factor_reset_help') }}

+
+
+ @endif + +
@@ -542,6 +581,40 @@ @include ('partials.bootstrap-table', ['simple_view' => true])