mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-25 03:08:51 +02:00
Added infos about 2FA and possibilities to disable them all on user admin page.
This commit is contained in:
parent
b5e80ec1b7
commit
b4958cbaf8
5 changed files with 106 additions and 11 deletions
|
@ -185,7 +185,7 @@ $(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("ajaxUI:start ajaxUI:reload", function() {
|
$(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
$("[data-delete-form]").unbind('submit').submit(function(event) {
|
$("[data-delete-form]").unbind('submit').submit(function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
let form = this;
|
let form = this;
|
||||||
|
@ -197,17 +197,38 @@ $(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
let message = $(this).data("message");
|
let message = $(this).data("message");
|
||||||
|
|
||||||
bootbox.confirm({
|
bootbox.confirm({
|
||||||
message: message,
|
message: message, title: title, callback: function (result) {
|
||||||
title: title,
|
|
||||||
callback: function(result) {
|
|
||||||
//If the dialog was confirmed, then submit the form.
|
//If the dialog was confirmed, then submit the form.
|
||||||
if(result) {
|
if (result) {
|
||||||
ajaxUI.submitForm(form, btn);
|
ajaxUI.submitForm(form, btn);
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Register for forms with delete-buttons
|
||||||
|
$("[data-delete-btn]").parents('form').unbind('submit').submit(function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
let form = this;
|
||||||
|
//Get the submit button
|
||||||
|
let btn = document.activeElement;
|
||||||
|
|
||||||
|
let title = $(btn).data("title");
|
||||||
|
let message = $(btn).data("message");
|
||||||
|
|
||||||
|
bootbox.confirm({
|
||||||
|
message: message, title: title, callback: function (result) {
|
||||||
|
//If the dialog was confirmed, then submit the form.
|
||||||
|
if (result) {
|
||||||
|
ajaxUI.submitForm(form, btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("ajaxUI:start ajaxUI:reload", function() {
|
$(document).on("ajaxUI:start ajaxUI:reload", function() {
|
||||||
|
|
|
@ -67,6 +67,29 @@ class UserController extends AdminPages\BaseAdminController
|
||||||
*/
|
*/
|
||||||
public function edit(User $entity, Request $request, EntityManagerInterface $em)
|
public function edit(User $entity, Request $request, EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
|
//Handle 2FA disabling
|
||||||
|
|
||||||
|
if($request->request->has('reset_2fa')) {
|
||||||
|
//Check if the admin has the needed permissions
|
||||||
|
$this->denyAccessUnlessGranted('set_password', $entity);
|
||||||
|
if ($this->isCsrfTokenValid('reset_2fa'.$entity->getId(), $request->request->get('_token'))) {
|
||||||
|
//Disable Google authenticator
|
||||||
|
$entity->setGoogleAuthenticatorSecret(null);
|
||||||
|
$entity->setBackupCodes([]);
|
||||||
|
//Remove all U2F keys
|
||||||
|
foreach($entity->getU2FKeys() as $key) {
|
||||||
|
$em->remove($key);
|
||||||
|
}
|
||||||
|
//Invalidate trusted devices
|
||||||
|
$entity->invalidateTrustedDeviceTokens();
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', 'user.edit.reset_success');
|
||||||
|
} else {
|
||||||
|
$this->addFlash('danger', 'csfr_invalid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->_edit($entity, $request, $em);
|
return $this->_edit($entity, $request, $em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ use App\Services\MoneyFormatter;
|
||||||
use App\Services\SIFormatter;
|
use App\Services\SIFormatter;
|
||||||
use App\Services\TreeBuilder;
|
use App\Services\TreeBuilder;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
use Twig\TwigFilter;
|
use Twig\TwigFilter;
|
||||||
use Twig\TwigFunction;
|
use Twig\TwigFunction;
|
||||||
|
@ -49,13 +50,14 @@ class AppExtension extends AbstractExtension
|
||||||
protected $amountFormatter;
|
protected $amountFormatter;
|
||||||
protected $attachmentURLGenerator;
|
protected $attachmentURLGenerator;
|
||||||
protected $FAIconGenerator;
|
protected $FAIconGenerator;
|
||||||
|
protected $translator;
|
||||||
|
|
||||||
public function __construct(EntityURLGenerator $entityURLGenerator, MarkdownParser $markdownParser,
|
public function __construct(EntityURLGenerator $entityURLGenerator, MarkdownParser $markdownParser,
|
||||||
SerializerInterface $serializer, TreeBuilder $treeBuilder,
|
SerializerInterface $serializer, TreeBuilder $treeBuilder,
|
||||||
MoneyFormatter $moneyFormatter,
|
MoneyFormatter $moneyFormatter,
|
||||||
SIFormatter $SIFormatter, AmountFormatter $amountFormatter,
|
SIFormatter $SIFormatter, AmountFormatter $amountFormatter,
|
||||||
AttachmentURLGenerator $attachmentURLGenerator,
|
AttachmentURLGenerator $attachmentURLGenerator,
|
||||||
FAIconGenerator $FAIconGenerator)
|
FAIconGenerator $FAIconGenerator, TranslatorInterface $translator)
|
||||||
{
|
{
|
||||||
$this->entityURLGenerator = $entityURLGenerator;
|
$this->entityURLGenerator = $entityURLGenerator;
|
||||||
$this->markdownParser = $markdownParser;
|
$this->markdownParser = $markdownParser;
|
||||||
|
@ -66,6 +68,7 @@ class AppExtension extends AbstractExtension
|
||||||
$this->amountFormatter = $amountFormatter;
|
$this->amountFormatter = $amountFormatter;
|
||||||
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
||||||
$this->FAIconGenerator = $FAIconGenerator;
|
$this->FAIconGenerator = $FAIconGenerator;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFilters()
|
public function getFilters()
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{% extends "AdminPages/EntityAdminBase.html.twig" %}
|
{% extends "AdminPages/EntityAdminBase.html.twig" %}
|
||||||
|
|
||||||
|
{% import "helper.twig" as helper %}
|
||||||
|
|
||||||
|
{# @var entity \App\Entity\UserSystem\User #}
|
||||||
|
|
||||||
{% block card_title %}
|
{% block card_title %}
|
||||||
<i class="fas fa-user fa-fw"></i> {% trans %}user.edit.caption{% endtrans %}
|
<i class="fas fa-user fa-fw"></i> {% trans %}user.edit.caption{% endtrans %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -34,6 +38,42 @@
|
||||||
{{ form_row(form.new_password) }}
|
{{ form_row(form.new_password) }}
|
||||||
{{ form_row(form.need_pw_change) }}
|
{{ form_row(form.need_pw_change) }}
|
||||||
{{ form_row(form.disabled) }}
|
{{ form_row(form.disabled) }}
|
||||||
|
|
||||||
|
{% if entity.id is not null %}
|
||||||
|
<div class="offset-3 mb-3">
|
||||||
|
<hr>
|
||||||
|
<h6>{% trans %}user.edit.tfa.caption{% endtrans %}</h6>
|
||||||
|
|
||||||
|
<p><b>{% trans %}user.edit.tfa.google_active{% endtrans %}:</b> {{ helper.boolean(entity.googleAuthenticatorEnabled) }}</p>
|
||||||
|
<p class="mb-0"><b>{% trans %}tfa_backup.remaining_tokens{% endtrans %}:</b> {{ entity.backupCodes | length }}</p>
|
||||||
|
<p><b>{% trans %}tfa_backup.generation_date{% endtrans %}:</b>
|
||||||
|
{% if entity.backupCodesGenerationDate is not null %}
|
||||||
|
{{ entity.backupCodesGenerationDate | format_datetime }}
|
||||||
|
{% else %}
|
||||||
|
{% trans %}user.edit.tfa.disabled{% endtrans %}
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
<p><b>{% trans %}user.edit.tfa.u2f_keys_count{% endtrans %}:</b>
|
||||||
|
{% if entity.u2FAuthEnabled %}
|
||||||
|
{{ entity.u2FKeys | length }}
|
||||||
|
{% else %}
|
||||||
|
{% trans %}user.edit.tfa.disabled{% endtrans %}
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% set tfa_disable_disabled = not is_granted('set_password', entity) %}
|
||||||
|
{# Disable button when he has no 2FA activated #}
|
||||||
|
{% if not entity.u2FAuthEnabled and not entity.googleAuthenticatorEnabled and entity.backupCodes is empty %}
|
||||||
|
{% set tfa_disable_disabled = true %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token('reset_2fa' ~ entity.id) }}">
|
||||||
|
<button class="btn btn-warning" {% if tfa_disable_disabled %}disabled="disabled"{% endif %}
|
||||||
|
data-delete-btn data-title="{% trans %}user.edit.tfa.disable_tfa_title{% endtrans %}" data-message="{% trans %}user.edit.tfa.disable_tfa_message{% endtrans %}"
|
||||||
|
type="submit" name="reset_2fa">{% trans %}user.edit.tfa.disable_tfa.btn{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane" id="permissions">
|
<div class="tab-pane" id="permissions">
|
||||||
|
|
|
@ -80,4 +80,12 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro bool_icon(bool) %}
|
||||||
|
{% if bool %}
|
||||||
|
<i class="fas fa-check-circle fa-fw" title="{% trans %}Yes{% endtrans %}"></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="fas fa-times-circle fa-fw" title="{% trans %}No{% endtrans %}"></i>
|
||||||
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
Loading…
Add table
Add a link
Reference in a new issue