resume/tests/Silex/Tests/Provider/SecurityServiceProviderTest...

441 lines
16 KiB
PHP

<?php
/*
* This file is part of the Silex framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Silex\Tests\Provider;
use Silex\Application;
use Silex\WebTestCase;
use Silex\Provider\SecurityServiceProvider;
use Silex\Provider\SessionServiceProvider;
use Silex\Provider\ValidatorServiceProvider;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpKernel\Client;
use Symfony\Component\HttpFoundation\Request;
/**
* SecurityServiceProvider.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class SecurityServiceProviderTest extends WebTestCase
{
/**
* @expectedException \LogicException
*/
public function testWrongAuthenticationType()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'wrong' => array(
'foobar' => true,
'users' => array(),
),
),
));
$app->get('/', function () {});
$app->handle(Request::create('/'));
}
public function testFormAuthentication()
{
$app = $this->createApplication('form');
$client = new Client($app);
$client->request('get', '/');
$this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());
$client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'bar'));
$this->assertContains('Bad credentials', $app['security.last_error']($client->getRequest()));
// hack to re-close the session as the previous assertions re-opens it
$client->getRequest()->getSession()->save();
$client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'foo'));
$this->assertEquals('', $app['security.last_error']($client->getRequest()));
$client->getRequest()->getSession()->save();
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertEquals('http://localhost/', $client->getResponse()->getTargetUrl());
$client->request('get', '/');
$this->assertEquals('fabienAUTHENTICATED', $client->getResponse()->getContent());
$client->request('get', '/admin');
$this->assertEquals(403, $client->getResponse()->getStatusCode());
$client->request('get', '/logout');
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertEquals('http://localhost/', $client->getResponse()->getTargetUrl());
$client->request('get', '/');
$this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());
$client->request('get', '/admin');
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertEquals('http://localhost/login', $client->getResponse()->getTargetUrl());
$client->request('post', '/login_check', array('_username' => 'admin', '_password' => 'foo'));
$this->assertEquals('', $app['security.last_error']($client->getRequest()));
$client->getRequest()->getSession()->save();
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertEquals('http://localhost/admin', $client->getResponse()->getTargetUrl());
$client->request('get', '/');
$this->assertEquals('adminAUTHENTICATEDADMIN', $client->getResponse()->getContent());
$client->request('get', '/admin');
$this->assertEquals('admin', $client->getResponse()->getContent());
}
public function testHttpAuthentication()
{
$app = $this->createApplication('http');
$client = new Client($app);
$client->request('get', '/');
$this->assertEquals(401, $client->getResponse()->getStatusCode());
$this->assertEquals('Basic realm="Secured"', $client->getResponse()->headers->get('www-authenticate'));
$client->request('get', '/', array(), array(), array('PHP_AUTH_USER' => 'dennis', 'PHP_AUTH_PW' => 'foo'));
$this->assertEquals('dennisAUTHENTICATED', $client->getResponse()->getContent());
$client->request('get', '/admin');
$this->assertEquals(403, $client->getResponse()->getStatusCode());
$client->restart();
$client->request('get', '/');
$this->assertEquals(401, $client->getResponse()->getStatusCode());
$this->assertEquals('Basic realm="Secured"', $client->getResponse()->headers->get('www-authenticate'));
$client->request('get', '/', array(), array(), array('PHP_AUTH_USER' => 'admin', 'PHP_AUTH_PW' => 'foo'));
$this->assertEquals('adminAUTHENTICATEDADMIN', $client->getResponse()->getContent());
$client->request('get', '/admin');
$this->assertEquals('admin', $client->getResponse()->getContent());
}
public function testGuardAuthentication()
{
$app = $this->createApplication('guard');
$client = new Client($app);
$client->request('get', '/');
$this->assertEquals(401, $client->getResponse()->getStatusCode(), 'The entry point is configured');
$this->assertEquals('{"message":"Authentication Required"}', $client->getResponse()->getContent());
$client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'lili:not the secret'));
$this->assertEquals(403, $client->getResponse()->getStatusCode(), 'User not found');
$this->assertEquals('{"message":"Username could not be found."}', $client->getResponse()->getContent());
$client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'victoria:not the secret'));
$this->assertEquals(403, $client->getResponse()->getStatusCode(), 'Invalid credentials');
$this->assertEquals('{"message":"Invalid credentials."}', $client->getResponse()->getContent());
$client->request('get', '/', array(), array(), array('HTTP_X_AUTH_TOKEN' => 'victoria:victoriasecret'));
$this->assertEquals('victoria', $client->getResponse()->getContent());
}
public function testUserPasswordValidatorIsRegistered()
{
$app = new Application();
$app->register(new ValidatorServiceProvider());
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'admin' => array(
'pattern' => '^/admin',
'http' => true,
'users' => array(
'admin' => array('ROLE_ADMIN', '513aeb0121909'),
),
),
),
));
$app->boot();
$this->assertInstanceOf('Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator', $app['security.validator.user_password_validator']);
}
public function testExposedExceptions()
{
$app = $this->createApplication('form');
$app['security.hide_user_not_found'] = false;
$client = new Client($app);
$client->request('get', '/');
$this->assertEquals('ANONYMOUS', $client->getResponse()->getContent());
$client->request('post', '/login_check', array('_username' => 'fabien', '_password' => 'bar'));
$this->assertEquals('The presented password is invalid.', $app['security.last_error']($client->getRequest()));
$client->getRequest()->getSession()->save();
$client->request('post', '/login_check', array('_username' => 'unknown', '_password' => 'bar'));
$this->assertEquals('Username "unknown" does not exist.', $app['security.last_error']($client->getRequest()));
$client->getRequest()->getSession()->save();
}
public function testFakeRoutesAreSerializable()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'admin' => array(
'logout' => true,
),
),
));
$app->boot();
$app->flush();
$this->assertCount(1, unserialize(serialize($app['routes'])));
}
public function testUser()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'http' => true,
'users' => array(
'fabien' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),
),
),
),
));
$app->get('/', function () { return 'foo'; });
$request = Request::create('/');
$app->handle($request);
$this->assertNull($app['user']);
$request->headers->set('PHP_AUTH_USER', 'fabien');
$request->headers->set('PHP_AUTH_PW', 'foo');
$app->handle($request);
$this->assertInstanceOf('Symfony\Component\Security\Core\User\UserInterface', $app['user']);
$this->assertEquals('fabien', $app['user']->getUsername());
}
public function testUserWithNoToken()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'http' => true,
),
),
));
$request = Request::create('/');
$app->get('/', function () { return 'foo'; });
$app->handle($request);
$this->assertNull($app['user']);
}
public function testUserWithInvalidUser()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'http' => true,
),
),
));
$request = Request::create('/');
$app->boot();
$app['security.token_storage']->setToken(new UsernamePasswordToken('foo', 'foo', 'foo'));
$app->get('/', function () { return 'foo'; });
$app->handle($request);
$this->assertNull($app['user']);
}
public function testAccessRulePathArray()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'http' => true,
),
),
'security.access_rules' => array(
array(array(
'path' => '^/admin',
), 'ROLE_ADMIN'),
),
));
$request = Request::create('/admin');
$app->boot();
$accessMap = $app['security.access_map'];
$this->assertEquals($accessMap->getPatterns($request), array(
array('ROLE_ADMIN'),
'',
));
}
public function createApplication($authenticationMethod = 'form')
{
$app = new Application();
$app->register(new SessionServiceProvider());
$app = call_user_func(array($this, 'add'.ucfirst($authenticationMethod).'Authentication'), $app);
$app['session.test'] = true;
return $app;
}
private function addFormAuthentication($app)
{
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'login' => array(
'pattern' => '^/login$',
),
'default' => array(
'pattern' => '^.*$',
'anonymous' => true,
'form' => array(
'require_previous_session' => false,
),
'logout' => true,
'users' => array(
// password is foo
'fabien' => array('ROLE_USER', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),
'admin' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),
),
),
),
'security.access_rules' => array(
array('^/admin', 'ROLE_ADMIN'),
),
'security.role_hierarchy' => array(
'ROLE_ADMIN' => array('ROLE_USER'),
),
));
$app->get('/login', function (Request $request) use ($app) {
$app['session']->start();
return $app['security.last_error']($request);
});
$app->get('/', function () use ($app) {
$user = $app['security.token_storage']->getToken()->getUser();
$content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';
if ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_FULLY')) {
$content .= 'AUTHENTICATED';
}
if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {
$content .= 'ADMIN';
}
return $content;
});
$app->get('/admin', function () use ($app) {
return 'admin';
});
return $app;
}
private function addHttpAuthentication($app)
{
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'http-auth' => array(
'pattern' => '^.*$',
'http' => true,
'users' => array(
// password is foo
'dennis' => array('ROLE_USER', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),
'admin' => array('ROLE_ADMIN', '$2y$15$lzUNsTegNXvZW3qtfucV0erYBcEqWVeyOmjolB7R1uodsAVJ95vvu'),
),
),
),
'security.access_rules' => array(
array('^/admin', 'ROLE_ADMIN'),
),
'security.role_hierarchy' => array(
'ROLE_ADMIN' => array('ROLE_USER'),
),
));
$app->get('/', function () use ($app) {
$user = $app['security.token_storage']->getToken()->getUser();
$content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';
if ($app['security.authorization_checker']->isGranted('IS_AUTHENTICATED_FULLY')) {
$content .= 'AUTHENTICATED';
}
if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {
$content .= 'ADMIN';
}
return $content;
});
$app->get('/admin', function () use ($app) {
return 'admin';
});
return $app;
}
private function addGuardAuthentication($app)
{
$app['app.authenticator.token'] = function ($app) {
return new SecurityServiceProviderTest\TokenAuthenticator($app);
};
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'guard' => array(
'pattern' => '^.*$',
'form' => true,
'guard' => array(
'authenticators' => array(
'app.authenticator.token',
),
),
'users' => array(
'victoria' => array('ROLE_USER', 'victoriasecret'),
),
),
),
));
$app->get('/', function () use ($app) {
$user = $app['security.token_storage']->getToken()->getUser();
$content = is_object($user) ? $user->getUsername() : 'ANONYMOUS';
return $content;
})->bind('homepage');
return $app;
}
}