]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #2327 from wallabag/user-management
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Sun, 2 Oct 2016 13:00:02 +0000 (15:00 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Oct 2016 13:00:02 +0000 (15:00 +0200)
Add users management UI

31 files changed:
app/config/routing.yml
app/config/security.yml
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/translations/validators.da.yml
src/Wallabag/CoreBundle/Resources/translations/validators.tr.yml
src/Wallabag/CoreBundle/Resources/views/base.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
src/Wallabag/UserBundle/Controller/ManageController.php [new file with mode: 0644]
src/Wallabag/UserBundle/Entity/User.php
src/Wallabag/UserBundle/Form/NewUserType.php [moved from src/Wallabag/CoreBundle/Form/Type/NewUserType.php with 77% similarity]
src/Wallabag/UserBundle/Form/UserType.php [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/views/manage.html.twig [new file with mode: 0644]
tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
tests/Wallabag/UserBundle/Controller/ManageControllerTest.php [new file with mode: 0644]

index 40cc7165bb4e410f175a330fa591e2f79ea70e59..2be74d7f08fcc46d960e193f3098e2405bcf58e0 100644 (file)
@@ -7,6 +7,11 @@ wallabag_import:
     type: annotation
     prefix: /import
 
+wallabag_user:
+    resource: "@WallabagUserBundle/Controller/"
+    type: annotation
+    prefix: /users
+
 wallabag_api:
     resource: "@WallabagApiBundle/Resources/config/routing.yml"
     prefix: /
index 1f30e58b845abceb50011a28ed32b0f7ab57daca..efb00a5348135d7ad16f94ec3760f0a7771564d7 100644 (file)
@@ -63,4 +63,5 @@ security:
         - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
         - { path: ^/annotations, roles: ROLE_USER }
+        - { path: ^/users, roles: ROLE_SUPER_ADMIN }
         - { path: ^/, roles: ROLE_USER }
index f1e212d989e849da34a45afe66a7803f709a90a0..91cdcae506fe75f2176f84fbe3c31911c29d3a66 100644 (file)
@@ -2,8 +2,6 @@
 
 namespace Wallabag\CoreBundle\Controller;
 
-use FOS\UserBundle\Event\UserEvent;
-use FOS\UserBundle\FOSUserEvents;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\HttpFoundation\JsonResponse;
@@ -13,7 +11,6 @@ use Wallabag\CoreBundle\Entity\Config;
 use Wallabag\CoreBundle\Entity\TaggingRule;
 use Wallabag\CoreBundle\Form\Type\ConfigType;
 use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
-use Wallabag\CoreBundle\Form\Type\NewUserType;
 use Wallabag\CoreBundle\Form\Type\RssType;
 use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
 use Wallabag\CoreBundle\Form\Type\UserInformationType;
@@ -138,38 +135,12 @@ class ConfigController extends Controller
             return $this->redirect($this->generateUrl('config').'#set5');
         }
 
-        // handle adding new user
-        $newUser = $userManager->createUser();
-        // enable created user by default
-        $newUser->setEnabled(true);
-        $newUserForm = $this->createForm(NewUserType::class, $newUser, [
-            'validation_groups' => ['Profile'],
-            'action' => $this->generateUrl('config').'#set6',
-        ]);
-        $newUserForm->handleRequest($request);
-
-        if ($newUserForm->isValid() && $this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN')) {
-            $userManager->updateUser($newUser);
-
-            // dispatch a created event so the associated config will be created
-            $event = new UserEvent($newUser, $request);
-            $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
-
-            $this->get('session')->getFlashBag()->add(
-                'notice',
-                $this->get('translator')->trans('flashes.config.notice.user_added', ['%username%' => $newUser->getUsername()])
-            );
-
-            return $this->redirect($this->generateUrl('config').'#set6');
-        }
-
         return $this->render('WallabagCoreBundle:Config:index.html.twig', [
             'form' => [
                 'config' => $configForm->createView(),
                 'rss' => $rssForm->createView(),
                 'pwd' => $pwdForm->createView(),
                 'user' => $userForm->createView(),
-                'new_user' => $newUserForm->createView(),
                 'new_tagging_rule' => $newTaggingRule->createView(),
             ],
             'rss' => [
index da7e2652aadafd335f1a83d43e913b410544f0a1..40644ff5f0062da2fce0d50b28cfe718ea4a8974 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Søg'
         # save_link: 'Save a link'
         back_to_unread: 'Tilbage til de ulæste artikler'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Tilføj ny artikel'
         search: 'Søg'
@@ -129,12 +130,6 @@ config:
         #         or: 'One rule OR another'
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-    form_new_user:
-        username_label: 'Brugernavn'
-        password_label: 'Adgangskode'
-        repeat_new_password_label: 'Gentag adgangskode'
-        plain_password_label: '????'
-        email_label: 'Emailadresse'
 
 entry:
     page_titles:
@@ -396,12 +391,14 @@ developer:
     #     page_title: 'Developer > New client'
     #     page_description: 'You are about to create a new client. Please fill the field below for the redirect URI of your application.'
     #     form:
+    #         name_label: 'Name of the client'
     #         redirect_uris_label: 'Redirect URIs'
     #         save_label: 'Create a new client'
     #     action_back: 'Back'
     # client_parameter:
     #     page_title: 'Developer > Client parameters'
     #     page_description: 'Here are your client parameters.'
+    #     field_name: 'Client name'
     #     field_id: 'Client ID'
     #     field_secret: 'Client secret'
     #     back: 'Back'
@@ -419,6 +416,33 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'Back'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Brugernavn'
+        # name_label: 'Name'
+        password_label: 'Adgangskode'
+        repeat_new_password_label: 'Gentag adgangskode'
+        plain_password_label: '????'
+        email_label: 'Emailadresse'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index eb82f13f3535bb6b8244fd66ef0b36d5b0852cb6..6f79074407daa77b0d66038b71d02823197f3c91 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Suche'
         save_link: 'Link speichern'
         back_to_unread: 'Zurück zu ungelesenen Artikeln'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Neuen Artikel hinzufügen'
         search: 'Suche'
@@ -129,12 +130,6 @@ config:
                 or: 'Eine Regel ODER die andere'
                 and: 'Eine Regel UND eine andere'
                 matches: 'Tests, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>'
-    form_new_user:
-        username_label: 'Benutzername'
-        password_label: 'Kennwort'
-        repeat_new_password_label: 'Neues Kennwort wiederholen'
-        plain_password_label: '????'
-        email_label: 'E-Mail-Adresse'
 
 entry:
     page_titles:
@@ -396,12 +391,14 @@ developer:
         page_title: 'Entwickler > Neuer Client'
         page_description: 'Du bist dabei, einen neuen Client zu erstellen. Fülle das nachfolgende Feld für die Weiterleitungs-URIs deiner Anwendung aus.'
         form:
+            # name_label: 'Name of the client'
             redirect_uris_label: 'Weiterleitungs-URIs'
             save_label: 'Neuen Client erstellen'
         action_back: 'Zurück'
     client_parameter:
         page_title: 'Entwickler > Client-Parameter'
         page_description: 'Dies sind deine Client-Parameter.'
+        # field_name: 'Client name'
         field_id: 'Client-ID'
         field_secret: 'Client-Secret'
         back: 'Zurück'
@@ -419,6 +416,33 @@ developer:
             paragraph_8: 'Wenn du alle API-Endpunkte sehen willst, werfe einen Blick auf die <a href="%link%">API-Dokumentation</a>.'
         back: 'Zurück'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Benutzername'
+        # name_label: 'Name'
+        password_label: 'Kennwort'
+        repeat_new_password_label: 'Neues Kennwort wiederholen'
+        plain_password_label: '????'
+        email_label: 'E-Mail-Adresse'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index 01d8053be5c7e9f367dece9cd97c006f9d8531b8..91abe16238735b535d3e9eae4e7a4cc6ca2640c0 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Search'
         save_link: 'Save a link'
         back_to_unread: 'Back to unread articles'
+        users_management: 'Users management'
     top:
         add_new_entry: 'Add a new entry'
         search: 'Search'
@@ -129,12 +130,6 @@ config:
                 or: 'One rule OR another'
                 and: 'One rule AND another'
                 matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-    form_new_user:
-        username_label: 'Username'
-        password_label: 'Password'
-        repeat_new_password_label: 'Repeat new password'
-        plain_password_label: '????'
-        email_label: 'Email'
 
 entry:
     page_titles:
@@ -421,6 +416,33 @@ developer:
             paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
         back: 'Back'
 
+user:
+    page_title: Users management
+    new_user: Create a new user
+    edit_user: Edit an existing user
+    description: "Here you can manage all users (create, edit and delete)"
+    list:
+        actions: Actions
+        edit_action: Edit
+        yes: Yes
+        no: No
+        create_new_one: Create a new user
+    form:
+        username_label: 'Username'
+        name_label: 'Name'
+        password_label: 'Password'
+        repeat_new_password_label: 'Repeat new password'
+        plain_password_label: '????'
+        email_label: 'Email'
+        enabled_label: 'Enabled'
+        locked_label: 'Locked'
+        last_login_label: 'Last login'
+        twofactor_label: Two factor authentication
+        save: Save
+        delete: Delete
+        delete_confirm: Are you sure?
+        back_to_list: Back to list
+
 flashes:
     config:
         notice:
@@ -431,7 +453,6 @@ flashes:
             rss_updated: 'RSS information updated'
             tagging_rules_updated: 'Tagging rules updated'
             tagging_rules_deleted: 'Tagging rule deleted'
-            user_added: 'User "%username%" added'
             rss_token_updated: 'RSS token updated'
     entry:
         notice:
@@ -462,3 +483,8 @@ flashes:
         notice:
             client_created: 'New client %name% created.'
             client_deleted: 'Client %name% deleted'
+    user:
+        notice:
+            added: 'User "%username%" added'
+            updated: 'User "%username%" updated'
+            deleted: 'User "%username%" deleted'
index 5364e99a616a23e2750579c645e80085d7f1b106..25d2f3a25c6d1aeb8dc0efcda59d65dc072bc9f9 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Buscar'
         save_link: 'Archivar un enlace'
         back_to_unread: 'Volver a los artículos sin leer'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Añadir un nuevo artículo'
         search: 'Buscar'
@@ -129,12 +130,6 @@ config:
                 or: 'Una regla U otra'
                 and: 'Una regla Y la otra'
                 matches: 'Pruebe si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>título coincide "football"</code>'
-    form_new_user:
-        username_label: 'Nombre de usuario'
-        password_label: 'Contraseña'
-        repeat_new_password_label: 'Confirmar la nueva contraseña'
-        plain_password_label: '????'
-        email_label: 'Email'
 
 entry:
     page_titles:
@@ -396,12 +391,14 @@ developer:
         page_title: 'Promotor > Nuevo cliente'
         page_description: 'Va a crear un nuevo cliente. Por favor, llene el campo abajo para URI redirigido de su aplicación.'
         form:
+            # name_label: 'Name of the client'
             redirect_uris_label: 'los URI redirigidos'
             save_label: 'Crear un nuevo cliente'
         action_back: 'Atrás'
     client_parameter:
         page_title: 'Promotor > Parámetros del cliente'
         page_description: 'Aquí hay sus parámetros del cliente.'
+        # field_name: 'Client name'
         field_id: 'Identificación del cliente'
         field_secret: 'Cliente secreto'
         back: 'Atrás'
@@ -419,6 +416,33 @@ developer:
             paragraph_8: 'Si quiere ver todos los fines de API, se puede ver <a href="%link%">a nuestra documentación API</a>.'
         back: 'Atrás'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Nombre de usuario'
+        # name_label: 'Name'
+        password_label: 'Contraseña'
+        repeat_new_password_label: 'Confirmar la nueva contraseña'
+        plain_password_label: '????'
+        email_label: 'Email'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index 6f42b173edbc138002060ed940f88c220f35acaf..b02ffea02fe1431397eeee328b1a93fbcf336ab2 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'جستجو'
         save_link: 'ذخیرهٔ یک پیوند'
         back_to_unread: 'بازگشت به خوانده‌نشده‌ها'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'افزودن مقالهٔ تازه'
         search: 'جستجو'
@@ -129,12 +130,6 @@ config:
         #         or: 'One rule OR another'
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-    form_new_user:
-        username_label: 'نام کاربری'
-        password_label: 'رمز'
-        repeat_new_password_label: 'رمز تازه را دوباره بنویسید'
-        plain_password_label: '????'
-        email_label: 'نشانی ایمیل'
 
 entry:
     page_titles:
@@ -395,12 +390,14 @@ developer:
     #     page_title: 'Developer > New client'
     #     page_description: 'You are about to create a new client. Please fill the field below for the redirect URI of your application.'
     #     form:
+    #         name_label: 'Name of the client'
     #         redirect_uris_label: 'Redirect URIs'
     #         save_label: 'Create a new client'
     #     action_back: 'بازگشت'
     # client_parameter:
     #     page_title: 'Developer > Client parameters'
     #     page_description: 'Here are your client parameters.'
+    #     field_name: 'Client name'
     #     field_id: 'Client ID'
     #     field_secret: 'Client secret'
     #     back: 'بازگشت'
@@ -418,6 +415,33 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'بازگشت'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'نام کاربری'
+        # name_label: 'Name'
+        password_label: 'رمز'
+        repeat_new_password_label: 'رمز تازه را دوباره بنویسید'
+        plain_password_label: '????'
+        email_label: 'نشانی ایمیل'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index 6984be834b51998bdb6b641befb134ba16e943db..598205b028129e26c2fc94551c5c49fa556dc088 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Recherche'
         save_link: 'Sauvegarder un nouvel article'
         back_to_unread: 'Retour aux articles non lus'
+        users_management: 'Gestion des utilisateurs'
     top:
         add_new_entry: 'Sauvegarder un nouvel article'
         search: 'Rechercher'
@@ -129,12 +130,6 @@ config:
                 or: "Une règle OU l'autre"
                 and: "Une règle ET l'autre"
                 matches: 'Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches "football"</code>'
-    form_new_user:
-        username_label: "Nom d'utilisateur"
-        password_label: 'Mot de passe'
-        repeat_new_password_label: 'Confirmez votre nouveau mot de passe'
-        plain_password_label: 'Mot de passe en clair'
-        email_label: 'Adresse e-mail'
 
 entry:
     page_titles:
@@ -421,6 +416,33 @@ developer:
             paragraph_8: "Si vous voulez toutes les méthodes de l'API, jetez un oeil <a href=\"%link%\">à la documentation de l'API</a>."
         back: 'Retour'
 
+user:
+    page_title: Gestion des utilisateurs
+    new_user: Créer un nouvel utilisateur
+    edit_user: Éditer un utilisateur existant
+    description: Ici vous pouvez gérer vos utilisateurs (création, mise à jour et suppression)
+    list:
+        actions: Actions
+        edit_action: Éditer
+        yes: Oui
+        no: Non
+        create_new_one: Créer un nouvel utilisateur
+    form:
+        username_label: "Nom d'utilisateur"
+        name_label: 'Nom'
+        password_label: 'Mot de passe'
+        repeat_new_password_label: 'Confirmez votre nouveau mot de passe'
+        plain_password_label: 'Mot de passe en clair'
+        email_label: 'Adresse e-mail'
+        enabled_label: 'Activé'
+        locked_label: 'Bloqué'
+        last_login_label: 'Dernière connexion'
+        twofactor_label: Double authentification
+        save: Sauvegarder
+        delete: Supprimer
+        delete_confirm: Êtes-vous sûr?
+        back_to_list: Revenir à la liste
+
 flashes:
     config:
         notice:
index 30b3287ebf3113ae0420e1a3e1799f1f3b0d7bed..c58c929f78f31cfddac4aeac1cd65722866ff1ca 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Cerca'
         save_link: 'Salva collegamento'
         back_to_unread: 'Torna ai contenuti non letti'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Aggiungi un nuovo contenuto'
         search: 'Cerca'
@@ -129,12 +130,6 @@ config:
                 or: "Una regola O un'altra"
                 and: "Una regola E un'altra"
                 matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
-    form_new_user:
-        username_label: 'Username'
-        password_label: 'Password'
-        repeat_new_password_label: 'Ripeti password'
-        plain_password_label: '????'
-        email_label: 'E-mail'
 
 entry:
     page_titles:
@@ -162,6 +157,7 @@ entry:
         status_label: 'Stato'
         archived_label: 'Archiviati'
         starred_label: 'Preferiti'
+        # unread_label: 'Unread'
         preview_picture_label: "Ha un'immagine di anteprima"
         preview_picture_help: 'Immagine di anteprima'
         language_label: 'Lingua'
@@ -395,12 +391,14 @@ developer:
         page_title: 'Sviluppatori > Nuovo client'
         page_description: 'Stai per creare un nuovo client. Compila i campi sottostanti per il redirect URI della tua applicazione.'
         form:
+            # name_label: 'Name of the client'
             redirect_uris_label: 'Redirect URI'
             save_label: 'Crea un nuovo client'
         action_back: 'Indietro'
     client_parameter:
         page_title: 'Sviluppatori > parametri Client'
         page_description: 'Questi sono i tuoi parametri del client.'
+        # field_name: 'Client name'
         field_id: 'Client ID'
         field_secret: 'Client secret'
         back: 'Indietro'
@@ -418,6 +416,33 @@ developer:
             paragraph_8: 'Se vuoi visualizzare tutti gli API endpoints, dai una occhiata alla <a href="%link%">documentazione delle API</a>.'
         back: 'Indietro'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Username'
+        # name_label: 'Name'
+        password_label: 'Password'
+        repeat_new_password_label: 'Ripeti password'
+        plain_password_label: '????'
+        email_label: 'E-mail'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index a077f1bf30756a50221f1293e5499126e51a71ac..8f06434dba9b3716f1e168cc2d0dc99aa6c54aaa 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Cercar'
         save_link: 'Enregistrar un novèl article'
         back_to_unread: 'Tornar als articles pas legits'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Enregistrar un novèl article'
         search: 'Cercar'
@@ -129,12 +130,6 @@ config:
                 or: "Una règla O l'autra"
                 and: "Una règla E l'autra"
                 matches: 'Teste se un <i>subjècte</i> correspond a una <i>recerca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>'
-    form_new_user:
-        username_label: "Nom d'utilizaire"
-        password_label: 'Senhal'
-        repeat_new_password_label: 'Confirmatz vòstre novèl senhal'
-        plain_password_label: 'Senhal en clar'
-        email_label: 'Adreça de corrièl'
 
 entry:
     page_titles:
@@ -421,6 +416,33 @@ developer:
             paragraph_8: "Se volètz totas las adreças d'accès de l'API, donatz un còp d’uèlh <a href=\"%link%\">a la documentacion de l'API</a>."
         back: 'Retorn'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: "Nom d'utilizaire"
+        # name_label: 'Name'
+        password_label: 'Senhal'
+        repeat_new_password_label: 'Confirmatz vòstre novèl senhal'
+        plain_password_label: 'Senhal en clar'
+        email_label: 'Adreça de corrièl'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index cad94dd5da85e08ea85f624fd124a7b695a1e6eb..54e669b31e778c8dfd8cb31c4f780ae0fa2c9f83 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Szukaj'
         save_link: 'Zapisz link'
         back_to_unread: 'Powrót do nieprzeczytanych artykułów'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Dodaj nowy wpis'
         search: 'Szukaj'
@@ -129,12 +130,6 @@ config:
                 or: 'Jedna reguła LUB inna'
                 and: 'Jedna reguła I inna'
                 matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
-    form_new_user:
-        username_label: 'Nazwa użytkownika'
-        password_label: 'Hasło'
-        repeat_new_password_label: 'Powtórz nowe hasło'
-        plain_password_label: 'Jawne hasło'
-        email_label: 'Adres email'
 
 entry:
     page_titles:
@@ -379,36 +374,38 @@ developer:
     full_documentation: 'Pokaż pełne API'
     list_methods: 'Lista metod API'
     clients:
-         title: 'Klienci'
-         create_new: 'Utwórz nowego klienta'
+        title: 'Klienci'
+        create_new: 'Utwórz nowego klienta'
     existing_clients:
-         title: 'Istniejący klienci'
-         field_id: 'ID klienta'
-         field_secret: 'Client secret'
-         field_uris: 'Przekieruj URIs'
-         field_grant_types: 'Przyznaj pozwolenie'
-         no_client: 'Nie ma jeszcze klienta.'
+        title: 'Istniejący klienci'
+        field_id: 'ID klienta'
+        field_secret: 'Client secret'
+        field_uris: 'Przekieruj URIs'
+        field_grant_types: 'Przyznaj pozwolenie'
+        no_client: 'Nie ma jeszcze klienta.'
     remove:
-         warn_message_1: 'Masz możliwość usunięcia tego klienta. Ta akcja jest NIEODWRACALNA !'
-         warn_message_2: "Jeżeli go usuniesz, aplikacje skonfigurowane z tym klientem nię będa w stanie autoryzować twojego wallabag."
-         action: 'Usuń tego klienta'
+        warn_message_1: 'Masz możliwość usunięcia tego klienta. Ta akcja jest NIEODWRACALNA !'
+        warn_message_2: "Jeżeli go usuniesz, aplikacje skonfigurowane z tym klientem nię będa w stanie autoryzować twojego wallabag."
+        action: 'Usuń tego klienta'
     client:
-         page_title: 'Deweloper > Nowy klient'
-         page_description: 'Tworzysz nowego klienta. Wypełnij poniższe pole w celu przekierowania URI twojej aplikacji.'
-         form:
-             redirect_uris_label: 'Przekieruj adresy URI'
-             save_label: 'Stwórz nowego klienta'
-         action_back: 'Cofnij'
+        page_title: 'Deweloper > Nowy klient'
+        page_description: 'Tworzysz nowego klienta. Wypełnij poniższe pole w celu przekierowania URI twojej aplikacji.'
+        form:
+            # name_label: 'Name of the client'
+            redirect_uris_label: 'Przekieruj adresy URI'
+            save_label: 'Stwórz nowego klienta'
+        action_back: 'Cofnij'
     client_parameter:
-         page_title: 'Deweloper > Parametry klienta'
-         page_description: 'Tutaj znajdują się parametry klienta.'
-         field_id: 'Client ID'
-         field_secret: 'Client secret'
-         back: 'Cofnij'
-         read_howto: 'Przeczytaj jak "Stworzyć moją pierwszą aplikację"'
+        page_title: 'Deweloper > Parametry klienta'
+        page_description: 'Tutaj znajdują się parametry klienta.'
+        # field_name: 'Client name'
+        field_id: 'Client ID'
+        field_secret: 'Client secret'
+        back: 'Cofnij'
+        read_howto: 'Przeczytaj jak "Stworzyć moją pierwszą aplikację"'
     howto:
-         page_title: 'Deweloper > Jak stworzyć moją pierwszą aplikację'
-         description:
+        page_title: 'Deweloper > Jak stworzyć moją pierwszą aplikację'
+        description:
             paragraph_1: 'Następujące komendy korzystają <a href="https://github.com/jkbrzt/httpie">Biblioteka HTTPie</a>. Upewnij się, czy zainstalowałeś ją w swoim systemie zanim z niej skorzystasz'
             paragraph_2: 'Potrzebujesz tokena w celu nawiązania komunikacji między swoją aplikacją a API wallabag.'
             paragraph_3: 'W celu stworzenia tokena musisz <a href="%link%">stwórz nowego klienta</a>.'
@@ -417,7 +414,34 @@ developer:
             paragraph_6: 'access_token jest użyteczny do wywołania API endpoint. Na przykład:'
             paragraph_7: 'To wywołanie zwróci wszystkie twoje wpisy.'
             paragraph_8: 'Jeżeli chcesz wyświetlić wszystkie punkty końcowe API, zobacz <a href="%link%">Dokumentacja naszego API</a>.'
-         back: 'Cofnij'
+        back: 'Cofnij'
+
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Nazwa użytkownika'
+        # name_label: 'Name'
+        password_label: 'Hasło'
+        repeat_new_password_label: 'Powtórz nowe hasło'
+        plain_password_label: 'Jawne hasło'
+        email_label: 'Adres email'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
 
 flashes:
     config:
index a271d6f3c584d4a9d515f8b162f55fd65c60837d..4e0e454c18e6175cb5b904441d6e4a773043ae81 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Căutare'
         # save_link: 'Save a link'
         back_to_unread: 'Înapoi la articolele necitite'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Introdu un nou articol'
         search: 'Căutare'
@@ -129,12 +130,6 @@ config:
         #         or: 'One rule OR another'
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-    form_new_user:
-        username_label: 'Nume de utilizator'
-        password_label: 'Parolă'
-        repeat_new_password_label: 'Repeat new password'
-        plain_password_label: '????'
-        email_label: 'E-mail'
 
 entry:
     page_titles:
@@ -396,12 +391,14 @@ developer:
     #     page_title: 'Developer > New client'
     #     page_description: 'You are about to create a new client. Please fill the field below for the redirect URI of your application.'
     #     form:
+    #         name_label: 'Name of the client'
     #         redirect_uris_label: 'Redirect URIs'
     #         save_label: 'Create a new client'
     #     action_back: 'Back'
     # client_parameter:
     #     page_title: 'Developer > Client parameters'
     #     page_description: 'Here are your client parameters.'
+    #     field_name: 'Client name'
     #     field_id: 'Client ID'
     #     field_secret: 'Client secret'
     #     back: 'Back'
@@ -419,6 +416,33 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'Back'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Nume de utilizator'
+        # name_label: 'Name'
+        password_label: 'Parolă'
+        repeat_new_password_label: 'Repeat new password'
+        plain_password_label: '????'
+        email_label: 'E-mail'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index f2307e65815dc4bb4eb1ff13d0359e72a9e432f9..02b3aae62fc25e7aecc3b0c67954c64c1540b994 100644 (file)
@@ -31,6 +31,7 @@ menu:
         search: 'Ara'
         # save_link: 'Save a link'
         back_to_unread: 'Okunmayan makalelere geri dön'
+        # users_management: 'Users management'
     top:
         add_new_entry: 'Yeni bir makale ekle'
         search: 'Ara'
@@ -128,12 +129,6 @@ config:
                 or: 'Bir kural veya birbaşkası'
                 and: 'Bir kural ve diğeri'
                 # matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-    form_new_user:
-        username_label: 'Kullanıcı adı'
-        password_label: 'Şifre'
-        repeat_new_password_label: 'Yeni şifrenin tekrarı'
-        plain_password_label: '????'
-        email_label: 'E-posta'
 
 entry:
     page_titles:
@@ -395,12 +390,14 @@ developer:
     #     page_title: 'Developer > New client'
     #     page_description: 'You are about to create a new client. Please fill the field below for the redirect URI of your application.'
     #     form:
+    #        name_label: 'Name of the client'
     #         redirect_uris_label: 'Redirect URIs'
     #         save_label: 'Create a new client'
     #     action_back: 'Back'
     # client_parameter:
     #     page_title: 'Developer > Client parameters'
     #     page_description: 'Here are your client parameters.'
+    #     field_name: 'Client name'
     #     field_id: 'Client ID'
     #     field_secret: 'Client secret'
     #     back: 'Back'
@@ -418,6 +415,33 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'Back'
 
+user:
+    # page_title: Users management
+    # new_user: Create a new user
+    # edit_user: Edit an existing user
+    # description: "Here you can manage all users (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new user
+    form:
+        username_label: 'Kullanıcı adı'
+        # name_label: 'Name'
+        password_label: 'Şifre'
+        repeat_new_password_label: 'Yeni şifrenin tekrarı'
+        plain_password_label: '????'
+        email_label: 'E-posta'
+        # enabled_label: 'Enabled'
+        # locked_label: 'Locked'
+        # last_login_label: 'Last login'
+        # twofactor_label: Two factor authentication
+        # save: Save
+        # delete: Delete
+        # delete_confirm: Are you sure?
+        # back_to_list: Back to list
+
 flashes:
     config:
         notice:
index dfe2c64d40907be25568d4c510115868986fb33c..313339ed0c0b861699cda30f605562706d30a8ef 100644 (file)
@@ -1,6 +1,6 @@
 validator:
     password_must_match: 'De indtastede adgangskoder skal være ens'
     password_too_short: 'Adgangskoden skal være mindst 8 tegn'
-#     password_wrong_value: 'Wrong value for your current password'
-#     item_per_page_too_high: 'This will certainly kill the app'
-#     rss_limit_too_hight: 'This will certainly kill the app'
+    # password_wrong_value: 'Wrong value for your current password'
+    # item_per_page_too_high: 'This will certainly kill the app'
+    # rss_limit_too_hight: 'This will certainly kill the app'
index 80ab470afc3483265c0c872efbe108d85c922e7e..1b358965de256f1b07e8890b169caba1084f2bd8 100644 (file)
@@ -1,6 +1,6 @@
 validator:
-#     password_must_match: 'The password fields must match.'
-#     password_too_short: 'Password should by at least 8 chars long'
-#     password_wrong_value: 'Wrong value for your current password'
-#     item_per_page_too_high: 'This will certainly kill the app'
-#     rss_limit_too_hight: 'This will certainly kill the app'
+    # password_must_match: 'The password fields must match.'
+    # password_too_short: 'Password should by at least 8 chars long'
+    # password_wrong_value: 'Wrong value for your current password'
+    # item_per_page_too_high: 'This will certainly kill the app'
+    # rss_limit_too_hight: 'This will certainly kill the app'
index 0f88901a5c0102cfaf10eba2b000711452d97f12..a1a9a1368949178e9d649fe92f7a3e3348bd58c7 100644 (file)
@@ -43,7 +43,7 @@
             {% block scripts %}
             {% endblock %}
 
-            <title>wallabag - {% block title %}{% endblock %}</title>
+            <title>{% block title %}{% endblock %} – wallabag</title>
         {% endblock %}
     </head>
 
index dd4f7b009e941cc8940a6ddbee7c1c51320ca8c5..ff7ef73a81509ac971aac10e47061aecc611b9b6 100644 (file)
             </table>
         </div>
     </div>
-
-    {% if is_granted('ROLE_SUPER_ADMIN') %}
-    <h2>{{ 'config.tab_menu.new_user'|trans }}</h2>
-
-    {{ form_start(form.new_user) }}
-        {{ form_errors(form.new_user) }}
-
-        <fieldset class="w500p inline">
-            <div class="row">
-                {{ form_label(form.new_user.username) }}
-                {{ form_errors(form.new_user.username) }}
-                {{ form_widget(form.new_user.username) }}
-            </div>
-        </fieldset>
-
-        <fieldset class="w500p inline">
-            <div class="row">
-                {{ form_label(form.new_user.plainPassword.first) }}
-                {{ form_errors(form.new_user.plainPassword.first) }}
-                {{ form_widget(form.new_user.plainPassword.first) }}
-            </div>
-        </fieldset>
-
-        <fieldset class="w500p inline">
-            <div class="row">
-                {{ form_label(form.new_user.plainPassword.second) }}
-                {{ form_errors(form.new_user.plainPassword.second) }}
-                {{ form_widget(form.new_user.plainPassword.second) }}
-            </div>
-        </fieldset>
-
-        <fieldset class="w500p inline">
-            <div class="row">
-                {{ form_label(form.new_user.email) }}
-                {{ form_errors(form.new_user.email) }}
-                {{ form_widget(form.new_user.email) }}
-            </div>
-        </fieldset>
-
-        {{ form_rest(form.new_user) }}
-        {% endif %}
-    </form>
 {% endblock %}
index 4fd4d317afb183558f37674bf21d39ef29b5957f..30fd0d85a3cd302d6fe11233a0151d940aaef8a7 100644 (file)
@@ -42,6 +42,7 @@
         </li>-->
         <li><a href="{{ path('config') }}">{{ 'menu.left.config'|trans }}</a></li>
         {% if is_granted('ROLE_SUPER_ADMIN') %}
+            <li><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li>
             <li><a href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a></li>
         {% endif %}
         <li><a href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a></li>
index 650a3ae2a03ce061ea148e318724799934ff4e38..270c077f332de577644e574849c7ff7acd7e748e 100644 (file)
@@ -16,9 +16,6 @@
                             <li class="tab col s3"><a href="#set3">{{ 'config.tab_menu.user_info'|trans }}</a></li>
                             <li class="tab col s3"><a href="#set4">{{ 'config.tab_menu.password'|trans }}</a></li>
                             <li class="tab col s3"><a href="#set5">{{ 'config.tab_menu.rules'|trans }}</a></li>
-                            {% if is_granted('ROLE_SUPER_ADMIN') %}
-                            <li class="tab col s3"><a href="#set6">{{ 'config.tab_menu.new_user'|trans }}</a></li>
-                            {% endif %}
                         </ul>
                     </div>
 
                             <div class="row">
                                 <div class="input-field col s12">
                                     {{ 'config.form_user.two_factor_description'|trans }}
-                                </div>
-                            </div>
 
-                            <div class="row">
-                                <div class="input-field col s12">
+                                    <br />
+
                                     {{ form_widget(form.user.twoFactorAuthentication) }}
                                     {{ form_label(form.user.twoFactorAuthentication) }}
                                     {{ form_errors(form.user.twoFactorAuthentication) }}
                             </div>
                         </div>
                     </div>
-
-                    {% if is_granted('ROLE_SUPER_ADMIN') %}
-                    <div id="set6" class="col s12">
-                        {{ form_start(form.new_user) }}
-                            {{ form_errors(form.new_user) }}
-
-                            <div class="row">
-                                <div class="input-field col s12">
-                                    {{ form_label(form.new_user.username) }}
-                                    {{ form_errors(form.new_user.username) }}
-                                    {{ form_widget(form.new_user.username) }}
-                                </div>
-                            </div>
-
-                            <div class="row">
-                                <div class="input-field col s12">
-                                    {{ form_label(form.new_user.plainPassword.first) }}
-                                    {{ form_errors(form.new_user.plainPassword.first) }}
-                                    {{ form_widget(form.new_user.plainPassword.first) }}
-                                </div>
-                            </div>
-
-                            <div class="row">
-                                <div class="input-field col s12">
-                                    {{ form_label(form.new_user.plainPassword.second) }}
-                                    {{ form_errors(form.new_user.plainPassword.second) }}
-                                    {{ form_widget(form.new_user.plainPassword.second) }}
-                                </div>
-                            </div>
-
-                            <div class="row">
-                                <div class="input-field col s12">
-                                    {{ form_label(form.new_user.email) }}
-                                    {{ form_errors(form.new_user.email) }}
-                                    {{ form_widget(form.new_user.email) }}
-                                </div>
-                            </div>
-
-                            {{ form_widget(form.new_user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
-                            {{ form_rest(form.new_user) }}
-                        </form>
-                    </div>
-                    {% endif %}
                 </div>
 
             </div>
index b2d77c2e2d81cf1f73c6cc1ebd583b9908292015..c7d6d70d3f03df06b5d945df5a9e0859dc62d442 100644 (file)
@@ -45,7 +45,7 @@
             <li class="bold {% if currentRoute == 'archive' %}active{% endif %}">
                 <a class="waves-effect" href="{{ path('archive') }}">{{ 'menu.left.archive'|trans }} <span class="numberItems grey-text">{{ count_entries('archive') }}</span></a>
             </li>
-            <li class="bold border-bottom {% if currentRoute == 'all' %}active{% endif %}">
+            <li class="bold {% if currentRoute == 'all' %}active{% endif %}">
                 <a class="waves-effect" href="{{ path('all') }}">{{ 'menu.left.all_articles'|trans }} <span class="numberItems grey-text">{{ count_entries('all') }}</span></a>
             </li>
             <li class="bold border-bottom {% if currentRoute == 'tags' %}active{% endif %}">
                 <a class="waves-effect" href="{{ path('config') }}">{{ 'menu.left.config'|trans }}</a>
             </li>
             {% if is_granted('ROLE_SUPER_ADMIN') %}
+                <li class="bold {% if currentRoute starts with 'user_' %}active{% endif %}">
+                    <a class="waves-effect" href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a>
+                </li>
+
                 <li class="bold border-bottom {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
                     <a class="waves-effect" href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a>
                 </li>
diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php
new file mode 100644 (file)
index 0000000..92ee2b4
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+
+namespace Wallabag\UserBundle\Controller;
+
+use FOS\UserBundle\Event\UserEvent;
+use FOS\UserBundle\FOSUserEvents;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Wallabag\UserBundle\Entity\User;
+use Wallabag\CoreBundle\Entity\Config;
+
+/**
+ * User controller.
+ */
+class ManageController extends Controller
+{
+    /**
+     * Lists all User entities.
+     *
+     * @Route("/", name="user_index")
+     * @Method("GET")
+     */
+    public function indexAction()
+    {
+        $em = $this->getDoctrine()->getManager();
+
+        $users = $em->getRepository('WallabagUserBundle:User')->findAll();
+
+        return $this->render('WallabagUserBundle:Manage:index.html.twig', array(
+            'users' => $users,
+        ));
+    }
+
+    /**
+     * Creates a new User entity.
+     *
+     * @Route("/new", name="user_new")
+     * @Method({"GET", "POST"})
+     */
+    public function newAction(Request $request)
+    {
+        $userManager = $this->container->get('fos_user.user_manager');
+
+        $user = $userManager->createUser();
+        // enable created user by default
+        $user->setEnabled(true);
+
+        $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [
+            'validation_groups' => ['Profile'],
+        ]);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $userManager->updateUser($user);
+
+            // dispatch a created event so the associated config will be created
+            $event = new UserEvent($user, $request);
+            $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.user.notice.added', ['%username%' => $user->getUsername()])
+            );
+
+            return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
+        }
+
+        return $this->render('WallabagUserBundle:Manage:new.html.twig', array(
+            'user' => $user,
+            'form' => $form->createView(),
+        ));
+    }
+
+    /**
+     * Displays a form to edit an existing User entity.
+     *
+     * @Route("/{id}/edit", name="user_edit")
+     * @Method({"GET", "POST"})
+     */
+    public function editAction(Request $request, User $user)
+    {
+        $deleteForm = $this->createDeleteForm($user);
+        $editForm = $this->createForm('Wallabag\UserBundle\Form\UserType', $user);
+        $editForm->handleRequest($request);
+
+        if ($editForm->isSubmitted() && $editForm->isValid()) {
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($user);
+            $em->flush();
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.user.notice.updated', ['%username%' => $user->getUsername()])
+            );
+
+            return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
+        }
+
+        return $this->render('WallabagUserBundle:Manage:edit.html.twig', array(
+            'user' => $user,
+            'edit_form' => $editForm->createView(),
+            'delete_form' => $deleteForm->createView(),
+            'twofactor_auth' => $this->getParameter('twofactor_auth'),
+        ));
+    }
+
+    /**
+     * Deletes a User entity.
+     *
+     * @Route("/{id}", name="user_delete")
+     * @Method("DELETE")
+     */
+    public function deleteAction(Request $request, User $user)
+    {
+        $form = $this->createDeleteForm($user);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.user.notice.deleted', ['%username%' => $user->getUsername()])
+            );
+
+            $em = $this->getDoctrine()->getManager();
+            $em->remove($user);
+            $em->flush();
+        }
+
+        return $this->redirectToRoute('user_index');
+    }
+
+    /**
+     * Creates a form to delete a User entity.
+     *
+     * @param User $user The User entity
+     *
+     * @return \Symfony\Component\Form\Form The form
+     */
+    private function createDeleteForm(User $user)
+    {
+        return $this->createFormBuilder()
+            ->setAction($this->generateUrl('user_delete', array('id' => $user->getId())))
+            ->setMethod('DELETE')
+            ->getForm()
+        ;
+    }
+}
index dfed8e47d4ab52000319f3536205004c7f87365b..d98ae76a533d5871f0befb514b13fbaab4ec9a98 100644 (file)
@@ -64,7 +64,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
     protected $entries;
 
     /**
-     * @ORM\OneToOne(targetEntity="Wallabag\CoreBundle\Entity\Config", mappedBy="user")
+     * @ORM\OneToOne(targetEntity="Wallabag\CoreBundle\Entity\Config", mappedBy="user", cascade={"remove"})
      */
     protected $config;
 
similarity index 77%
rename from src/Wallabag/CoreBundle/Form/Type/NewUserType.php
rename to src/Wallabag/UserBundle/Form/NewUserType.php
index 6a6f63d166428a990d978f65d7ff4a94f0c9171e..ad5a2405924ae8b6211f9ac4c6928e7f7d31e385 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wallabag\CoreBundle\Form\Type;
+namespace Wallabag\UserBundle\Form;
 
 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\Extension\Core\Type\EmailType;
@@ -19,13 +19,13 @@ class NewUserType extends AbstractType
         $builder
             ->add('username', TextType::class, [
                 'required' => true,
-                'label' => 'config.form_new_user.username_label',
+                'label' => 'user.form.username_label',
             ])
             ->add('plainPassword', RepeatedType::class, [
                 'type' => PasswordType::class,
                 'invalid_message' => 'validator.password_must_match',
-                'first_options' => ['label' => 'config.form_new_user.password_label'],
-                'second_options' => ['label' => 'config.form_new_user.repeat_new_password_label'],
+                'first_options' => ['label' => 'user.form.password_label'],
+                'second_options' => ['label' => 'user.form.repeat_new_password_label'],
                 'constraints' => [
                     new Constraints\Length([
                         'min' => 8,
@@ -33,13 +33,13 @@ class NewUserType extends AbstractType
                     ]),
                     new Constraints\NotBlank(),
                 ],
-                'label' => 'config.form_new_user.plain_password_label',
+                'label' => 'user.form.plain_password_label',
             ])
             ->add('email', EmailType::class, [
-                'label' => 'config.form_new_user.email_label',
+                'label' => 'user.form.email_label',
             ])
             ->add('save', SubmitType::class, [
-                'label' => 'config.form.save',
+                'label' => 'user.form.save',
             ])
         ;
     }
diff --git a/src/Wallabag/UserBundle/Form/UserType.php b/src/Wallabag/UserBundle/Form/UserType.php
new file mode 100644 (file)
index 0000000..cfa6779
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+namespace Wallabag\UserBundle\Form;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\Extension\Core\Type\EmailType;
+
+class UserType extends AbstractType
+{
+    /**
+     * @param FormBuilderInterface $builder
+     * @param array                $options
+     */
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('name', TextType::class, [
+                'required' => false,
+                'label' => 'user.form.name_label',
+            ])
+            ->add('username', TextType::class, [
+                'required' => true,
+                'label' => 'user.form.username_label',
+            ])
+            ->add('email', EmailType::class, [
+                'required' => true,
+                'label' => 'user.form.email_label',
+            ])
+            ->add('enabled', CheckboxType::class, [
+                'required' => false,
+                'label' => 'user.form.enabled_label',
+            ])
+            ->add('locked', CheckboxType::class, [
+                'required' => false,
+                'label' => 'user.form.locked_label',
+            ])
+            ->add('twoFactorAuthentication', CheckboxType::class, [
+                'required' => false,
+                'label' => 'user.form.twofactor_label',
+            ])
+            ->add('save', SubmitType::class, [
+                'label' => 'user.form.save',
+            ])
+        ;
+    }
+
+    /**
+     * @param OptionsResolver $resolver
+     */
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults(array(
+            'data_class' => 'Wallabag\UserBundle\Entity\User',
+        ));
+    }
+}
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig
new file mode 100644 (file)
index 0000000..d5cf99c
--- /dev/null
@@ -0,0 +1,86 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'user.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'user.edit_user'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(edit_form) }}
+                                {{ form_errors(edit_form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.name) }}
+                                        {{ form_errors(edit_form.name) }}
+                                        {{ form_widget(edit_form.name) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.username) }}
+                                        {{ form_errors(edit_form.username) }}
+                                        {{ form_widget(edit_form.username) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.email) }}
+                                        {{ form_errors(edit_form.email) }}
+                                        {{ form_widget(edit_form.email) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_widget(edit_form.enabled) }}
+                                        {{ form_label(edit_form.enabled) }}
+                                        {{ form_errors(edit_form.enabled) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_widget(edit_form.locked) }}
+                                        {{ form_label(edit_form.locked) }}
+                                        {{ form_errors(edit_form.locked) }}
+                                    </div>
+                                </div>
+
+                                {% if twofactor_auth %}
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_widget(edit_form.twoFactorAuthentication) }}
+                                        {{ form_label(edit_form.twoFactorAuthentication) }}
+                                        {{ form_errors(edit_form.twoFactorAuthentication) }}
+                                    </div>
+                                </div>
+                                {% endif %}
+
+                                <br/>
+
+                                {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_rest(edit_form) }}
+                            </form>
+                            <p>
+                                {{ form_start(delete_form) }}
+                                    <button {% if app.user.id == user.id %}disabled="disabled"{% endif %} onclick="return confirm('{{ 'user.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'user.form.delete'|trans }}</button>
+                                {{ form_end(delete_form) }}
+                            </p>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('user_index') }}">{{ 'user.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig
new file mode 100644 (file)
index 0000000..996bdb1
--- /dev/null
@@ -0,0 +1,48 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'user.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <p class="help">{{ 'user.description'|trans|raw }}</p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'user.form.username_label'|trans }}</th>
+                                    <th>{{ 'user.form.email_label'|trans }}</th>
+                                    <th>{{ 'user.form.last_login_label'|trans }}</th>
+                                    <th>{{ 'user.form.locked_label'|trans }}</th>
+                                    <th>{{ 'user.list.actions'|trans }}</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                            {% for user in users %}
+                                <tr>
+                                    <td>{{ user.username }}</td>
+                                    <td>{{ user.email }}</td>
+                                    <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td>
+                                    <td>{% if user.locked %}{{ 'user.list.yes'|trans }}{% else %}{{ 'user.list.no'|trans }}{% endif %}</td>
+                                    <td>
+                                        <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a>
+                                    </td>
+                                </tr>
+                            {% endfor %}
+                            </tbody>
+                        </table>
+                        <br />
+                        <p>
+                            <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a>
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig
new file mode 100644 (file)
index 0000000..8c894c0
--- /dev/null
@@ -0,0 +1,61 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'user.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'user.new_user'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(form) }}
+                                {{ form_errors(form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.username) }}
+                                        {{ form_errors(form.username) }}
+                                        {{ form_widget(form.username) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.plainPassword.first) }}
+                                        {{ form_errors(form.plainPassword.first) }}
+                                        {{ form_widget(form.plainPassword.first) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.plainPassword.second) }}
+                                        {{ form_errors(form.plainPassword.second) }}
+                                        {{ form_widget(form.plainPassword.second) }}
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.email) }}
+                                        {{ form_errors(form.email) }}
+                                        {{ form_widget(form.email) }}
+                                    </div>
+                                </div>
+
+                                {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_rest(form) }}
+                            </form>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('user_index') }}">{{ 'user.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/UserBundle/Resources/views/manage.html.twig b/src/Wallabag/UserBundle/Resources/views/manage.html.twig
new file mode 100644 (file)
index 0000000..c614c55
--- /dev/null
@@ -0,0 +1,43 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'user.manage.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <p class="help">{{ 'user.manage.description'|trans|raw }}</p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'user.manage.field.username'|trans }}</th>
+                                    <th>{{ 'user.manage.field.email'|trans }}</th>
+                                    <th>{{ 'user.manage.field.last_login'|trans }}</th>
+                                    <th>{{ 'user.manage.field.locked'|trans }}</th>
+                                    <th>{{ 'user.manage.action'|trans }}</th>
+                                </tr>
+                            </thead>
+
+                            <tbody>
+                                {% for user in users %}
+                                    <tr>
+                                        <td>{{ user.username }}</td>
+                                        <td>{{ user.email }}</td>
+                                        <td>{{ user.lastLogin|date('d/m/Y H:i:s') }}</td>
+                                        <td>{{ user.locked ? 'yes' : 'no' }}</td>
+                                        <td>edit - delete</td>
+                                    </tr>
+                                {% endfor %}
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
index bb3ea9e2cfea3a00a88dab2ed18ba5fb6e26343f..1954c654a53fba9f7882d62ad524907fcd6fa069 100644 (file)
@@ -28,7 +28,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $this->assertCount(1, $crawler->filter('button[id=config_save]'));
         $this->assertCount(1, $crawler->filter('button[id=change_passwd_save]'));
         $this->assertCount(1, $crawler->filter('button[id=update_user_save]'));
-        $this->assertCount(1, $crawler->filter('button[id=new_user_save]'));
         $this->assertCount(1, $crawler->filter('button[id=rss_config_save]'));
     }
 
@@ -283,119 +282,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
     }
 
-    public function dataForNewUserFailed()
-    {
-        return [
-            [
-                [
-                    'new_user[username]' => '',
-                    'new_user[plainPassword][first]' => '',
-                    'new_user[plainPassword][second]' => '',
-                    'new_user[email]' => '',
-                ],
-                'fos_user.username.blank',
-            ],
-            [
-                [
-                    'new_user[username]' => 'a',
-                    'new_user[plainPassword][first]' => 'mypassword',
-                    'new_user[plainPassword][second]' => 'mypassword',
-                    'new_user[email]' => '',
-                ],
-                'fos_user.username.short',
-            ],
-            [
-                [
-                    'new_user[username]' => 'wallace',
-                    'new_user[plainPassword][first]' => 'mypassword',
-                    'new_user[plainPassword][second]' => 'mypassword',
-                    'new_user[email]' => 'test',
-                ],
-                'fos_user.email.invalid',
-            ],
-            [
-                [
-                    'new_user[username]' => 'admin',
-                    'new_user[plainPassword][first]' => 'wallacewallace',
-                    'new_user[plainPassword][second]' => 'wallacewallace',
-                    'new_user[email]' => 'wallace@wallace.me',
-                ],
-                'fos_user.username.already_used',
-            ],
-            [
-                [
-                    'new_user[username]' => 'wallace',
-                    'new_user[plainPassword][first]' => 'mypassword1',
-                    'new_user[plainPassword][second]' => 'mypassword2',
-                    'new_user[email]' => 'wallace@wallace.me',
-                ],
-                'validator.password_must_match',
-            ],
-        ];
-    }
-
-    /**
-     * @dataProvider dataForNewUserFailed
-     */
-    public function testNewUserFailed($data, $expectedMessage)
-    {
-        $this->logInAs('admin');
-        $client = $this->getClient();
-
-        $crawler = $client->request('GET', '/config');
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        $form = $crawler->filter('button[id=new_user_save]')->form();
-
-        $crawler = $client->submit($form, $data);
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
-        $this->assertContains($expectedMessage, $alert[0]);
-    }
-
-    public function testNewUserCreated()
-    {
-        $this->logInAs('admin');
-        $client = $this->getClient();
-
-        $crawler = $client->request('GET', '/config');
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        $form = $crawler->filter('button[id=new_user_save]')->form();
-
-        $data = [
-            'new_user[username]' => 'wallace',
-            'new_user[plainPassword][first]' => 'wallace1',
-            'new_user[plainPassword][second]' => 'wallace1',
-            'new_user[email]' => 'wallace@wallace.me',
-        ];
-
-        $client->submit($form, $data);
-
-        $this->assertEquals(302, $client->getResponse()->getStatusCode());
-
-        $crawler = $client->followRedirect();
-
-        $this->assertContains('flashes.config.notice.user_added', $crawler->filter('body')->extract(['_text'])[0]);
-
-        $em = $client->getContainer()->get('doctrine.orm.entity_manager');
-        $user = $em
-            ->getRepository('WallabagUserBundle:User')
-            ->findOneByUsername('wallace');
-
-        $this->assertTrue(false !== $user);
-        $this->assertTrue($user->isEnabled());
-        $this->assertEquals('material', $user->getConfig()->getTheme());
-        $this->assertEquals(12, $user->getConfig()->getItemsPerPage());
-        $this->assertEquals(50, $user->getConfig()->getRssLimit());
-        $this->assertEquals('en', $user->getConfig()->getLanguage());
-        $this->assertEquals(1, $user->getConfig()->getReadingSpeed());
-    }
-
     public function testRssUpdateResetToken()
     {
         $this->logInAs('admin');
diff --git a/tests/Wallabag/UserBundle/Controller/ManageControllerTest.php b/tests/Wallabag/UserBundle/Controller/ManageControllerTest.php
new file mode 100644 (file)
index 0000000..19b824b
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+
+namespace Wallabag\UserBundle\Tests\Controller;
+
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+
+class ManageControllerTest extends WallabagCoreTestCase
+{
+    public function testLogin()
+    {
+        $client = $this->getClient();
+
+        $client->request('GET', '/users/');
+
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+        $this->assertContains('login', $client->getResponse()->headers->get('location'));
+    }
+
+    public function testCompleteScenario()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        // Create a new user in the database
+        $crawler = $client->request('GET', '/users/');
+        $this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /users/");
+        $crawler = $client->click($crawler->selectLink('user.list.create_new_one')->link());
+
+        // Fill in the form and submit it
+        $form = $crawler->selectButton('user.form.save')->form(array(
+            'new_user[username]' => 'test_user',
+            'new_user[email]' => 'test@test.io',
+            'new_user[plainPassword][first]' => 'test',
+            'new_user[plainPassword][second]' => 'test',
+        ));
+
+        $client->submit($form);
+        $client->followRedirect();
+        $crawler = $client->request('GET', '/users/');
+
+        // Check data in the show view
+        $this->assertGreaterThan(0, $crawler->filter('td:contains("test_user")')->count(), 'Missing element td:contains("test_user")');
+
+        // Edit the user
+        $crawler = $client->click($crawler->selectLink('user.list.edit_action')->last()->link());
+
+        $form = $crawler->selectButton('user.form.save')->form(array(
+            'user[name]' => 'Foo User',
+            'user[username]' => 'test_user',
+            'user[email]' => 'test@test.io',
+            'user[enabled]' => true,
+            'user[locked]' => false,
+        ));
+
+        $client->submit($form);
+        $crawler = $client->followRedirect();
+
+        // Check the element contains an attribute with value equals "Foo User"
+        $this->assertGreaterThan(0, $crawler->filter('[value="Foo User"]')->count(), 'Missing element [value="Foo User"]');
+
+        $crawler = $client->request('GET', '/users/');
+        $crawler = $client->click($crawler->selectLink('user.list.edit_action')->last()->link());
+
+        // Delete the user
+        $client->submit($crawler->selectButton('user.form.delete')->form());
+        $crawler = $client->followRedirect();
+
+        // Check the user has been delete on the list
+        $this->assertNotRegExp('/Foo User/', $client->getResponse()->getContent());
+    }
+
+    public function testDeleteDisabledForLoggedUser()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/users/'.$this->getLoggedInUserId().'/edit');
+        $disabled = $crawler->selectButton('user.form.delete')->extract('disabled');
+
+        $this->assertEquals('disabled', $disabled[0]);
+    }
+}