Как разрабатывать, подделывая логин для тестирования ACL в Symfony 2

Я разрабатываю часть создания веб-приложения на Symfony 2. Как и во многих приложениях, требуется аутентификация и авторизация. Как я могу продолжить разработку, принимая соображения ACL, пропустив или притворив логин?

В документах login_check прозрачность сеанса аутентификации и сеансов. Я думаю, что мне может потребоваться реализовать версию этого или каким-то образом вызвать его для входа в систему как разные пользователи/роли

Ответ 1

Я не совсем уверен, что понимаю ваш вопрос, но вы просто спрашиваете, как вы входите в систему программно?

В моих тестах я просто звоню как:

$this->container->get('security.context')->setToken(
    new UsernamePasswordToken(
        'maintenance', null, 'main', array('ROLE_FIXTURE_LOADER')
    )
);

В этом случае "обслуживание" не является даже реальным сущностью пользователя, это просто имя пользователя, которое я составил для своих приборов, чтобы они могли получить доступ к сервису, имея ROLE_FIXTURE_LOADER, но если вы действительно хотите войти в систему в качестве полного (так, чтобы у них был правильный идентификатор ACL), вы можете получить объект $user из базы данных и вызвать:

$this->container->get('security.context')->setToken(
    new UsernamePasswordToken(
        $user, null, 'main', $user->getRoles())
    )
);

Это не полный логин, но он работает с RBAC, и я не понимаю, почему он не будет работать с ACL, если вы передадите фактический пользовательский объект.

Что касается функционального тестирования моего интерфейса, если мне нужно войти в систему, я просто перейду на страницу входа и отправлю форму в соответствии с документами тестирования. Для любого из тех, кто работает, вам нужен доступ к контейнеру, поэтому вам нужно расширить WebTestCase или запустить собственную способность загружать ядро ​​(см. здесь).

У меня такое чувство, что я неправильно понял вопрос (т.е. вам нужно сделать что-то более сложное, чем просто поставить токен). Возможно, вы могли бы попытаться уточнить немного больше, что вы подразумеваете под

передача или подделка логина

Конкретный пример установки маркера безопасности в тесте:

Сначала мы создаем базовый класс для наших тестов, которые содержат метод удобства входа. Это можно сделать, расширив WebTestCase и используя метод getContainer на client ИЛИ, вы можете вытащить WebTestCase отдельно, чтобы свернуть собственный базовый класс, который просто загружает ядро ​​без клиента и возвращает контейнер (см. Мой ссылка для двух решений для достижения этого).

namespace Acme\SomeBundle\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

abstract class AcmeTestCase extends WebTestCase {

    protected function loginAs($client, $username) {
        $container = $client->getContainer();
        $doctrine = $container->get('doctrine');

        $user = $this->loadUser($doctrine, $username);

        // First Parameter is the actual user object.
        // Change 'main' to whatever your firewall is called in security.yml
        $container->get('security.context')->setToken(
            new UsernamePasswordToken(
                $user, null, 'main', $user->getRoles()
            )
        );
    }

    private function loadUser($doctrine, $username) {
        // Don't have to use doctrine if you don't want to, you could use
        // a service to load your user since you have access to the
        // container.

        // Assumes User entity implements UserInterface
        return $doctrine
                ->getRepository('AcmeUserBundle:User')
                ->findOneByUsername($username);
    }

}

Тогда вам просто нужно использовать свой базовый класс в любом тесте, который вы хотите. Например:

namespace Acme\SomeBundle\Tests\Entity;

use Acme\SomeBundle\Tests\AcmeTestCase;

class SomeEntityTest extends AcmeTestCase {

    public function somethingTest() {
        $this->loginAs(static::createClient(), 'SomeUsernameInDB');

        // Do the rest of your test here.
    }

}

Надеюсь, это поможет.

Ответ 2

Не уверен, что я очень хорошо понимаю ваш вопрос, но если вы просто хотите увидеть приложение с другой ролью пользователя, вы можете использовать Sympony Role Switcher, описанный здесь: http://symfony.com/doc/current/book/security.html#impersonating-a-user

Таким образом, вам просто нужно указать параметр в своем URL-адресе для просмотра вашего приложения в качестве другого подключенного пользователя.

Надеюсь, что это поможет!