Skip to content

Commit c01b778

Browse files
elias-playfindereliasfernandez
authored andcommitted
Impersonate from user menu dropdown #6524
1 parent c4d72d4 commit c01b778

33 files changed

+141
-46
lines changed

assets/js/app.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class App {
3232
this.#createModalWindowsForDeleteActions();
3333
this.#createPopovers();
3434
this.#createTooltips();
35+
this.#createImpersonateModal();
3536

3637
document.addEventListener('ea.collection.item-added', () => this.#createAutoCompleteFields());
3738
}
@@ -449,4 +450,12 @@ class App {
449450
});
450451
});
451452
}
453+
454+
#createImpersonateModal(){
455+
const impersonateButton = document.querySelector('#modal-impersonate-link');
456+
const impersonateModal = document.querySelector(impersonateButton.getAttribute('data-bs-target'));
457+
document.querySelector('#impersonate-modal-apply-button').addEventListener('click', () => {
458+
impersonateModal.querySelector('form').submit();
459+
});
460+
}
452461
}

public/app.1ecd6d7a.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

public/app.3682f817.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/app.9f3e666b.css

Lines changed: 0 additions & 22 deletions
This file was deleted.

public/app.ab66d3f1.css

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/entrypoints.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"entrypoints": {
33
"app": {
44
"css": [
5-
"/app.9f3e666b.css"
5+
"/app.ab66d3f1.css"
66
],
77
"js": [
8-
"/app.1ecd6d7a.js"
8+
"/app.3682f817.js"
99
]
1010
},
1111
"form": {
@@ -30,10 +30,10 @@
3030
},
3131
"field-code-editor": {
3232
"css": [
33-
"/field-code-editor.cdcf15eb.css"
33+
"/field-code-editor.b7d8b94d.css"
3434
],
3535
"js": [
36-
"/field-code-editor.877c61fa.js"
36+
"/field-code-editor.c092384b.js"
3737
]
3838
},
3939
"field-collection": {
@@ -66,7 +66,7 @@
6666
"/field-text-editor.750725ec.css"
6767
],
6868
"js": [
69-
"/field-text-editor.cb6de4f5.js"
69+
"/field-text-editor.ae3901ca.js"
7070
]
7171
},
7272
"login": {

public/field-code-editor.cdcf15eb.css renamed to public/field-code-editor.b7d8b94d.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/field-code-editor.877c61fa.js renamed to public/field-code-editor.c092384b.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/field-text-editor.ae3901ca.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/field-text-editor.cb6de4f5.js

Lines changed: 0 additions & 1 deletion
This file was deleted.
115 KB
Binary file not shown.
-116 KB
Binary file not shown.
-24.9 KB
Binary file not shown.
24.9 KB
Binary file not shown.
-155 KB
Binary file not shown.
154 KB
Binary file not shown.
4.69 KB
Binary file not shown.
-4.68 KB
Binary file not shown.

public/manifest.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
{
2-
"app.css": "app.9f3e666b.css",
3-
"app.js": "app.1ecd6d7a.js",
2+
"app.css": "app.ab66d3f1.css",
3+
"app.js": "app.3682f817.js",
44
"form.js": "form.bcec6c2a.js",
55
"page-layout.js": "page-layout.3347892e.js",
66
"page-color-scheme.js": "page-color-scheme.30cb23c2.js",
77
"field-boolean.js": "field-boolean.ae2abe46.js",
8-
"field-code-editor.css": "field-code-editor.cdcf15eb.css",
9-
"field-code-editor.js": "field-code-editor.877c61fa.js",
8+
"field-code-editor.css": "field-code-editor.b7d8b94d.css",
9+
"field-code-editor.js": "field-code-editor.c092384b.js",
1010
"field-collection.js": "field-collection.f685c209.js",
1111
"field-file-upload.js": "field-file-upload.7f9cb952.js",
1212
"field-image.js": "field-image.c338d2ad.js",
1313
"field-slug.js": "field-slug.df11f109.js",
1414
"field-textarea.js": "field-textarea.74319bb1.js",
1515
"field-text-editor.css": "field-text-editor.750725ec.css",
16-
"field-text-editor.js": "field-text-editor.cb6de4f5.js",
16+
"field-text-editor.js": "field-text-editor.ae3901ca.js",
1717
"login.js": "login.7259f5de.js",
18-
"fonts/fa-solid-900.ttf": "fonts/fa-solid-900.ad1782c7.ttf",
19-
"fonts/fa-brands-400.ttf": "fonts/fa-brands-400.26b80c88.ttf",
20-
"fonts/fa-solid-900.woff2": "fonts/fa-solid-900.83a538a0.woff2",
21-
"fonts/fa-brands-400.woff2": "fonts/fa-brands-400.fdbb5585.woff2",
22-
"fonts/fa-regular-400.ttf": "fonts/fa-regular-400.05fdd87b.ttf",
23-
"fonts/fa-regular-400.woff2": "fonts/fa-regular-400.4f6a2dab.woff2",
24-
"fonts/fa-v4compatibility.ttf": "fonts/fa-v4compatibility.fa86b3c8.ttf",
25-
"fonts/fa-v4compatibility.woff2": "fonts/fa-v4compatibility.c3ea317a.woff2"
18+
"fonts/fa-solid-900.ttf": "fonts/fa-solid-900.07ed6d5f.ttf",
19+
"fonts/fa-brands-400.ttf": "fonts/fa-brands-400.0ff70dcb.ttf",
20+
"fonts/fa-solid-900.woff2": "fonts/fa-solid-900.93f719f4.woff2",
21+
"fonts/fa-brands-400.woff2": "fonts/fa-brands-400.bb8d5a14.woff2",
22+
"fonts/fa-regular-400.ttf": "fonts/fa-regular-400.17a6e1ae.ttf",
23+
"fonts/fa-regular-400.woff2": "fonts/fa-regular-400.bc372268.woff2",
24+
"fonts/fa-v4compatibility.ttf": "fonts/fa-v4compatibility.0f6cb412.ttf",
25+
"fonts/fa-v4compatibility.woff2": "fonts/fa-v4compatibility.6cfec841.woff2"
2626
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace EasyCorp\Bundle\EasyAdminBundle\Config\Menu;
4+
5+
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Menu\MenuItemInterface;
6+
use EasyCorp\Bundle\EasyAdminBundle\Dto\MenuItemDto;
7+
use Symfony\Contracts\Translation\TranslatableInterface;
8+
9+
/**
10+
* @see EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem::linkToAccessImpersonation()
11+
*
12+
* @author Elías Fernández <[email protected]>
13+
*/
14+
final class AccessImpersonationMenuItem implements MenuItemInterface
15+
{
16+
use MenuItemTrait;
17+
18+
public function __construct(TranslatableInterface|string $label, ?string $icon)
19+
{
20+
$this->dto = new MenuItemDto();
21+
22+
$this->dto->setType(MenuItemDto::TYPE_ACCESS_IMPERSONATION);
23+
$this->dto->setLabel($label);
24+
$this->dto->setIcon($icon);
25+
$this->dto->setLinkUrl('test');
26+
}
27+
}

src/Config/MenuItem.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace EasyCorp\Bundle\EasyAdminBundle\Config;
44

5+
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\AccessImpersonationMenuItem;
56
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\CrudMenuItem;
67
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\DashboardMenuItem;
78
use EasyCorp\Bundle\EasyAdminBundle\Config\Menu\ExitImpersonationMenuItem;
@@ -45,6 +46,14 @@ public static function linkToExitImpersonation(TranslatableInterface|string $lab
4546
return new ExitImpersonationMenuItem($label, $icon);
4647
}
4748

49+
/**
50+
* @param string|null $icon The full CSS classes of the FontAwesome icon to render (see https://fontawesome.com/v6/search?m=free)
51+
*/
52+
public static function linkToAccessImpersonation(TranslatableInterface|string $label, ?string $icon = null): AccessImpersonationMenuItem
53+
{
54+
return new AccessImpersonationMenuItem($label, $icon);
55+
}
56+
4857
/**
4958
* @param string|null $icon The full CSS classes of the FontAwesome icon to render (see https://fontawesome.com/v6/search?m=free)
5059
*/

src/Controller/AbstractDashboardController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ public function configureUserMenu(UserInterface $user): UserMenu
6969
if ($this->isGranted(Permission::EA_EXIT_IMPERSONATION)) {
7070
$userMenuItems[] = MenuItem::linkToExitImpersonation(t('user.exit_impersonation', domain: 'EasyAdminBundle'), 'internal:user-lock');
7171
}
72+
if (!$this->isGranted(Permission::EA_EXIT_IMPERSONATION) && $this->isGranted(Permission::EA_CAN_SWITCH_USER)) {
73+
$userMenuItems[] = MenuItem::linkToAccessImpersonation(t('user.impersonate_user', domain: 'EasyAdminBundle'), 'fa-user-lock');
74+
}
7275

7376
$userName = method_exists($user, '__toString') ? (string) $user : $user->getUserIdentifier();
7477

src/Dto/MenuItemDto.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ final class MenuItemDto
1414
public const TYPE_URL = 'url';
1515
public const TYPE_SECTION = 'section';
1616
public const TYPE_EXIT_IMPERSONATION = 'exit_impersonation';
17+
public const TYPE_ACCESS_IMPERSONATION = 'access_impersonation';
1718
public const TYPE_DASHBOARD = 'dashboard';
1819
public const TYPE_LOGOUT = 'logout';
1920
public const TYPE_SUBMENU = 'submenu';

src/Security/Permission.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ final class Permission
1212
public const EA_VIEW_MENU_ITEM = 'EA_VIEW_MENU_ITEM';
1313
public const EA_VIEW_FIELD = 'EA_VIEW_FIELD';
1414
public const EA_EXIT_IMPERSONATION = 'EA_EXIT_IMPERSONATION';
15+
public const EA_CAN_SWITCH_USER = 'EA_CAN_SWITCH_USER';
1516

1617
public static function exists(?string $permissionName): bool
1718
{
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<div id="modal-impersonate" class="modal fade" tabindex="-1">
2+
<div class="modal-dialog">
3+
<div class="modal-content">
4+
<div class="modal-body p-4">
5+
<form method="get">
6+
<div class="row">
7+
<div class="col-12">
8+
<div class="field-text form-group">
9+
<label for="_switch_user" class="form-control-label required">{{ 'impersonate.username'|trans(domain = 'EasyAdminBundle') }}</label>
10+
<div class="form-widget">
11+
<input type="text" name="_switch_user" id="impersonate_user_name" required="required" class="form-control" value="">
12+
</div>
13+
</div>
14+
</div>
15+
</div>
16+
</form>
17+
</div>
18+
<div class="modal-footer">
19+
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-secondary" id="impersonate-modal-clear-button" formtarget="_self">
20+
<i class="fa fa-close"></i> {{ 'action.close'|trans(domain = 'EasyAdminBundle') }}
21+
</button>
22+
23+
<button type="button" data-bs-dismiss="modal" class="btn btn-sm btn-primary" id="impersonate-modal-apply-button" formtarget="_self">
24+
<i class="fa fa-check"></i> {{ 'user.impersonate_user'|trans(domain = 'EasyAdminBundle') }}
25+
</button>
26+
</div>
27+
</div>
28+
</div>
29+
</div>

templates/layout.html.twig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@
103103
{% elseif not item.isMenuSection %}
104104
<a href="{{ item.linkUrl }}" class="dropdown-item user-action {{ item.cssClass }}"
105105
target="{{ item.linkTarget }}" rel="{{ item.linkRel }}"
106+
{% if item.type == "access_impersonation" %}
107+
data-bs-toggle="modal" data-bs-target="#modal-impersonate" id="modal-impersonate-link"
108+
{% endif %}
106109
referrerpolicy="origin-when-cross-origin">
107110
{% if item.icon is not empty %}<twig:ea:Icon name="{{ item.icon }}" />{% endif %}
108111
{{ item.label|trans }}
@@ -360,6 +363,9 @@
360363

361364
<section id="main" class="content-body">
362365
{% block main %}{% endblock %}
366+
{% if impersonator_permission == 'IS_IMPERSONATOR' %}
367+
{{ include('@EasyAdmin/includes/_impersonate_modal.html.twig') }}
368+
{% endif %}
363369
</section>
364370

365371
{% block content_footer_wrapper %}

translations/EasyAdminBundle.en.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
'anonymous' => 'Anonymous User',
110110
'sign_out' => 'Sign out',
111111
'exit_impersonation' => 'Exit impersonation',
112+
'impersonate_user' => 'Impersonate user',
112113
],
113114

114115
'settings' => [
@@ -141,4 +142,8 @@
141142
'no-more-results' => 'No more results',
142143
'loading-more-results' => 'Loading more results…',
143144
],
145+
146+
'impersonate' => [
147+
'username' => 'Username to impersonate',
148+
],
144149
];

translations/EasyAdminBundle.es.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@
108108
'unnamed' => 'Usuario sin nombre',
109109
'anonymous' => 'Usuario anónimo',
110110
'sign_out' => 'Cerrar sesión',
111-
'exit_impersonation' => 'Terminar impersonación',
111+
'exit_impersonation' => 'Terminar suplantación',
112+
'impersonate_user' => 'Suplantar usuario',
112113
],
113114

114115
'settings' => [
@@ -141,4 +142,8 @@
141142
'no-more-results' => 'No hay más resultados',
142143
'loading-more-results' => 'Cargando más resultados…',
143144
],
145+
146+
'impersonate' => [
147+
'username' => 'Nombre de usuario a suplantar',
148+
],
144149
];

0 commit comments

Comments
 (0)