summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Acl/.gitignore3
-rw-r--r--Acl/Dbal/AclProvider.php26
-rw-r--r--Acl/Dbal/MutableAclProvider.php70
-rw-r--r--Acl/Domain/Acl.php18
-rw-r--r--Acl/Exception/Exception.php2
-rw-r--r--Acl/LICENSE19
-rw-r--r--Acl/Permission/AbstractMaskBuilder.php85
-rw-r--r--Acl/Permission/BasicPermissionMap.php10
-rw-r--r--Acl/Permission/MaskBuilder.php124
-rw-r--r--Acl/Permission/MaskBuilderInterface.php76
-rw-r--r--Acl/Permission/MaskBuilderRetrievalInterface.php25
-rw-r--r--Acl/README.md16
-rw-r--r--Acl/Resources/schema/drizzle.sql10
-rw-r--r--Acl/Resources/schema/mssql.sql10
-rw-r--r--Acl/Resources/schema/mysql.sql10
-rw-r--r--Acl/Resources/schema/oracle.sql44
-rw-r--r--Acl/Resources/schema/sqlanywhere.sql43
-rw-r--r--Acl/Resources/schema/sqlite.sql10
-rw-r--r--Acl/Tests/Dbal/AclProviderBenchmarkTest.php (renamed from Tests/Acl/Dbal/AclProviderBenchmarkTest.php)2
-rw-r--r--Acl/Tests/Dbal/AclProviderTest.php (renamed from Tests/Acl/Dbal/AclProviderTest.php)2
-rw-r--r--Acl/Tests/Dbal/MutableAclProviderTest.php (renamed from Tests/Acl/Dbal/MutableAclProviderTest.php)32
-rw-r--r--Acl/Tests/Domain/AclTest.php (renamed from Tests/Acl/Domain/AclTest.php)2
-rw-r--r--Acl/Tests/Domain/AuditLoggerTest.php (renamed from Tests/Acl/Domain/AuditLoggerTest.php)6
-rw-r--r--Acl/Tests/Domain/DoctrineAclCacheTest.php (renamed from Tests/Acl/Domain/DoctrineAclCacheTest.php)2
-rw-r--r--Acl/Tests/Domain/EntryTest.php (renamed from Tests/Acl/Domain/EntryTest.php)2
-rw-r--r--Acl/Tests/Domain/FieldEntryTest.php (renamed from Tests/Acl/Domain/FieldEntryTest.php)2
-rw-r--r--Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php (renamed from Tests/Acl/Domain/ObjectIdentityRetrievalStrategyTest.php)2
-rw-r--r--Acl/Tests/Domain/ObjectIdentityTest.php (renamed from Tests/Acl/Domain/ObjectIdentityTest.php)20
-rw-r--r--Acl/Tests/Domain/PermissionGrantingStrategyTest.php (renamed from Tests/Acl/Domain/PermissionGrantingStrategyTest.php)2
-rw-r--r--Acl/Tests/Domain/RoleSecurityIdentityTest.php (renamed from Tests/Acl/Domain/RoleSecurityIdentityTest.php)2
-rw-r--r--Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php (renamed from Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php)4
-rw-r--r--Acl/Tests/Domain/UserSecurityIdentityTest.php (renamed from Tests/Acl/Domain/UserSecurityIdentityTest.php)6
-rw-r--r--Acl/Tests/Permission/BasicPermissionMapTest.php (renamed from Tests/Acl/Permission/BasicPermissionMapTest.php)2
-rw-r--r--Acl/Tests/Permission/MaskBuilderTest.php (renamed from Tests/Acl/Permission/MaskBuilderTest.php)2
-rw-r--r--Acl/Tests/Voter/AclVoterTest.php (renamed from Tests/Acl/Voter/AclVoterTest.php)2
-rw-r--r--Acl/Voter/AclVoter.php8
-rw-r--r--Acl/composer.json44
-rw-r--r--Acl/phpunit.xml.dist34
-rw-r--r--CHANGELOG.md26
-rw-r--r--Core/.gitignore3
-rw-r--r--Core/Authentication/AuthenticationProviderManager.php6
-rw-r--r--Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php34
-rw-r--r--Core/Authentication/Provider/SimpleAuthenticationProvider.php50
-rw-r--r--Core/Authentication/Provider/UserAuthenticationProvider.php4
-rw-r--r--Core/Authentication/SimpleAuthenticatorInterface.php25
-rw-r--r--Core/Authentication/SimpleFormAuthenticatorInterface.php22
-rw-r--r--Core/Authentication/SimplePreAuthenticatorInterface.php22
-rw-r--r--Core/Authentication/Token/AbstractToken.php12
-rw-r--r--Core/Authentication/Token/Storage/TokenStorage.php43
-rw-r--r--Core/Authentication/Token/Storage/TokenStorageInterface.php36
-rw-r--r--Core/Authorization/AccessDecisionManager.php13
-rw-r--r--Core/Authorization/AuthorizationChecker.php70
-rw-r--r--Core/Authorization/AuthorizationCheckerInterface.php30
-rw-r--r--Core/Authorization/ExpressionLanguage.php33
-rw-r--r--Core/Authorization/ExpressionLanguageProvider.php58
-rw-r--r--Core/Authorization/Voter/AbstractVoter.php113
-rw-r--r--Core/Authorization/Voter/ExpressionVoter.php118
-rw-r--r--Core/Encoder/EncoderAwareInterface.php28
-rw-r--r--Core/Encoder/EncoderFactory.php27
-rw-r--r--Core/Encoder/UserPasswordEncoder.php55
-rw-r--r--Core/Encoder/UserPasswordEncoderInterface.php40
-rw-r--r--Core/Exception/AccessDeniedException.php2
-rw-r--r--Core/Exception/ExceptionInterface.php21
-rw-r--r--Core/Exception/InvalidArgumentException.php21
-rw-r--r--Core/Exception/RuntimeException.php21
-rw-r--r--Core/Exception/UsernameNotFoundException.php8
-rw-r--r--Core/LICENSE19
-rw-r--r--Core/README.md16
-rw-r--r--Core/Resources/translations/security.ar.xlf71
-rw-r--r--Core/Resources/translations/security.az.xlf71
-rw-r--r--Core/Resources/translations/security.bg.xlf71
-rw-r--r--Core/Resources/translations/security.ca.xlf71
-rw-r--r--Core/Resources/translations/security.cs.xlf71
-rw-r--r--Core/Resources/translations/security.da.xlf71
-rw-r--r--Core/Resources/translations/security.de.xlf71
-rw-r--r--Core/Resources/translations/security.el.xlf71
-rw-r--r--Core/Resources/translations/security.en.xlf71
-rw-r--r--Core/Resources/translations/security.es.xlf71
-rw-r--r--Core/Resources/translations/security.fa.xlf71
-rw-r--r--Core/Resources/translations/security.fr.xlf71
-rw-r--r--Core/Resources/translations/security.gl.xlf71
-rw-r--r--Core/Resources/translations/security.he.xlf71
-rw-r--r--Core/Resources/translations/security.hr.xlf71
-rw-r--r--Core/Resources/translations/security.hu.xlf71
-rw-r--r--Core/Resources/translations/security.id.xlf71
-rw-r--r--Core/Resources/translations/security.it.xlf71
-rw-r--r--Core/Resources/translations/security.ja.xlf71
-rw-r--r--Core/Resources/translations/security.lb.xlf71
-rw-r--r--Core/Resources/translations/security.lt.xlf71
-rw-r--r--Core/Resources/translations/security.nl.xlf71
-rw-r--r--Core/Resources/translations/security.no.xlf71
-rw-r--r--Core/Resources/translations/security.pl.xlf71
-rw-r--r--Core/Resources/translations/security.pt_BR.xlf71
-rw-r--r--Core/Resources/translations/security.pt_PT.xlf71
-rw-r--r--Core/Resources/translations/security.ro.xlf71
-rw-r--r--Core/Resources/translations/security.ru.xlf71
-rw-r--r--Core/Resources/translations/security.sk.xlf71
-rw-r--r--Core/Resources/translations/security.sl.xlf71
-rw-r--r--Core/Resources/translations/security.sr_Cyrl.xlf71
-rw-r--r--Core/Resources/translations/security.sr_Latn.xlf71
-rw-r--r--Core/Resources/translations/security.sv.xlf71
-rw-r--r--Core/Resources/translations/security.th.xlf71
-rw-r--r--Core/Resources/translations/security.tr.xlf71
-rw-r--r--Core/Resources/translations/security.ua.xlf71
-rw-r--r--Core/Resources/translations/security.vi.xlf71
-rw-r--r--Core/Resources/translations/security.zh_CN.xlf71
-rw-r--r--Core/Role/RoleHierarchy.php4
-rw-r--r--Core/Security.php25
-rw-r--r--Core/SecurityContext.php79
-rw-r--r--Core/SecurityContextInterface.php39
-rw-r--r--Core/Tests/Authentication/AuthenticationProviderManagerTest.php (renamed from Tests/Core/Authentication/AuthenticationProviderManagerTest.php)14
-rw-r--r--Core/Tests/Authentication/AuthenticationTrustResolverTest.php (renamed from Tests/Core/Authentication/AuthenticationTrustResolverTest.php)2
-rw-r--r--Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php (renamed from Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php (renamed from Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php (renamed from Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php (renamed from Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php (renamed from Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php (renamed from Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php)2
-rw-r--r--Core/Tests/Authentication/RememberMe/PersistentTokenTest.php (renamed from Tests/Core/Authentication/RememberMe/PersistentTokenTest.php)2
-rw-r--r--Core/Tests/Authentication/Token/AbstractTokenTest.php (renamed from Tests/Core/Authentication/Token/AbstractTokenTest.php)2
-rw-r--r--Core/Tests/Authentication/Token/AnonymousTokenTest.php (renamed from Tests/Core/Authentication/Token/AnonymousTokenTest.php)2
-rw-r--r--Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php (renamed from Tests/Core/Authentication/Token/PreAuthenticatedTokenTest.php)2
-rw-r--r--Core/Tests/Authentication/Token/RememberMeTokenTest.php (renamed from Tests/Core/Authentication/Token/RememberMeTokenTest.php)2
-rw-r--r--Core/Tests/Authentication/Token/Storage/TokenStorageTest.php26
-rw-r--r--Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php (renamed from Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php)2
-rw-r--r--Core/Tests/Authorization/AccessDecisionManagerTest.php (renamed from Tests/Core/Authorization/AccessDecisionManagerTest.php)48
-rw-r--r--Core/Tests/Authorization/AuthorizationCheckerTest.php99
-rw-r--r--Core/Tests/Authorization/ExpressionLanguageTest.php79
-rw-r--r--Core/Tests/Authorization/Voter/AbstractVoterTest.php74
-rw-r--r--Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php (renamed from Tests/Core/Authorization/Voter/AuthenticatedVoterTest.php)2
-rw-r--r--Core/Tests/Authorization/Voter/ExpressionVoterTest.php97
-rw-r--r--Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php (renamed from Tests/Core/Authorization/Voter/RoleHierarchyVoterTest.php)2
-rw-r--r--Core/Tests/Authorization/Voter/RoleVoterTest.php (renamed from Tests/Core/Authorization/Voter/RoleVoterTest.php)2
-rw-r--r--Core/Tests/Encoder/BCryptPasswordEncoderTest.php (renamed from Tests/Core/Encoder/BCryptPasswordEncoderTest.php)11
-rw-r--r--Core/Tests/Encoder/BasePasswordEncoderTest.php (renamed from Tests/Core/Encoder/BasePasswordEncoderTest.php)2
-rw-r--r--Core/Tests/Encoder/EncoderFactoryTest.php (renamed from Tests/Core/Encoder/EncoderFactoryTest.php)72
-rw-r--r--Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php (renamed from Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php)2
-rw-r--r--Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php (renamed from Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php)2
-rw-r--r--Core/Tests/Encoder/PlaintextPasswordEncoderTest.php (renamed from Tests/Core/Encoder/PlaintextPasswordEncoderTest.php)2
-rw-r--r--Core/Tests/Encoder/UserPasswordEncoderTest.php70
-rw-r--r--Core/Tests/Exception/UsernameNotFoundExceptionTest.php25
-rw-r--r--Core/Tests/LegacySecurityContextInterfaceTest.php31
-rw-r--r--Core/Tests/LegacySecurityContextTest.php122
-rw-r--r--Core/Tests/Resources/TranslationFilesTest.php31
-rw-r--r--Core/Tests/Role/RoleHierarchyTest.php (renamed from Tests/Core/Role/RoleHierarchyTest.php)2
-rw-r--r--Core/Tests/Role/RoleTest.php (renamed from Tests/Core/Role/RoleTest.php)2
-rw-r--r--Core/Tests/Role/SwitchUserRoleTest.php (renamed from Tests/Core/Role/SwitchUserRoleTest.php)2
-rw-r--r--Core/Tests/User/ChainUserProviderTest.php (renamed from Tests/Core/User/ChainUserProviderTest.php)2
-rw-r--r--Core/Tests/User/InMemoryUserProviderTest.php (renamed from Tests/Core/User/InMemoryUserProviderTest.php)2
-rw-r--r--Core/Tests/User/UserCheckerTest.php (renamed from Tests/Core/User/UserCheckerTest.php)2
-rw-r--r--Core/Tests/User/UserTest.php (renamed from Tests/Core/User/UserTest.php)8
-rw-r--r--Core/Tests/Util/ClassUtilsTest.php (renamed from Tests/Core/Util/ClassUtilsTest.php)12
-rw-r--r--Core/Tests/Util/StringUtilsTest.php (renamed from Tests/Core/Util/StringUtilsTest.php)2
-rw-r--r--Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorTest.php28
-rw-r--r--Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php169
-rw-r--r--Core/User/User.php5
-rw-r--r--Core/Validator/Constraints/UserPassword.php2
-rw-r--r--Core/Validator/Constraints/UserPasswordValidator.php15
-rw-r--r--Core/composer.json49
-rw-r--r--Core/phpunit.xml.dist34
-rw-r--r--Csrf/.gitignore3
-rw-r--r--Csrf/CsrfToken.php72
-rw-r--r--Csrf/CsrfTokenManager.php97
-rw-r--r--Csrf/CsrfTokenManagerInterface.php69
-rw-r--r--Csrf/Exception/TokenNotFoundException.php21
-rw-r--r--Csrf/LICENSE19
-rw-r--r--Csrf/README.md14
-rw-r--r--Csrf/Tests/CsrfTokenManagerTest.php164
-rw-r--r--Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php71
-rw-r--r--Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php126
-rw-r--r--Csrf/Tests/TokenStorage/SessionTokenStorageTest.php258
-rw-r--r--Csrf/TokenGenerator/TokenGeneratorInterface.php29
-rw-r--r--Csrf/TokenGenerator/UriSafeTokenGenerator.php66
-rw-r--r--Csrf/TokenStorage/NativeSessionTokenStorage.php123
-rw-r--r--Csrf/TokenStorage/SessionTokenStorage.php109
-rw-r--r--Csrf/TokenStorage/TokenStorageInterface.php60
-rw-r--r--Csrf/composer.json40
-rw-r--r--Csrf/phpunit.xml.dist33
-rw-r--r--Http/.gitignore3
-rw-r--r--Http/AccessMap.php6
-rw-r--r--Http/Authentication/AuthenticationUtils.php88
-rw-r--r--Http/Authentication/CustomAuthenticationFailureHandler.php45
-rw-r--r--Http/Authentication/CustomAuthenticationSuccessHandler.php49
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php44
-rw-r--r--Http/Authentication/DefaultAuthenticationSuccessHandler.php38
-rw-r--r--Http/Authentication/SimpleAuthenticationHandler.php106
-rw-r--r--Http/EntryPoint/DigestAuthenticationEntryPoint.php2
-rw-r--r--Http/Firewall.php28
-rw-r--r--Http/Firewall/AbstractAuthenticationListener.php33
-rw-r--r--Http/Firewall/AbstractPreAuthenticatedListener.php30
-rw-r--r--Http/Firewall/AccessListener.php14
-rw-r--r--Http/Firewall/AnonymousAuthenticationListener.php31
-rw-r--r--Http/Firewall/BasicAuthenticationListener.php20
-rw-r--r--Http/Firewall/ChannelListener.php6
-rw-r--r--Http/Firewall/ContextListener.php57
-rw-r--r--Http/Firewall/DigestAuthenticationListener.php29
-rw-r--r--Http/Firewall/ExceptionListener.php45
-rw-r--r--Http/Firewall/LogoutListener.php42
-rw-r--r--Http/Firewall/RememberMeListener.php41
-rw-r--r--Http/Firewall/RemoteUserAuthenticationListener.php49
-rw-r--r--Http/Firewall/SimpleFormAuthenticationListener.php130
-rw-r--r--Http/Firewall/SimplePreAuthenticationListener.php126
-rw-r--r--Http/Firewall/SwitchUserListener.php27
-rw-r--r--Http/Firewall/UsernamePasswordFormAuthenticationListener.php32
-rw-r--r--Http/Firewall/X509AuthenticationListener.php6
-rw-r--r--Http/HttpUtils.php16
-rw-r--r--Http/LICENSE19
-rw-r--r--Http/Logout/LogoutUrlGenerator.php139
-rw-r--r--Http/README.md16
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php6
-rw-r--r--Http/RememberMe/PersistentTokenBasedRememberMeServices.php3
-rw-r--r--Http/RememberMe/RememberMeServicesInterface.php4
-rw-r--r--Http/RememberMe/ResponseListener.php3
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php4
-rw-r--r--Http/Session/SessionAuthenticationStrategyInterface.php2
-rw-r--r--Http/Tests/AccessMapTest.php (renamed from Tests/Http/AccessMapTest.php)2
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php (renamed from Tests/Http/Authentication/DefaultAuthenticationFailureHandlerTest.php)20
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php (renamed from Tests/Http/Authentication/DefaultAuthenticationSuccessHandlerTest.php)2
-rw-r--r--Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php194
-rw-r--r--Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php (renamed from Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php)2
-rw-r--r--Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php (renamed from Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php)2
-rw-r--r--Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php (renamed from Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php)2
-rw-r--r--Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php (renamed from Tests/Http/EntryPoint/RetryAuthenticationEntryPointTest.php)2
-rw-r--r--Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php (renamed from Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php)40
-rw-r--r--Http/Tests/Firewall/AccessListenerTest.php (renamed from Tests/Http/Firewall/AccessListenerTest.php)30
-rw-r--r--Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php87
-rw-r--r--Http/Tests/Firewall/BasicAuthenticationListenerTest.php (renamed from Tests/Http/Firewall/BasicAuthenticationListenerTest.php)40
-rw-r--r--Http/Tests/Firewall/ChannelListenerTest.php (renamed from Tests/Http/Firewall/ChannelListenerTest.php)2
-rw-r--r--Http/Tests/Firewall/ContextListenerTest.php (renamed from Tests/Http/Firewall/ContextListenerTest.php)61
-rw-r--r--Http/Tests/Firewall/DigestDataTest.php (renamed from Tests/Http/Firewall/DigestDataTest.php)2
-rw-r--r--Http/Tests/Firewall/ExceptionListenerTest.php (renamed from Tests/Http/Firewall/ExceptionListenerTest.php)21
-rw-r--r--Http/Tests/Firewall/LogoutListenerTest.php (renamed from Tests/Http/Firewall/LogoutListenerTest.php)56
-rw-r--r--Http/Tests/Firewall/RememberMeListenerTest.php415
-rw-r--r--Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php91
-rw-r--r--Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php128
-rw-r--r--Http/Tests/Firewall/SwitchUserListenerTest.php (renamed from Tests/Http/Firewall/SwitchUserListenerTest.php)89
-rw-r--r--Http/Tests/Firewall/X509AuthenticationListenerTest.php (renamed from Tests/Http/Firewall/X509AuthenticationListenerTest.php)18
-rw-r--r--Http/Tests/FirewallMapTest.php (renamed from Tests/Http/FirewallMapTest.php)2
-rw-r--r--Http/Tests/FirewallTest.php (renamed from Tests/Http/FirewallTest.php)2
-rw-r--r--Http/Tests/HttpUtilsTest.php (renamed from Tests/Http/HttpUtilsTest.php)10
-rw-r--r--Http/Tests/Logout/CookieClearingLogoutHandlerTest.php (renamed from Tests/Http/Logout/CookieClearingLogoutHandlerTest.php)2
-rw-r--r--Http/Tests/Logout/DefaultLogoutSuccessHandlerTest.php (renamed from Tests/Http/Logout/DefaultLogoutSuccessHandlerTest.php)2
-rw-r--r--Http/Tests/Logout/SessionLogoutHandlerTest.php (renamed from Tests/Http/Logout/SessionLogoutHandlerTest.php)2
-rw-r--r--Http/Tests/RememberMe/AbstractRememberMeServicesTest.php (renamed from Tests/Http/RememberMe/AbstractRememberMeServicesTest.php)4
-rw-r--r--Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php (renamed from Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php)2
-rw-r--r--Http/Tests/RememberMe/ResponseListenerTest.php (renamed from Tests/Http/RememberMe/ResponseListenerTest.php)4
-rw-r--r--Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php (renamed from Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php)2
-rw-r--r--Http/Tests/Session/SessionAuthenticationStrategyTest.php (renamed from Tests/Http/Session/SessionAuthenticationStrategyTest.php)2
-rw-r--r--Http/composer.json46
-rw-r--r--Http/phpunit.xml.dist33
-rw-r--r--Tests/Core/SecurityContextTest.php97
-rw-r--r--Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php157
-rw-r--r--Tests/Http/Firewall/AnonymousAuthenticationListenerTest.php68
-rw-r--r--Tests/Http/Firewall/RememberMeListenerTest.php247
-rw-r--r--Tests/TranslationSyncStatusTest.php63
-rw-r--r--composer.json40
-rw-r--r--phpunit.xml.dist5
257 files changed, 9192 insertions, 1392 deletions
diff --git a/Acl/.gitignore b/Acl/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/Acl/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php
index bba5824..6709023 100644
--- a/Acl/Dbal/AclProvider.php
+++ b/Acl/Dbal/AclProvider.php
@@ -206,7 +206,8 @@ class AclProvider implements AclProviderInterface
foreach ($oids as $oid) {
if (!$result->contains($oid)) {
if (1 === count($oids)) {
- throw new AclNotFoundException(sprintf('No ACL found for %s.', $oid));
+ $objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
+ throw new AclNotFoundException(sprintf('No ACL found for %s.', $objectName));
}
$partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
@@ -296,7 +297,8 @@ SELECTCLAUSE;
if (1 === count($types)) {
$ids = array();
for ($i = 0; $i < $count; ++$i) {
- $ids[] = $this->connection->quote($batch[$i]->getIdentifier());
+ $identifier = (string) $batch[$i]->getIdentifier();
+ $ids[] = $this->connection->quote($identifier);
}
$sql .= sprintf(
@@ -339,17 +341,17 @@ SELECTCLAUSE;
$query = <<<FINDCHILDREN
SELECT o.object_identifier, c.class_type
FROM
- {$this->options['oid_table_name']} as o
- INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id
- INNER JOIN {$this->options['oid_ancestors_table_name']} as a ON a.object_identity_id = o.id
+ {$this->options['oid_table_name']} o
+ INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
+ INNER JOIN {$this->options['oid_ancestors_table_name']} a ON a.object_identity_id = o.id
WHERE
a.ancestor_id = %d AND a.object_identity_id != a.ancestor_id
FINDCHILDREN;
} else {
$query = <<<FINDCHILDREN
SELECT o.object_identifier, c.class_type
- FROM {$this->options['oid_table_name']} as o
- INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id
+ FROM {$this->options['oid_table_name']} o
+ INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
WHERE o.parent_object_identity_id = %d
FINDCHILDREN;
}
@@ -378,8 +380,8 @@ QUERY;
$query,
$this->options['oid_table_name'],
$this->options['class_table_name'],
- $this->connection->quote($oid->getIdentifier()),
- $this->connection->quote($oid->getType())
+ $this->connection->quote((string) $oid->getIdentifier()),
+ $this->connection->quote((string) $oid->getType())
);
}
@@ -435,8 +437,8 @@ QUERY;
$ancestorIds = array();
foreach ($this->connection->executeQuery($sql)->fetchAll() as $data) {
// FIXME: skip ancestors which are cached
-
- $ancestorIds[] = $data['ancestor_id'];
+ // Fix: Oracle returns keys in uppercase
+ $ancestorIds[] = reset($data);
}
return $ancestorIds;
@@ -542,7 +544,7 @@ QUERY;
$auditSuccess,
$auditFailure,
$username,
- $securityIdentifier) = $data;
+ $securityIdentifier) = array_values($data);
// has the ACL been hydrated during this hydration cycle?
if (isset($acls[$aclId])) {
diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php
index 40ed471..273625a 100644
--- a/Acl/Dbal/MutableAclProvider.php
+++ b/Acl/Dbal/MutableAclProvider.php
@@ -51,7 +51,8 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
public function createAcl(ObjectIdentityInterface $oid)
{
if (false !== $this->retrieveObjectIdentityPrimaryKey($oid)) {
- throw new AclAlreadyExistsException(sprintf('%s is already associated with an ACL.', $oid));
+ $objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
+ throw new AclAlreadyExistsException(sprintf('%s is already associated with an ACL.', $objectName));
}
$this->connection->beginTransaction();
@@ -109,6 +110,19 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
}
/**
+ * Deletes the security identity from the database.
+ * ACL entries have the CASCADE option on their foreign key so they will also get deleted.
+ *
+ * @param SecurityIdentityInterface $sid
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function deleteSecurityIdentity(SecurityIdentityInterface $sid)
+ {
+ $this->connection->executeQuery($this->getDeleteSecurityIdentityIdSql($sid));
+ }
+
+ /**
* {@inheritdoc}
*/
public function findAcls(array $oids, array $sids = array())
@@ -352,6 +366,17 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
}
/**
+ * Updates a user security identity when the user's username changes.
+ *
+ * @param UserSecurityIdentity $usid
+ * @param string $oldUsername
+ */
+ public function updateUserSecurityIdentity(UserSecurityIdentity $usid, $oldUsername)
+ {
+ $this->connection->executeQuery($this->getUpdateUserSecurityIdentitySql($usid, $oldUsername));
+ }
+
+ /**
* Constructs the SQL for deleting access control entries.
*
* @param int $oidPK
@@ -626,6 +651,23 @@ QUERY;
}
/**
+ * Constructs the SQL to delete a security identity.
+ *
+ * @param SecurityIdentityInterface $sid
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return string
+ */
+ protected function getDeleteSecurityIdentityIdSql(SecurityIdentityInterface $sid)
+ {
+ $select = $this->getSelectSecurityIdentityIdSql($sid);
+ $delete = preg_replace('/^SELECT id FROM/', 'DELETE FROM', $select);
+
+ return $delete;
+ }
+
+ /**
* Constructs the SQL for updating an object identity.
*
* @param int $pk
@@ -650,6 +692,32 @@ QUERY;
}
/**
+ * Constructs the SQL for updating a user security identity.
+ *
+ * @param UserSecurityIdentity $usid
+ * @param string $oldUsername
+ *
+ * @return string
+ */
+ protected function getUpdateUserSecurityIdentitySql(UserSecurityIdentity $usid, $oldUsername)
+ {
+ if ($usid->getUsername() == $oldUsername) {
+ throw new \InvalidArgumentException('There are no changes.');
+ }
+
+ $oldIdentifier = $usid->getClass().'-'.$oldUsername;
+ $newIdentifier = $usid->getClass().'-'.$usid->getUsername();
+
+ return sprintf(
+ 'UPDATE %s SET identifier = %s WHERE identifier = %s AND username = %s',
+ $this->options['sid_table_name'],
+ $this->connection->quote($newIdentifier),
+ $this->connection->quote($oldIdentifier),
+ $this->connection->getDatabasePlatform()->convertBooleans(true)
+ );
+ }
+
+ /**
* Constructs the SQL for updating an ACE.
*
* @param int $pk
diff --git a/Acl/Domain/Acl.php b/Acl/Domain/Acl.php
index 365fc37..fb70738 100644
--- a/Acl/Domain/Acl.php
+++ b/Acl/Domain/Acl.php
@@ -38,14 +38,14 @@ class Acl implements AuditableAclInterface, NotifyPropertyChanged
private $parentAcl;
private $permissionGrantingStrategy;
private $objectIdentity;
- private $classAces;
- private $classFieldAces;
- private $objectAces;
- private $objectFieldAces;
+ private $classAces = array();
+ private $classFieldAces = array();
+ private $objectAces = array();
+ private $objectFieldAces = array();
private $id;
private $loadedSids;
private $entriesInheriting;
- private $listeners;
+ private $listeners = array();
/**
* Constructor.
@@ -56,19 +56,13 @@ class Acl implements AuditableAclInterface, NotifyPropertyChanged
* @param array $loadedSids
* @param bool $entriesInheriting
*/
- public function __construct($id, ObjectIdentityInterface $objectIdentity, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $loadedSids = array(), $entriesInheriting)
+ public function __construct($id, ObjectIdentityInterface $objectIdentity, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $loadedSids, $entriesInheriting)
{
$this->id = $id;
$this->objectIdentity = $objectIdentity;
$this->permissionGrantingStrategy = $permissionGrantingStrategy;
$this->loadedSids = $loadedSids;
$this->entriesInheriting = $entriesInheriting;
- $this->parentAcl = null;
- $this->classAces = array();
- $this->classFieldAces = array();
- $this->objectAces = array();
- $this->objectFieldAces = array();
- $this->listeners = array();
}
/**
diff --git a/Acl/Exception/Exception.php b/Acl/Exception/Exception.php
index a38c8ee..f1e1001 100644
--- a/Acl/Exception/Exception.php
+++ b/Acl/Exception/Exception.php
@@ -16,6 +16,6 @@ namespace Symfony\Component\Security\Acl\Exception;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
-class Exception extends \Exception
+class Exception extends \RuntimeException
{
}
diff --git a/Acl/LICENSE b/Acl/LICENSE
new file mode 100644
index 0000000..12a7453
--- /dev/null
+++ b/Acl/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2016 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Acl/Permission/AbstractMaskBuilder.php b/Acl/Permission/AbstractMaskBuilder.php
new file mode 100644
index 0000000..93f1755
--- /dev/null
+++ b/Acl/Permission/AbstractMaskBuilder.php
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Permission;
+
+/**
+ * This abstract class implements nearly all the MaskBuilderInterface methods.
+ */
+abstract class AbstractMaskBuilder implements MaskBuilderInterface
+{
+ /**
+ * @var int
+ */
+ protected $mask;
+
+ /**
+ * Constructor.
+ *
+ * @param int $mask optional; defaults to 0
+ */
+ public function __construct($mask = 0)
+ {
+ $this->set($mask);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($mask)
+ {
+ if (!is_int($mask)) {
+ throw new \InvalidArgumentException('$mask must be an integer.');
+ }
+
+ $this->mask = $mask;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get()
+ {
+ return $this->mask;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add($mask)
+ {
+ $this->mask |= $this->resolveMask($mask);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($mask)
+ {
+ $this->mask &= ~$this->resolveMask($mask);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ $this->mask = 0;
+
+ return $this;
+ }
+}
diff --git a/Acl/Permission/BasicPermissionMap.php b/Acl/Permission/BasicPermissionMap.php
index 4e26c02..fa5437d 100644
--- a/Acl/Permission/BasicPermissionMap.php
+++ b/Acl/Permission/BasicPermissionMap.php
@@ -17,7 +17,7 @@ namespace Symfony\Component\Security\Acl\Permission;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
-class BasicPermissionMap implements PermissionMapInterface
+class BasicPermissionMap implements PermissionMapInterface, MaskBuilderRetrievalInterface
{
const PERMISSION_VIEW = 'VIEW';
const PERMISSION_EDIT = 'EDIT';
@@ -105,4 +105,12 @@ class BasicPermissionMap implements PermissionMapInterface
{
return isset($this->map[$permission]);
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMaskBuilder()
+ {
+ return new MaskBuilder();
+ }
}
diff --git a/Acl/Permission/MaskBuilder.php b/Acl/Permission/MaskBuilder.php
index ca25c70..0b5f388 100644
--- a/Acl/Permission/MaskBuilder.php
+++ b/Acl/Permission/MaskBuilder.php
@@ -42,7 +42,7 @@ namespace Symfony\Component\Security\Acl\Permission;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
-class MaskBuilder
+class MaskBuilder extends AbstractMaskBuilder
{
const MASK_VIEW = 1; // 1 << 0
const MASK_CREATE = 2; // 1 << 1
@@ -67,56 +67,6 @@ class MaskBuilder
const OFF = '.';
const ON = '*';
- private $mask;
-
- /**
- * Constructor.
- *
- * @param int $mask optional; defaults to 0
- *
- * @throws \InvalidArgumentException
- */
- public function __construct($mask = 0)
- {
- if (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- $this->mask = $mask;
- }
-
- /**
- * Adds a mask to the permission.
- *
- * @param mixed $mask
- *
- * @return MaskBuilder
- *
- * @throws \InvalidArgumentException
- */
- public function add($mask)
- {
- if (is_string($mask) && defined($name = 'static::MASK_'.strtoupper($mask))) {
- $mask = constant($name);
- } elseif (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- $this->mask |= $mask;
-
- return $this;
- }
-
- /**
- * Returns the mask of this permission.
- *
- * @return int
- */
- public function get()
- {
- return $this->mask;
- }
-
/**
* Returns a human-readable representation of the permission.
*
@@ -142,40 +92,6 @@ class MaskBuilder
}
/**
- * Removes a mask from the permission.
- *
- * @param mixed $mask
- *
- * @return MaskBuilder
- *
- * @throws \InvalidArgumentException
- */
- public function remove($mask)
- {
- if (is_string($mask) && defined($name = 'static::MASK_'.strtoupper($mask))) {
- $mask = constant($name);
- } elseif (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- $this->mask &= ~$mask;
-
- return $this;
- }
-
- /**
- * Resets the PermissionBuilder.
- *
- * @return MaskBuilder
- */
- public function reset()
- {
- $this->mask = 0;
-
- return $this;
- }
-
- /**
* Returns the code for the passed mask.
*
* @param int $mask
@@ -193,19 +109,43 @@ class MaskBuilder
$reflection = new \ReflectionClass(get_called_class());
foreach ($reflection->getConstants() as $name => $cMask) {
- if (0 !== strpos($name, 'MASK_')) {
+ if (0 !== strpos($name, 'MASK_') || $mask !== $cMask) {
continue;
}
- if ($mask === $cMask) {
- if (!defined($cName = 'static::CODE_'.substr($name, 5))) {
- throw new \RuntimeException('There was no code defined for this mask.');
- }
-
- return constant($cName);
+ if (!defined($cName = 'static::CODE_'.substr($name, 5))) {
+ throw new \RuntimeException('There was no code defined for this mask.');
}
+
+ return constant($cName);
}
throw new \InvalidArgumentException(sprintf('The mask "%d" is not supported.', $mask));
}
+
+ /**
+ * Returns the mask for the passed code.
+ *
+ * @param mixed $code
+ *
+ * @return int
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function resolveMask($code)
+ {
+ if (is_string($code)) {
+ if (!defined($name = sprintf('static::MASK_%s', strtoupper($code)))) {
+ throw new \InvalidArgumentException(sprintf('The code "%s" is not supported', $code));
+ }
+
+ return constant($name);
+ }
+
+ if (!is_int($code)) {
+ throw new \InvalidArgumentException('$code must be an integer.');
+ }
+
+ return $code;
+ }
}
diff --git a/Acl/Permission/MaskBuilderInterface.php b/Acl/Permission/MaskBuilderInterface.php
new file mode 100644
index 0000000..ef183de
--- /dev/null
+++ b/Acl/Permission/MaskBuilderInterface.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Permission;
+
+/**
+ * This is the interface that must be implemented by mask builders.
+ */
+interface MaskBuilderInterface
+{
+ /**
+ * Set the mask of this permission.
+ *
+ * @param int $mask
+ *
+ * @return MaskBuilderInterface
+ *
+ * @throws \InvalidArgumentException if $mask is not an integer
+ */
+ public function set($mask);
+
+ /**
+ * Returns the mask of this permission.
+ *
+ * @return int
+ */
+ public function get();
+
+ /**
+ * Adds a mask to the permission.
+ *
+ * @param mixed $mask
+ *
+ * @return MaskBuilderInterface
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function add($mask);
+
+ /**
+ * Removes a mask from the permission.
+ *
+ * @param mixed $mask
+ *
+ * @return MaskBuilderInterface
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function remove($mask);
+
+ /**
+ * Resets the PermissionBuilder.
+ *
+ * @return MaskBuilderInterface
+ */
+ public function reset();
+
+ /**
+ * Returns the mask for the passed code.
+ *
+ * @param mixed $code
+ *
+ * @return int
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function resolveMask($code);
+}
diff --git a/Acl/Permission/MaskBuilderRetrievalInterface.php b/Acl/Permission/MaskBuilderRetrievalInterface.php
new file mode 100644
index 0000000..2cde262
--- /dev/null
+++ b/Acl/Permission/MaskBuilderRetrievalInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Acl\Permission;
+
+/**
+ * Retrieves the MaskBuilder.
+ */
+interface MaskBuilderRetrievalInterface
+{
+ /**
+ * Returns a new instance of the MaskBuilder used in the permissionMap.
+ *
+ * @return MaskBuilderInterface
+ */
+ public function getMaskBuilder();
+}
diff --git a/Acl/README.md b/Acl/README.md
new file mode 100644
index 0000000..a6048fd
--- /dev/null
+++ b/Acl/README.md
@@ -0,0 +1,16 @@
+Security Component - ACL (Access Control List)
+==============================================
+
+Security provides an infrastructure for sophisticated authorization systems,
+which makes it possible to easily separate the actual authorization logic from
+so called user providers that hold the users credentials. It is inspired by
+the Java Spring framework.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/Acl/Resources/schema/drizzle.sql b/Acl/Resources/schema/drizzle.sql
index 378f114..9398c29 100644
--- a/Acl/Resources/schema/drizzle.sql
+++ b/Acl/Resources/schema/drizzle.sql
@@ -1,12 +1,12 @@
-CREATE TABLE acl_classes (id INT AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY(id), UNIQUE INDEX UNIQ_69DD750638A36066 (class_type))
+CREATE TABLE acl_classes (id INT AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, UNIQUE INDEX UNIQ_69DD750638A36066 (class_type), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_security_identities (id INT AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, PRIMARY KEY(id), UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username))
+CREATE TABLE acl_security_identities (id INT AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_object_identities (id INT AUTO_INCREMENT NOT NULL, parent_object_identity_id INT DEFAULT NULL, class_id INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, PRIMARY KEY(id), UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id))
+CREATE TABLE acl_object_identities (id INT AUTO_INCREMENT NOT NULL, parent_object_identity_id INT DEFAULT NULL, class_id INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id), INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id))
+CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id), PRIMARY KEY(object_identity_id, ancestor_id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_entries (id INT AUTO_INCREMENT NOT NULL, class_id INT NOT NULL, object_identity_id INT DEFAULT NULL, security_identity_id INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order INT NOT NULL, mask INT NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, PRIMARY KEY(id), UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id))
+CREATE TABLE acl_entries (id INT AUTO_INCREMENT NOT NULL, class_id INT NOT NULL, object_identity_id INT DEFAULT NULL, security_identity_id INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order INT NOT NULL, mask INT NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
diff --git a/Acl/Resources/schema/mssql.sql b/Acl/Resources/schema/mssql.sql
index 1b4733c..8126f78 100644
--- a/Acl/Resources/schema/mssql.sql
+++ b/Acl/Resources/schema/mssql.sql
@@ -1,24 +1,24 @@
-CREATE TABLE acl_classes (id INT UNSIGNED IDENTITY NOT NULL, class_type NVARCHAR(200) NOT NULL, PRIMARY KEY (id))
+CREATE TABLE acl_classes (id INT IDENTITY NOT NULL, class_type NVARCHAR(200) NOT NULL, PRIMARY KEY (id))
CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type) WHERE class_type IS NOT NULL
-CREATE TABLE acl_security_identities (id INT UNSIGNED IDENTITY NOT NULL, identifier NVARCHAR(200) NOT NULL, username BIT NOT NULL, PRIMARY KEY (id))
+CREATE TABLE acl_security_identities (id INT IDENTITY NOT NULL, identifier NVARCHAR(200) NOT NULL, username BIT NOT NULL, PRIMARY KEY (id))
CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username) WHERE identifier IS NOT NULL AND username IS NOT NULL
-CREATE TABLE acl_object_identities (id INT UNSIGNED IDENTITY NOT NULL, parent_object_identity_id INT UNSIGNED DEFAULT NULL, class_id INT UNSIGNED NOT NULL, object_identifier NVARCHAR(100) NOT NULL, entries_inheriting BIT NOT NULL, PRIMARY KEY (id))
+CREATE TABLE acl_object_identities (id INT IDENTITY NOT NULL, parent_object_identity_id INT, class_id INT NOT NULL, object_identifier NVARCHAR(100) NOT NULL, entries_inheriting BIT NOT NULL, PRIMARY KEY (id))
CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id) WHERE object_identifier IS NOT NULL AND class_id IS NOT NULL
CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT UNSIGNED NOT NULL, ancestor_id INT UNSIGNED NOT NULL, PRIMARY KEY (object_identity_id, ancestor_id))
+CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, PRIMARY KEY (object_identity_id, ancestor_id))
CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-CREATE TABLE acl_entries (id INT UNSIGNED IDENTITY NOT NULL, class_id INT UNSIGNED NOT NULL, object_identity_id INT UNSIGNED DEFAULT NULL, security_identity_id INT UNSIGNED NOT NULL, field_name NVARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INT NOT NULL, granting BIT NOT NULL, granting_strategy NVARCHAR(30) NOT NULL, audit_success BIT NOT NULL, audit_failure BIT NOT NULL, PRIMARY KEY (id))
+CREATE TABLE acl_entries (id INT IDENTITY NOT NULL, class_id INT NOT NULL, object_identity_id INT, security_identity_id INT NOT NULL, field_name NVARCHAR(50), ace_order SMALLINT NOT NULL, mask INT NOT NULL, granting BIT NOT NULL, granting_strategy NVARCHAR(30) NOT NULL, audit_success BIT NOT NULL, audit_failure BIT NOT NULL, PRIMARY KEY (id))
CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order) WHERE class_id IS NOT NULL AND object_identity_id IS NOT NULL AND field_name IS NOT NULL AND ace_order IS NOT NULL
diff --git a/Acl/Resources/schema/mysql.sql b/Acl/Resources/schema/mysql.sql
index db01e95..1c63f4d 100644
--- a/Acl/Resources/schema/mysql.sql
+++ b/Acl/Resources/schema/mysql.sql
@@ -1,12 +1,12 @@
-CREATE TABLE acl_classes (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, UNIQUE INDEX UNIQ_69DD750638A36066 (class_type), PRIMARY KEY(id)) ENGINE = InnoDB
+CREATE TABLE acl_classes (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, UNIQUE INDEX UNIQ_69DD750638A36066 (class_type), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_security_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username), PRIMARY KEY(id)) ENGINE = InnoDB
+CREATE TABLE acl_security_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_object_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, parent_object_identity_id INT UNSIGNED DEFAULT NULL, class_id INT UNSIGNED NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id), PRIMARY KEY(id)) ENGINE = InnoDB
+CREATE TABLE acl_object_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, parent_object_identity_id INT UNSIGNED DEFAULT NULL, class_id INT UNSIGNED NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT UNSIGNED NOT NULL, ancestor_id INT UNSIGNED NOT NULL, INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id), PRIMARY KEY(object_identity_id, ancestor_id)) ENGINE = InnoDB
+CREATE TABLE acl_object_identity_ancestors (object_identity_id INT UNSIGNED NOT NULL, ancestor_id INT UNSIGNED NOT NULL, INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id), PRIMARY KEY(object_identity_id, ancestor_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-CREATE TABLE acl_entries (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_id INT UNSIGNED NOT NULL, object_identity_id INT UNSIGNED DEFAULT NULL, security_identity_id INT UNSIGNED NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INT NOT NULL, granting TINYINT(1) NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success TINYINT(1) NOT NULL, audit_failure TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id), PRIMARY KEY(id)) ENGINE = InnoDB
+CREATE TABLE acl_entries (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_id INT UNSIGNED NOT NULL, object_identity_id INT UNSIGNED DEFAULT NULL, security_identity_id INT UNSIGNED NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INT NOT NULL, granting TINYINT(1) NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success TINYINT(1) NOT NULL, audit_failure TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
diff --git a/Acl/Resources/schema/oracle.sql b/Acl/Resources/schema/oracle.sql
index 9896cf0..94821dc 100644
--- a/Acl/Resources/schema/oracle.sql
+++ b/Acl/Resources/schema/oracle.sql
@@ -5,7 +5,7 @@ DECLARE
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_CLASSES' AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_CLASSES ADD CONSTRAINT ACL_CLASSES_AI_PK PRIMARY KEY (id)';
+ EXECUTE IMMEDIATE 'ALTER TABLE ACL_CLASSES ADD CONSTRAINT ACL_CLASSES_AI_PK PRIMARY KEY (ID)';
END IF;
END;
@@ -19,14 +19,14 @@ DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
- SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
- IF (:NEW.id IS NULL OR :NEW.id = 0) THEN
- SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
+ SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
+ IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
+ SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'ACL_CLASSES_SEQ';
- SELECT :NEW.id INTO last_InsertID FROM DUAL;
+ SELECT :NEW.ID INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ACL_CLASSES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
@@ -42,7 +42,7 @@ DECLARE
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_SECURITY_IDENTITIES' AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_SECURITY_IDENTITIES ADD CONSTRAINT ACL_SECURITY_IDENTITIES_AI_PK PRIMARY KEY (id)';
+ EXECUTE IMMEDIATE 'ALTER TABLE ACL_SECURITY_IDENTITIES ADD CONSTRAINT ACL_SECURITY_IDENTITIES_AI_PK PRIMARY KEY (ID)';
END IF;
END;
@@ -56,14 +56,14 @@ DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
- SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
- IF (:NEW.id IS NULL OR :NEW.id = 0) THEN
- SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
+ SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
+ IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
+ SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'ACL_SECURITY_IDENTITIES_SEQ';
- SELECT :NEW.id INTO last_InsertID FROM DUAL;
+ SELECT :NEW.ID INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
@@ -72,14 +72,14 @@ END;
CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-CREATE TABLE acl_object_identities (id NUMBER(10) NOT NULL, parent_object_identity_id NUMBER(10) DEFAULT NULL, class_id NUMBER(10) NOT NULL, object_identifier VARCHAR2(100) NOT NULL, entries_inheriting NUMBER(1) NOT NULL, PRIMARY KEY(id))
+CREATE TABLE acl_object_identities (id NUMBER(10) NOT NULL, parent_object_identity_id NUMBER(10) DEFAULT NULL NULL, class_id NUMBER(10) NOT NULL, object_identifier VARCHAR2(100) NOT NULL, entries_inheriting NUMBER(1) NOT NULL, PRIMARY KEY(id))
DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_OBJECT_IDENTITIES' AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_OBJECT_IDENTITIES ADD CONSTRAINT ACL_OBJECT_IDENTITIES_AI_PK PRIMARY KEY (id)';
+ EXECUTE IMMEDIATE 'ALTER TABLE ACL_OBJECT_IDENTITIES ADD CONSTRAINT ACL_OBJECT_IDENTITIES_AI_PK PRIMARY KEY (ID)';
END IF;
END;
@@ -93,14 +93,14 @@ DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
- SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
- IF (:NEW.id IS NULL OR :NEW.id = 0) THEN
- SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
+ SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
+ IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
+ SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'ACL_OBJECT_IDENTITIES_SEQ';
- SELECT :NEW.id INTO last_InsertID FROM DUAL;
+ SELECT :NEW.ID INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
@@ -117,14 +117,14 @@ CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_ident
CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-CREATE TABLE acl_entries (id NUMBER(10) NOT NULL, class_id NUMBER(10) NOT NULL, object_identity_id NUMBER(10) DEFAULT NULL, security_identity_id NUMBER(10) NOT NULL, field_name VARCHAR2(50) DEFAULT NULL, ace_order NUMBER(5) NOT NULL, mask NUMBER(10) NOT NULL, granting NUMBER(1) NOT NULL, granting_strategy VARCHAR2(30) NOT NULL, audit_success NUMBER(1) NOT NULL, audit_failure NUMBER(1) NOT NULL, PRIMARY KEY(id))
+CREATE TABLE acl_entries (id NUMBER(10) NOT NULL, class_id NUMBER(10) NOT NULL, object_identity_id NUMBER(10) DEFAULT NULL NULL, security_identity_id NUMBER(10) NOT NULL, field_name VARCHAR2(50) DEFAULT NULL NULL, ace_order NUMBER(5) NOT NULL, mask NUMBER(10) NOT NULL, granting NUMBER(1) NOT NULL, granting_strategy VARCHAR2(30) NOT NULL, audit_success NUMBER(1) NOT NULL, audit_failure NUMBER(1) NOT NULL, PRIMARY KEY(id))
DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_ENTRIES' AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_ENTRIES ADD CONSTRAINT ACL_ENTRIES_AI_PK PRIMARY KEY (id)';
+ EXECUTE IMMEDIATE 'ALTER TABLE ACL_ENTRIES ADD CONSTRAINT ACL_ENTRIES_AI_PK PRIMARY KEY (ID)';
END IF;
END;
@@ -138,14 +138,14 @@ DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
- SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
- IF (:NEW.id IS NULL OR :NEW.id = 0) THEN
- SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
+ SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
+ IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
+ SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'ACL_ENTRIES_SEQ';
- SELECT :NEW.id INTO last_InsertID FROM DUAL;
+ SELECT :NEW.ID INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
diff --git a/Acl/Resources/schema/sqlanywhere.sql b/Acl/Resources/schema/sqlanywhere.sql
new file mode 100644
index 0000000..d73b102
--- /dev/null
+++ b/Acl/Resources/schema/sqlanywhere.sql
@@ -0,0 +1,43 @@
+CREATE TABLE acl_classes (id UNSIGNED INT IDENTITY NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY (id))
+
+CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
+
+CREATE TABLE acl_security_identities (id UNSIGNED INT IDENTITY NOT NULL, identifier VARCHAR(200) NOT NULL, username BIT NOT NULL, PRIMARY KEY (id))
+
+CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
+
+CREATE TABLE acl_object_identities (id UNSIGNED INT IDENTITY NOT NULL, parent_object_identity_id UNSIGNED INT DEFAULT NULL, class_id UNSIGNED INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BIT NOT NULL, PRIMARY KEY (id))
+
+CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
+
+CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
+
+CREATE TABLE acl_object_identity_ancestors (object_identity_id UNSIGNED INT NOT NULL, ancestor_id UNSIGNED INT NOT NULL, PRIMARY KEY (object_identity_id, ancestor_id))
+
+CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
+
+CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
+
+CREATE TABLE acl_entries (id UNSIGNED INT IDENTITY NOT NULL, class_id UNSIGNED INT NOT NULL, object_identity_id UNSIGNED INT DEFAULT NULL, security_identity_id UNSIGNED INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order UNSIGNED SMALLINT NOT NULL, mask INT NOT NULL, granting BIT NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BIT NOT NULL, audit_failure BIT NOT NULL, PRIMARY KEY (id))
+
+CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
+
+CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
+
+CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
+
+CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
+
+CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
+
+ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
+
+ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
+
+ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
+
+ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
+
+ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
+
+ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/sqlite.sql b/Acl/Resources/schema/sqlite.sql
index 21c9f67..4429bfa 100644
--- a/Acl/Resources/schema/sqlite.sql
+++ b/Acl/Resources/schema/sqlite.sql
@@ -1,24 +1,24 @@
-CREATE TABLE acl_classes (id INTEGER NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY("id"))
+CREATE TABLE acl_classes (id INTEGER NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY(id))
CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-CREATE TABLE acl_security_identities (id INTEGER NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, PRIMARY KEY("id"))
+CREATE TABLE acl_security_identities (id INTEGER NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, PRIMARY KEY(id))
CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-CREATE TABLE acl_object_identities (id INTEGER NOT NULL, parent_object_identity_id INTEGER DEFAULT NULL, class_id INTEGER NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, PRIMARY KEY("id"))
+CREATE TABLE acl_object_identities (id INTEGER NOT NULL, parent_object_identity_id INTEGER UNSIGNED DEFAULT NULL, class_id INTEGER UNSIGNED NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id) NOT DEFERRABLE INITIALLY IMMEDIATE)
CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INTEGER NOT NULL, ancestor_id INTEGER NOT NULL, PRIMARY KEY("object_identity_id", "ancestor_id"))
+CREATE TABLE acl_object_identity_ancestors (object_identity_id INTEGER UNSIGNED NOT NULL, ancestor_id INTEGER UNSIGNED NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id), CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)
CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-CREATE TABLE acl_entries (id INTEGER NOT NULL, class_id INTEGER NOT NULL, object_identity_id INTEGER DEFAULT NULL, security_identity_id INTEGER NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order INTEGER NOT NULL, mask INTEGER NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, PRIMARY KEY("id"))
+CREATE TABLE acl_entries (id INTEGER NOT NULL, class_id INTEGER UNSIGNED NOT NULL, object_identity_id INTEGER UNSIGNED DEFAULT NULL, security_identity_id INTEGER UNSIGNED NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INTEGER NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)
CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
diff --git a/Tests/Acl/Dbal/AclProviderBenchmarkTest.php b/Acl/Tests/Dbal/AclProviderBenchmarkTest.php
index 0c35475..c95b474 100644
--- a/Tests/Acl/Dbal/AclProviderBenchmarkTest.php
+++ b/Acl/Tests/Dbal/AclProviderBenchmarkTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Dbal;
+namespace Symfony\Component\Security\Acl\Tests\Dbal;
use Symfony\Component\Security\Acl\Dbal\AclProvider;
use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
diff --git a/Tests/Acl/Dbal/AclProviderTest.php b/Acl/Tests/Dbal/AclProviderTest.php
index afbcb56..680c6c3 100644
--- a/Tests/Acl/Dbal/AclProviderTest.php
+++ b/Acl/Tests/Dbal/AclProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Dbal;
+namespace Symfony\Component\Security\Acl\Tests\Dbal;
use Symfony\Component\Security\Acl\Dbal\AclProvider;
use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
diff --git a/Tests/Acl/Dbal/MutableAclProviderTest.php b/Acl/Tests/Dbal/MutableAclProviderTest.php
index 3213406..c2169e4 100644
--- a/Tests/Acl/Dbal/MutableAclProviderTest.php
+++ b/Acl/Tests/Dbal/MutableAclProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Dbal;
+namespace Symfony\Component\Security\Acl\Tests\Dbal;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Model\FieldEntryInterface;
@@ -413,6 +413,36 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
$provider->updateAcl($acl);
}
+ public function testUpdateUserSecurityIdentity()
+ {
+ $provider = $this->getProvider();
+ $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
+ $sid = new UserSecurityIdentity('johannes', 'FooClass');
+ $acl->setEntriesInheriting(!$acl->isEntriesInheriting());
+
+ $acl->insertObjectAce($sid, 1);
+ $acl->insertClassAce($sid, 5, 0, false);
+ $acl->insertObjectAce($sid, 2, 1, true);
+ $acl->insertClassFieldAce('field', $sid, 2, 0, true);
+ $provider->updateAcl($acl);
+
+ $newSid = new UserSecurityIdentity('mathieu', 'FooClass');
+ $provider->updateUserSecurityIdentity($newSid, 'johannes');
+
+ $reloadProvider = $this->getProvider();
+ $reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
+
+ $this->assertNotSame($acl, $reloadedAcl);
+ $this->assertSame($acl->isEntriesInheriting(), $reloadedAcl->isEntriesInheriting());
+
+ $aces = $acl->getObjectAces();
+ $reloadedAces = $reloadedAcl->getObjectAces();
+ $this->assertEquals(count($aces), count($reloadedAces));
+ foreach ($reloadedAces as $ace) {
+ $this->assertTrue($ace->getSecurityIdentity()->equals($newSid));
+ }
+ }
+
/**
* Imports acls.
*
diff --git a/Tests/Acl/Domain/AclTest.php b/Acl/Tests/Domain/AclTest.php
index 9be4a94..84b9ba9 100644
--- a/Tests/Acl/Domain/AclTest.php
+++ b/Acl/Tests/Domain/AclTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
diff --git a/Tests/Acl/Domain/AuditLoggerTest.php b/Acl/Tests/Domain/AuditLoggerTest.php
index c8522b4..15538d3 100644
--- a/Tests/Acl/Domain/AuditLoggerTest.php
+++ b/Acl/Tests/Domain/AuditLoggerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
class AuditLoggerTest extends \PHPUnit_Framework_TestCase
{
@@ -26,12 +26,12 @@ class AuditLoggerTest extends \PHPUnit_Framework_TestCase
->expects($this->once())
->method('isAuditSuccess')
->will($this->returnValue($audit))
- ;
+ ;
$ace
->expects($this->never())
->method('isAuditFailure')
- ;
+ ;
} else {
$ace
->expects($this->never())
diff --git a/Tests/Acl/Domain/DoctrineAclCacheTest.php b/Acl/Tests/Domain/DoctrineAclCacheTest.php
index 54f932d..255f7f4 100644
--- a/Tests/Acl/Domain/DoctrineAclCacheTest.php
+++ b/Acl/Tests/Domain/DoctrineAclCacheTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
diff --git a/Tests/Acl/Domain/EntryTest.php b/Acl/Tests/Domain/EntryTest.php
index 966f2f1..ab8e481 100644
--- a/Tests/Acl/Domain/EntryTest.php
+++ b/Acl/Tests/Domain/EntryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\Entry;
diff --git a/Tests/Acl/Domain/FieldEntryTest.php b/Acl/Tests/Domain/FieldEntryTest.php
index 7f0cbc0..735e2e8 100644
--- a/Tests/Acl/Domain/FieldEntryTest.php
+++ b/Acl/Tests/Domain/FieldEntryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\FieldEntry;
diff --git a/Tests/Acl/Domain/ObjectIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
index e89e1ef..59fc3bd 100644
--- a/Tests/Acl/Domain/ObjectIdentityRetrievalStrategyTest.php
+++ b/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy;
diff --git a/Tests/Acl/Domain/ObjectIdentityTest.php b/Acl/Tests/Domain/ObjectIdentityTest.php
index 312f433..770ada7 100644
--- a/Tests/Acl/Domain/ObjectIdentityTest.php
+++ b/Acl/Tests/Domain/ObjectIdentityTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain
+namespace Symfony\Component\Security\Acl\Tests\Domain
{
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Model\DomainObjectInterface;
@@ -27,10 +27,10 @@ namespace Symfony\Component\Security\Tests\Acl\Domain
// Test that constructor never changes passed type, even with proxies
public function testConstructorWithProxy()
{
- $id = new ObjectIdentity('fooid', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject');
+ $id = new ObjectIdentity('fooid', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject');
$this->assertEquals('fooid', $id->getIdentifier());
- $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
public function testFromDomainObjectPrefersInterfaceOverGetId()
@@ -45,14 +45,14 @@ namespace Symfony\Component\Security\Tests\Acl\Domain
{
$id = ObjectIdentity::fromDomainObject(new TestDomainObject());
$this->assertEquals('getId()', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
public function testFromDomainObjectWithProxy()
{
- $id = ObjectIdentity::fromDomainObject(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject());
+ $id = ObjectIdentity::fromDomainObject(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject());
$this->assertEquals('getId()', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
public function testFromDomainObjectWithoutInterfaceEnforcesStringIdentifier()
@@ -62,7 +62,7 @@ namespace Symfony\Component\Security\Tests\Acl\Domain
$id = ObjectIdentity::fromDomainObject($domainObject);
$this->assertSame('1', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
public function testFromDomainObjectWithoutInterfaceAllowsZeroAsIdentifier()
@@ -72,7 +72,7 @@ namespace Symfony\Component\Security\Tests\Acl\Domain
$id = ObjectIdentity::fromDomainObject($domainObject);
$this->assertSame('0', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
/**
@@ -127,9 +127,9 @@ namespace Symfony\Component\Security\Tests\Acl\Domain
}
}
-namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain
+namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain
{
- class TestDomainObject extends \Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject
+ class TestDomainObject extends \Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject
{
}
}
diff --git a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php b/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
index fd33f8d..34ef690 100644
--- a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php
+++ b/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
diff --git a/Tests/Acl/Domain/RoleSecurityIdentityTest.php b/Acl/Tests/Domain/RoleSecurityIdentityTest.php
index 341f33c..ad5f236 100644
--- a/Tests/Acl/Domain/RoleSecurityIdentityTest.php
+++ b/Acl/Tests/Domain/RoleSecurityIdentityTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
index e5fb4ed..160c27c 100644
--- a/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php
+++ b/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
@@ -88,7 +88,7 @@ class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
)),
array(new CustomUserImpl('johannes'), array('ROLE_FOO'), 'fullFledged', array(
- new UserSecurityIdentity('johannes', 'Symfony\Component\Security\Tests\Acl\Domain\CustomUserImpl'),
+ new UserSecurityIdentity('johannes', 'Symfony\Component\Security\Acl\Tests\Domain\CustomUserImpl'),
new RoleSecurityIdentity('ROLE_FOO'),
new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
diff --git a/Tests/Acl/Domain/UserSecurityIdentityTest.php b/Acl/Tests/Domain/UserSecurityIdentityTest.php
index 1d6a3c5..09d3f0d 100644
--- a/Tests/Acl/Domain/UserSecurityIdentityTest.php
+++ b/Acl/Tests/Domain/UserSecurityIdentityTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Domain;
+namespace Symfony\Component\Security\Acl\Tests\Domain;
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
@@ -27,10 +27,10 @@ class UserSecurityIdentityTest extends \PHPUnit_Framework_TestCase
// Test that constructor never changes the type, even for proxies
public function testConstructorWithProxy()
{
- $id = new UserSecurityIdentity('foo', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\Foo');
+ $id = new UserSecurityIdentity('foo', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo');
$this->assertEquals('foo', $id->getUsername());
- $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\Foo', $id->getClass());
+ $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo', $id->getClass());
}
/**
diff --git a/Tests/Acl/Permission/BasicPermissionMapTest.php b/Acl/Tests/Permission/BasicPermissionMapTest.php
index 743634b..2afe588 100644
--- a/Tests/Acl/Permission/BasicPermissionMapTest.php
+++ b/Acl/Tests/Permission/BasicPermissionMapTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Permission;
+namespace Symfony\Component\Security\Acl\Tests\Permission;
use Symfony\Component\Security\Acl\Permission\BasicPermissionMap;
diff --git a/Tests/Acl/Permission/MaskBuilderTest.php b/Acl/Tests/Permission/MaskBuilderTest.php
index de034e3..8245669 100644
--- a/Tests/Acl/Permission/MaskBuilderTest.php
+++ b/Acl/Tests/Permission/MaskBuilderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Permission;
+namespace Symfony\Component\Security\Acl\Tests\Permission;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
diff --git a/Tests/Acl/Voter/AclVoterTest.php b/Acl/Tests/Voter/AclVoterTest.php
index 8544b19..2148135 100644
--- a/Tests/Acl/Voter/AclVoterTest.php
+++ b/Acl/Tests/Voter/AclVoterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Acl\Voter;
+namespace Symfony\Component\Security\Acl\Tests\Voter;
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
use Symfony\Component\Security\Acl\Voter\FieldVote;
diff --git a/Acl/Voter/AclVoter.php b/Acl/Voter/AclVoter.php
index 4a8533a..ec6024a 100644
--- a/Acl/Voter/AclVoter.php
+++ b/Acl/Voter/AclVoter.php
@@ -64,7 +64,7 @@ class AclVoter implements VoterInterface
if (null === $object) {
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
+ $this->logger->debug(sprintf('Object identity unavailable. Voting to %s.', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
}
return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
@@ -79,7 +79,7 @@ class AclVoter implements VoterInterface
$oid = $object;
} elseif (null === $oid = $this->objectIdentityRetrievalStrategy->getObjectIdentity($object)) {
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
+ $this->logger->debug(sprintf('Object identity unavailable. Voting to %s.', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
}
return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
@@ -96,13 +96,13 @@ class AclVoter implements VoterInterface
if (null === $field && $acl->isGranted($masks, $sids, false)) {
if (null !== $this->logger) {
- $this->logger->debug('ACL found, permission granted. Voting to grant access');
+ $this->logger->debug('ACL found, permission granted. Voting to grant access.');
}
return self::ACCESS_GRANTED;
} elseif (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) {
if (null !== $this->logger) {
- $this->logger->debug('ACL found, permission granted. Voting to grant access');
+ $this->logger->debug('ACL found, permission granted. Voting to grant access.');
}
return self::ACCESS_GRANTED;
diff --git a/Acl/composer.json b/Acl/composer.json
new file mode 100644
index 0000000..b292742
--- /dev/null
+++ b/Acl/composer.json
@@ -0,0 +1,44 @@
+{
+ "name": "symfony/security-acl",
+ "type": "library",
+ "description": "Symfony Security Component - ACL (Access Control List)",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/security-core": "~2.4"
+ },
+ "require-dev": {
+ "doctrine/common": "~2.2",
+ "doctrine/dbal": "~2.2",
+ "psr/log": "~1.0"
+ },
+ "suggest": {
+ "symfony/class-loader": "For using the ACL generateSql script",
+ "symfony/finder": "For using the ACL generateSql script",
+ "doctrine/dbal": "For using the built-in ACL implementation"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Security\\Acl\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ }
+}
diff --git a/Acl/phpunit.xml.dist b/Acl/phpunit.xml.dist
new file mode 100644
index 0000000..b1ea047
--- /dev/null
+++ b/Acl/phpunit.xml.dist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Security Component ACL Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92f8073..22eb9cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,32 @@
CHANGELOG
=========
+2.7.0
+-----
+
+ * added LogoutUrlGenerator
+ * added the triggering of the `Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN` in `Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener`
+ * The MaskBuilder logic has been abstracted in the `Symfony\Component\Security\Acl\Permission\AbstractMaskBuilder`
+ and described in the `Symfony\Component\Security\Acl\Permission\MaskBuilderInterface`
+ * added interface `Symfony\Component\Security\Acl\Permission\MaskBuilderRetrievalInterface`
+
+2.6.0
+-----
+
+ * added Symfony\Component\Security\Http\Authentication\AuthenticationUtils
+ * Deprecated the `SecurityContext` class in favor of the `AuthorizationChecker` and `TokenStorage` classes
+
+2.4.0
+-----
+
+ * Translations in the `src/Symfony/Component/Security/Resources/translations/` directory are deprecated, ones in `src/Symfony/Component/Security/Core/Resources/translations/` must be used instead.
+ * The switch user listener now preserves the query string when switching a user
+ * The remember-me cookie hashes now use HMAC, which means that current cookies will be invalidated
+ * added simpler customization options
+ * structured component into three sub-components Acl, Core and Http
+ * added Csrf sub-component
+ * changed Http sub-component to depend on Csrf sub-component instead of the Form component
+
2.3.0
-----
diff --git a/Core/.gitignore b/Core/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/Core/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/Core/Authentication/AuthenticationProviderManager.php b/Core/Authentication/AuthenticationProviderManager.php
index f713e8f..16de8da 100644
--- a/Core/Authentication/AuthenticationProviderManager.php
+++ b/Core/Authentication/AuthenticationProviderManager.php
@@ -48,6 +48,12 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
throw new \InvalidArgumentException('You must at least add one authentication provider.');
}
+ foreach ($providers as $provider) {
+ if (!$provider instanceof AuthenticationProviderInterface) {
+ throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_class($provider)));
+ }
+ }
+
$this->providers = $providers;
$this->eraseCredentials = (bool) $eraseCredentials;
}
diff --git a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
index 87b7114..4f73254 100644
--- a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
+++ b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php
@@ -47,28 +47,28 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn
$this->providerKey = $providerKey;
}
- /**
- * {@inheritdoc}
- */
- public function authenticate(TokenInterface $token)
- {
- if (!$this->supports($token)) {
- return;
- }
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ return;
+ }
- if (!$user = $token->getUser()) {
- throw new BadCredentialsException('No pre-authenticated principal found in request.');
- }
+ if (!$user = $token->getUser()) {
+ throw new BadCredentialsException('No pre-authenticated principal found in request.');
+ }
- $user = $this->userProvider->loadUserByUsername($user);
+ $user = $this->userProvider->loadUserByUsername($user);
- $this->userChecker->checkPostAuth($user);
+ $this->userChecker->checkPostAuth($user);
- $authenticatedToken = new PreAuthenticatedToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
- $authenticatedToken->setAttributes($token->getAttributes());
+ $authenticatedToken = new PreAuthenticatedToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
+ $authenticatedToken->setAttributes($token->getAttributes());
- return $authenticatedToken;
- }
+ return $authenticatedToken;
+ }
/**
* {@inheritdoc}
diff --git a/Core/Authentication/Provider/SimpleAuthenticationProvider.php b/Core/Authentication/Provider/SimpleAuthenticationProvider.php
new file mode 100644
index 0000000..ffbc72c
--- /dev/null
+++ b/Core/Authentication/Provider/SimpleAuthenticationProvider.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication\Provider;
+
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class SimpleAuthenticationProvider implements AuthenticationProviderInterface
+{
+ private $simpleAuthenticator;
+ private $userProvider;
+ private $providerKey;
+
+ public function __construct(SimpleAuthenticatorInterface $simpleAuthenticator, UserProviderInterface $userProvider, $providerKey)
+ {
+ $this->simpleAuthenticator = $simpleAuthenticator;
+ $this->userProvider = $userProvider;
+ $this->providerKey = $providerKey;
+ }
+
+ public function authenticate(TokenInterface $token)
+ {
+ $authToken = $this->simpleAuthenticator->authenticateToken($token, $this->userProvider, $this->providerKey);
+
+ if ($authToken instanceof TokenInterface) {
+ return $authToken;
+ }
+
+ throw new AuthenticationException('Simple authenticator failed to return an authenticated token.');
+ }
+
+ public function supports(TokenInterface $token)
+ {
+ return $this->simpleAuthenticator->supportsToken($token, $this->providerKey);
+ }
+}
diff --git a/Core/Authentication/Provider/UserAuthenticationProvider.php b/Core/Authentication/Provider/UserAuthenticationProvider.php
index a624ccf..2674088 100644
--- a/Core/Authentication/Provider/UserAuthenticationProvider.php
+++ b/Core/Authentication/Provider/UserAuthenticationProvider.php
@@ -70,7 +70,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
$user = $this->retrieveUser($username, $token);
} catch (UsernameNotFoundException $e) {
if ($this->hideUserNotFoundExceptions) {
- throw new BadCredentialsException('Bad credentials', 0, $e);
+ throw new BadCredentialsException('Bad credentials.', 0, $e);
}
$e->setUsername($username);
@@ -87,7 +87,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
$this->userChecker->checkPostAuth($user);
} catch (BadCredentialsException $e) {
if ($this->hideUserNotFoundExceptions) {
- throw new BadCredentialsException('Bad credentials', 0, $e);
+ throw new BadCredentialsException('Bad credentials.', 0, $e);
}
throw $e;
diff --git a/Core/Authentication/SimpleAuthenticatorInterface.php b/Core/Authentication/SimpleAuthenticatorInterface.php
new file mode 100644
index 0000000..868d072
--- /dev/null
+++ b/Core/Authentication/SimpleAuthenticatorInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface SimpleAuthenticatorInterface
+{
+ public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey);
+
+ public function supportsToken(TokenInterface $token, $providerKey);
+}
diff --git a/Core/Authentication/SimpleFormAuthenticatorInterface.php b/Core/Authentication/SimpleFormAuthenticatorInterface.php
new file mode 100644
index 0000000..95ee881
--- /dev/null
+++ b/Core/Authentication/SimpleFormAuthenticatorInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface SimpleFormAuthenticatorInterface extends SimpleAuthenticatorInterface
+{
+ public function createToken(Request $request, $username, $password, $providerKey);
+}
diff --git a/Core/Authentication/SimplePreAuthenticatorInterface.php b/Core/Authentication/SimplePreAuthenticatorInterface.php
new file mode 100644
index 0000000..6164e7d
--- /dev/null
+++ b/Core/Authentication/SimplePreAuthenticatorInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface SimplePreAuthenticatorInterface extends SimpleAuthenticatorInterface
+{
+ public function createToken(Request $request, $providerKey);
+}
diff --git a/Core/Authentication/Token/AbstractToken.php b/Core/Authentication/Token/AbstractToken.php
index b07312f..7538648 100644
--- a/Core/Authentication/Token/AbstractToken.php
+++ b/Core/Authentication/Token/AbstractToken.php
@@ -26,9 +26,9 @@ use Symfony\Component\Security\Core\User\EquatableInterface;
abstract class AbstractToken implements TokenInterface
{
private $user;
- private $roles;
- private $authenticated;
- private $attributes;
+ private $roles = array();
+ private $authenticated = false;
+ private $attributes = array();
/**
* Constructor.
@@ -39,10 +39,6 @@ abstract class AbstractToken implements TokenInterface
*/
public function __construct(array $roles = array())
{
- $this->authenticated = false;
- $this->attributes = array();
-
- $this->roles = array();
foreach ($roles as $role) {
if (is_string($role)) {
$role = new Role($role);
@@ -219,7 +215,7 @@ abstract class AbstractToken implements TokenInterface
}
/**
- * Sets a attribute.
+ * Sets an attribute.
*
* @param string $name The attribute name
* @param mixed $value The attribute value
diff --git a/Core/Authentication/Token/Storage/TokenStorage.php b/Core/Authentication/Token/Storage/TokenStorage.php
new file mode 100644
index 0000000..b493081
--- /dev/null
+++ b/Core/Authentication/Token/Storage/TokenStorage.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication\Token\Storage;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * TokenStorage contains a TokenInterface.
+ *
+ * It gives access to the token representing the current user authentication.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class TokenStorage implements TokenStorageInterface
+{
+ private $token;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getToken()
+ {
+ return $this->token;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setToken(TokenInterface $token = null)
+ {
+ $this->token = $token;
+ }
+}
diff --git a/Core/Authentication/Token/Storage/TokenStorageInterface.php b/Core/Authentication/Token/Storage/TokenStorageInterface.php
new file mode 100644
index 0000000..218d750
--- /dev/null
+++ b/Core/Authentication/Token/Storage/TokenStorageInterface.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authentication\Token\Storage;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * The TokenStorageInterface.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface TokenStorageInterface
+{
+ /**
+ * Returns the current security token.
+ *
+ * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
+ */
+ public function getToken();
+
+ /**
+ * Sets the authentication token.
+ *
+ * @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored
+ */
+ public function setToken(TokenInterface $token = null);
+}
diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php
index 6e5effb..b8b6a77 100644
--- a/Core/Authorization/AccessDecisionManager.php
+++ b/Core/Authorization/AccessDecisionManager.php
@@ -22,6 +22,10 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
*/
class AccessDecisionManager implements AccessDecisionManagerInterface
{
+ const STRATEGY_AFFIRMATIVE = 'affirmative';
+ const STRATEGY_CONSENSUS = 'consensus';
+ const STRATEGY_UNANIMOUS = 'unanimous';
+
private $voters;
private $strategy;
private $allowIfAllAbstainDecisions;
@@ -37,14 +41,19 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*
* @throws \InvalidArgumentException
*/
- public function __construct(array $voters, $strategy = 'affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
+ public function __construct(array $voters, $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
{
if (!$voters) {
throw new \InvalidArgumentException('You must at least add one voter.');
}
+ $strategyMethod = 'decide'.ucfirst($strategy);
+ if (!is_callable(array($this, $strategyMethod))) {
+ throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy));
+ }
+
$this->voters = $voters;
- $this->strategy = 'decide'.ucfirst($strategy);
+ $this->strategy = $strategyMethod;
$this->allowIfAllAbstainDecisions = (bool) $allowIfAllAbstainDecisions;
$this->allowIfEqualGrantedDeniedDecisions = (bool) $allowIfEqualGrantedDeniedDecisions;
}
diff --git a/Core/Authorization/AuthorizationChecker.php b/Core/Authorization/AuthorizationChecker.php
new file mode 100644
index 0000000..23c190c
--- /dev/null
+++ b/Core/Authorization/AuthorizationChecker.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization;
+
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
+
+/**
+ * AuthorizationChecker is the main authorization point of the Security component.
+ *
+ * It gives access to the token representing the current user authentication.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class AuthorizationChecker implements AuthorizationCheckerInterface
+{
+ private $tokenStorage;
+ private $accessDecisionManager;
+ private $authenticationManager;
+ private $alwaysAuthenticate;
+
+ /**
+ * Constructor.
+ *
+ * @param TokenStorageInterface $tokenStorage
+ * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManager instance
+ * @param AccessDecisionManagerInterface $accessDecisionManager An AccessDecisionManager instance
+ * @param bool $alwaysAuthenticate
+ */
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, $alwaysAuthenticate = false)
+ {
+ $this->tokenStorage = $tokenStorage;
+ $this->authenticationManager = $authenticationManager;
+ $this->accessDecisionManager = $accessDecisionManager;
+ $this->alwaysAuthenticate = $alwaysAuthenticate;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token.
+ */
+ final public function isGranted($attributes, $object = null)
+ {
+ if (null === ($token = $this->tokenStorage->getToken())) {
+ throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
+ }
+
+ if ($this->alwaysAuthenticate || !$token->isAuthenticated()) {
+ $this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token));
+ }
+
+ if (!is_array($attributes)) {
+ $attributes = array($attributes);
+ }
+
+ return $this->accessDecisionManager->decide($token, $attributes, $object);
+ }
+}
diff --git a/Core/Authorization/AuthorizationCheckerInterface.php b/Core/Authorization/AuthorizationCheckerInterface.php
new file mode 100644
index 0000000..bd24d6f
--- /dev/null
+++ b/Core/Authorization/AuthorizationCheckerInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization;
+
+/**
+ * The AuthorizationCheckerInterface.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface AuthorizationCheckerInterface
+{
+ /**
+ * Checks if the attributes are granted against the current authentication token and optionally supplied object.
+ *
+ * @param mixed $attributes
+ * @param mixed $object
+ *
+ * @return bool
+ */
+ public function isGranted($attributes, $object = null);
+}
diff --git a/Core/Authorization/ExpressionLanguage.php b/Core/Authorization/ExpressionLanguage.php
new file mode 100644
index 0000000..c2925af
--- /dev/null
+++ b/Core/Authorization/ExpressionLanguage.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization;
+
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
+
+/**
+ * Adds some function to the default ExpressionLanguage.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @see ExpressionLanguageProvider
+ */
+class ExpressionLanguage extends BaseExpressionLanguage
+{
+ public function __construct(ParserCacheInterface $cache = null, array $providers = array())
+ {
+ // prepend the default provider to let users override it easily
+ array_unshift($providers, new ExpressionLanguageProvider());
+
+ parent::__construct($cache, $providers);
+ }
+}
diff --git a/Core/Authorization/ExpressionLanguageProvider.php b/Core/Authorization/ExpressionLanguageProvider.php
new file mode 100644
index 0000000..9293ba7
--- /dev/null
+++ b/Core/Authorization/ExpressionLanguageProvider.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization;
+
+use Symfony\Component\ExpressionLanguage\ExpressionFunction;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * Define some ExpressionLanguage functions.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
+{
+ public function getFunctions()
+ {
+ return array(
+ new ExpressionFunction('is_anonymous', function () {
+ return '$trust_resolver->isAnonymous($token)';
+ }, function (array $variables) {
+ return $variables['trust_resolver']->isAnonymous($variables['token']);
+ }),
+
+ new ExpressionFunction('is_authenticated', function () {
+ return '$token && !$trust_resolver->isAnonymous($token)';
+ }, function (array $variables) {
+ return $variables['token'] && !$variables['trust_resolver']->isAnonymous($variables['token']);
+ }),
+
+ new ExpressionFunction('is_fully_authenticated', function () {
+ return '$trust_resolver->isFullFledged($token)';
+ }, function (array $variables) {
+ return $variables['trust_resolver']->isFullFledged($variables['token']);
+ }),
+
+ new ExpressionFunction('is_remember_me', function () {
+ return '$trust_resolver->isRememberMe($token)';
+ }, function (array $variables) {
+ return $variables['trust_resolver']->isRememberMe($variables['token']);
+ }),
+
+ new ExpressionFunction('has_role', function ($role) {
+ return sprintf('in_array(%s, $roles)', $role);
+ }, function (array $variables, $role) {
+ return in_array($role, $variables['roles']);
+ }),
+ );
+ }
+}
diff --git a/Core/Authorization/Voter/AbstractVoter.php b/Core/Authorization/Voter/AbstractVoter.php
new file mode 100644
index 0000000..efa1562
--- /dev/null
+++ b/Core/Authorization/Voter/AbstractVoter.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization\Voter;
+
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * Abstract Voter implementation that reduces boilerplate code required to create a custom Voter.
+ *
+ * @author Roman Marintšenko <inoryy@gmail.com>
+ */
+abstract class AbstractVoter implements VoterInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsAttribute($attribute)
+ {
+ return in_array($attribute, $this->getSupportedAttributes());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsClass($class)
+ {
+ foreach ($this->getSupportedClasses() as $supportedClass) {
+ if ($supportedClass === $class || is_subclass_of($class, $supportedClass)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Iteratively check all given attributes by calling isGranted.
+ *
+ * This method terminates as soon as it is able to return ACCESS_GRANTED
+ * If at least one attribute is supported, but access not granted, then ACCESS_DENIED is returned
+ * Otherwise it will return ACCESS_ABSTAIN
+ *
+ * @param TokenInterface $token A TokenInterface instance
+ * @param object $object The object to secure
+ * @param array $attributes An array of attributes associated with the method being invoked
+ *
+ * @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
+ */
+ public function vote(TokenInterface $token, $object, array $attributes)
+ {
+ if (!$object || !$this->supportsClass(get_class($object))) {
+ return self::ACCESS_ABSTAIN;
+ }
+
+ // abstain vote by default in case none of the attributes are supported
+ $vote = self::ACCESS_ABSTAIN;
+
+ foreach ($attributes as $attribute) {
+ if (!$this->supportsAttribute($attribute)) {
+ continue;
+ }
+
+ // as soon as at least one attribute is supported, default is to deny access
+ $vote = self::ACCESS_DENIED;
+
+ if ($this->isGranted($attribute, $object, $token->getUser())) {
+ // grant access as soon as at least one voter returns a positive response
+ return self::ACCESS_GRANTED;
+ }
+ }
+
+ return $vote;
+ }
+
+ /**
+ * Return an array of supported classes. This will be called by supportsClass.
+ *
+ * @return array an array of supported classes, i.e. array('Acme\DemoBundle\Model\Product')
+ */
+ abstract protected function getSupportedClasses();
+
+ /**
+ * Return an array of supported attributes. This will be called by supportsAttribute.
+ *
+ * @return array an array of supported attributes, i.e. array('CREATE', 'READ')
+ */
+ abstract protected function getSupportedAttributes();
+
+ /**
+ * Perform a single access check operation on a given attribute, object and (optionally) user
+ * It is safe to assume that $attribute and $object's class pass supportsAttribute/supportsClass
+ * $user can be one of the following:
+ * a UserInterface object (fully authenticated user)
+ * a string (anonymously authenticated user).
+ *
+ * @param string $attribute
+ * @param object $object
+ * @param UserInterface|string $user
+ *
+ * @return bool
+ */
+ abstract protected function isGranted($attribute, $object, $user = null);
+}
diff --git a/Core/Authorization/Voter/ExpressionVoter.php b/Core/Authorization/Voter/ExpressionVoter.php
new file mode 100644
index 0000000..98b8f50
--- /dev/null
+++ b/Core/Authorization/Voter/ExpressionVoter.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization\Voter;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
+use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
+use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+use Symfony\Component\ExpressionLanguage\Expression;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * ExpressionVoter votes based on the evaluation of an expression.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExpressionVoter implements VoterInterface
+{
+ private $expressionLanguage;
+ private $trustResolver;
+ private $roleHierarchy;
+
+ /**
+ * Constructor.
+ *
+ * @param ExpressionLanguage $expressionLanguage
+ * @param AuthenticationTrustResolverInterface $trustResolver
+ * @param RoleHierarchyInterface|null $roleHierarchy
+ */
+ public function __construct(ExpressionLanguage $expressionLanguage, AuthenticationTrustResolverInterface $trustResolver, RoleHierarchyInterface $roleHierarchy = null)
+ {
+ $this->expressionLanguage = $expressionLanguage;
+ $this->trustResolver = $trustResolver;
+ $this->roleHierarchy = $roleHierarchy;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguage->registerProvider($provider);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsAttribute($attribute)
+ {
+ return $attribute instanceof Expression;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsClass($class)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function vote(TokenInterface $token, $object, array $attributes)
+ {
+ $result = VoterInterface::ACCESS_ABSTAIN;
+ $variables = null;
+ foreach ($attributes as $attribute) {
+ if (!$this->supportsAttribute($attribute)) {
+ continue;
+ }
+
+ if (null === $variables) {
+ $variables = $this->getVariables($token, $object);
+ }
+
+ $result = VoterInterface::ACCESS_DENIED;
+ if ($this->expressionLanguage->evaluate($attribute, $variables)) {
+ return VoterInterface::ACCESS_GRANTED;
+ }
+ }
+
+ return $result;
+ }
+
+ private function getVariables(TokenInterface $token, $object)
+ {
+ if (null !== $this->roleHierarchy) {
+ $roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
+ } else {
+ $roles = $token->getRoles();
+ }
+
+ $variables = array(
+ 'token' => $token,
+ 'user' => $token->getUser(),
+ 'object' => $object,
+ 'roles' => array_map(function ($role) { return $role->getRole(); }, $roles),
+ 'trust_resolver' => $this->trustResolver,
+ );
+
+ // this is mainly to propose a better experience when the expression is used
+ // in an access control rule, as the developer does not know that it's going
+ // to be handled by this voter
+ if ($object instanceof Request) {
+ $variables['request'] = $object;
+ }
+
+ return $variables;
+ }
+}
diff --git a/Core/Encoder/EncoderAwareInterface.php b/Core/Encoder/EncoderAwareInterface.php
new file mode 100644
index 0000000..22ae820
--- /dev/null
+++ b/Core/Encoder/EncoderAwareInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Encoder;
+
+/**
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+interface EncoderAwareInterface
+{
+ /**
+ * Gets the name of the encoder used to encode the password.
+ *
+ * If the method returns null, the standard way to retrieve the encoder
+ * will be used instead.
+ *
+ * @return string
+ */
+ public function getEncoderName();
+}
diff --git a/Core/Encoder/EncoderFactory.php b/Core/Encoder/EncoderFactory.php
index 5f6c20c..0568d41 100644
--- a/Core/Encoder/EncoderFactory.php
+++ b/Core/Encoder/EncoderFactory.php
@@ -30,19 +30,32 @@ class EncoderFactory implements EncoderFactoryInterface
*/
public function getEncoder($user)
{
- foreach ($this->encoders as $class => $encoder) {
- if ((is_object($user) && !$user instanceof $class) || (!is_object($user) && !is_subclass_of($user, $class) && $user != $class)) {
- continue;
+ $encoderKey = null;
+
+ if ($user instanceof EncoderAwareInterface && (null !== $encoderName = $user->getEncoderName())) {
+ if (!array_key_exists($encoderName, $this->encoders)) {
+ throw new \RuntimeException(sprintf('The encoder "%s" was not configured.', $encoderName));
}
- if (!$encoder instanceof PasswordEncoderInterface) {
- return $this->encoders[$class] = $this->createEncoder($encoder);
+ $encoderKey = $encoderName;
+ } else {
+ foreach ($this->encoders as $class => $encoder) {
+ if ((is_object($user) && $user instanceof $class) || (!is_object($user) && (is_subclass_of($user, $class) || $user == $class))) {
+ $encoderKey = $class;
+ break;
+ }
}
+ }
+
+ if (null === $encoderKey) {
+ throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user));
+ }
- return $this->encoders[$class];
+ if (!$this->encoders[$encoderKey] instanceof PasswordEncoderInterface) {
+ $this->encoders[$encoderKey] = $this->createEncoder($this->encoders[$encoderKey]);
}
- throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user));
+ return $this->encoders[$encoderKey];
}
/**
diff --git a/Core/Encoder/UserPasswordEncoder.php b/Core/Encoder/UserPasswordEncoder.php
new file mode 100644
index 0000000..b096049
--- /dev/null
+++ b/Core/Encoder/UserPasswordEncoder.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Encoder;
+
+use Symfony\Component\Security\Core\User\UserInterface;
+
+/**
+ * A generic password encoder.
+ *
+ * @author Ariel Ferrandini <arielferrandini@gmail.com>
+ */
+class UserPasswordEncoder implements UserPasswordEncoderInterface
+{
+ /**
+ * @var EncoderFactoryInterface
+ */
+ private $encoderFactory;
+
+ /**
+ * @param EncoderFactoryInterface $encoderFactory The encoder factory
+ */
+ public function __construct(EncoderFactoryInterface $encoderFactory)
+ {
+ $this->encoderFactory = $encoderFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function encodePassword(UserInterface $user, $plainPassword)
+ {
+ $encoder = $this->encoderFactory->getEncoder($user);
+
+ return $encoder->encodePassword($plainPassword, $user->getSalt());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isPasswordValid(UserInterface $user, $raw)
+ {
+ $encoder = $this->encoderFactory->getEncoder($user);
+
+ return $encoder->isPasswordValid($user->getPassword(), $raw, $user->getSalt());
+ }
+}
diff --git a/Core/Encoder/UserPasswordEncoderInterface.php b/Core/Encoder/UserPasswordEncoderInterface.php
new file mode 100644
index 0000000..7861caa
--- /dev/null
+++ b/Core/Encoder/UserPasswordEncoderInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Encoder;
+
+use Symfony\Component\Security\Core\User\UserInterface;
+
+/**
+ * UserPasswordEncoderInterface is the interface for the password encoder service.
+ *
+ * @author Ariel Ferrandini <arielferrandini@gmail.com>
+ */
+interface UserPasswordEncoderInterface
+{
+ /**
+ * Encodes the plain password.
+ *
+ * @param UserInterface $user The user
+ * @param string $plainPassword The password to encode
+ *
+ * @return string The encoded password
+ */
+ public function encodePassword(UserInterface $user, $plainPassword);
+
+ /**
+ * @param UserInterface $user The user
+ * @param string $raw A raw password
+ *
+ * @return bool true if the password is valid, false otherwise
+ */
+ public function isPasswordValid(UserInterface $user, $raw);
+}
diff --git a/Core/Exception/AccessDeniedException.php b/Core/Exception/AccessDeniedException.php
index 7c16afb..736a36b 100644
--- a/Core/Exception/AccessDeniedException.php
+++ b/Core/Exception/AccessDeniedException.php
@@ -18,7 +18,7 @@ namespace Symfony\Component\Security\Core\Exception;
*/
class AccessDeniedException extends \RuntimeException
{
- public function __construct($message = 'Access Denied', \Exception $previous = null)
+ public function __construct($message = 'Access Denied.', \Exception $previous = null)
{
parent::__construct($message, 403, $previous);
}
diff --git a/Core/Exception/ExceptionInterface.php b/Core/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..5000d02
--- /dev/null
+++ b/Core/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Exception;
+
+/**
+ * Base ExceptionInterface for the Security component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/Core/Exception/InvalidArgumentException.php b/Core/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..6f85e95
--- /dev/null
+++ b/Core/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Exception;
+
+/**
+ * Base InvalidArgumentException for the Security component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/Core/Exception/RuntimeException.php b/Core/Exception/RuntimeException.php
new file mode 100644
index 0000000..95edec8
--- /dev/null
+++ b/Core/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Exception;
+
+/**
+ * Base RuntimeException for the Security component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/Core/Exception/UsernameNotFoundException.php b/Core/Exception/UsernameNotFoundException.php
index 11607d3..6979389 100644
--- a/Core/Exception/UsernameNotFoundException.php
+++ b/Core/Exception/UsernameNotFoundException.php
@@ -69,4 +69,12 @@ class UsernameNotFoundException extends AuthenticationException
parent::unserialize($parentData);
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageData()
+ {
+ return array('{{ username }}' => $this->username);
+ }
}
diff --git a/Core/LICENSE b/Core/LICENSE
new file mode 100644
index 0000000..12a7453
--- /dev/null
+++ b/Core/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2016 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Core/README.md b/Core/README.md
new file mode 100644
index 0000000..ede185b
--- /dev/null
+++ b/Core/README.md
@@ -0,0 +1,16 @@
+Security Component - Core
+=========================
+
+Security provides an infrastructure for sophisticated authorization systems,
+which makes it possible to easily separate the actual authorization logic from
+so called user providers that hold the users credentials. It is inspired by
+the Java Spring framework.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/Core/Resources/translations/security.ar.xlf b/Core/Resources/translations/security.ar.xlf
new file mode 100644
index 0000000..fd18ee6
--- /dev/null
+++ b/Core/Resources/translations/security.ar.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>حدث خطأ اثناء الدخول.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>لم استطع العثور على معلومات الدخول.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>لم يكتمل طلب الدخول نتيجه عطل فى النظام.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>معلومات الدخول خاطئة.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>ملفات تعريف الارتباط(cookies) تم استخدامها من قبل شخص اخر.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>ليست لديك الصلاحيات الكافية لهذا الطلب.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>رمز الموقع غير صحيح.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>انتهت صلاحية(digest nonce).</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>لا يوجد معرف للدخول يدعم الرمز المستخدم للدخول.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>لا يوجد صلة بينك و بين الموقع اما انها انتهت او ان متصفحك لا يدعم خاصية ملفات تعريف الارتباط (cookies).</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>لم استطع العثور على الرمز.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>لم استطع العثور على اسم الدخول.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>انتهت صلاحية الحساب.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>انتهت صلاحية معلومات الدخول.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>الحساب موقوف.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>الحساب مغلق.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.az.xlf b/Core/Resources/translations/security.az.xlf
new file mode 100644
index 0000000..a974ed0
--- /dev/null
+++ b/Core/Resources/translations/security.az.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Doğrulama istisnası baş verdi.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Doğrulama məlumatları tapılmadı.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Sistem xətası səbəbilə doğrulama istəyi emal edilə bilmədi.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Yanlış məlumat.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Kuki başqası tərəfindən istifadə edilib.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Resurs istəyi üçün imtiyaz yoxdur.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Yanlış CSRF nişanı.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Dərləmə istifadə müddəti bitib.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Doğrulama nişanını dəstəkləyəcək provayder tapılmadı.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Uyğun seans yoxdur, vaxtı keçib və ya kuki aktiv deyil.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nişan tapılmadı.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>İstifadəçi adı tapılmadı.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Hesabın istifadə müddəti bitib.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Məlumatların istifadə müddəti bitib.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Hesab qeyri-aktiv edilib.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Hesab kilitlənib.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.bg.xlf b/Core/Resources/translations/security.bg.xlf
new file mode 100644
index 0000000..06692ea
--- /dev/null
+++ b/Core/Resources/translations/security.bg.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Грешка при автентикация.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Удостоверението за автентикация не е открито.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Заявката за автентикация не може да бъде обработената поради системна грешка.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Невалидно удостоверение за автентикация.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Това cookie вече се ползва от някой друг.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Нямате права за достъп до този ресурс.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Невалиден CSRF токен.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce е изтекъл.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Не е открит провайдър, който да поддържа този токен за автентикация.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Сесията не е достъпна, или времето за достъп е изтекло, или кукитата не са разрешени.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Токена не е открит.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Потребителското име не е открито.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Акаунта е изтекъл.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Удостоверението за автентикация е изтекло.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Акаунта е деактивиран.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Акаунта е заключен.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.ca.xlf b/Core/Resources/translations/security.ca.xlf
new file mode 100644
index 0000000..7ece260
--- /dev/null
+++ b/Core/Resources/translations/security.ca.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ha succeït un error d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>No s'han trobat les credencials d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La solicitud d'autenticació no s'ha pogut processar per un problema del sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credencials no vàlides.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>La cookie ja ha estat utilitzada per una altra persona.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>No té privilegis per solicitar el recurs.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF no vàlid.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>El vector d'inicialització (digest nonce) ha expirat.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No s'ha trobat un proveïdor d'autenticació que suporti el token d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No hi ha sessió disponible, ha expirat o les cookies no estan habilitades.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No s'ha trobat cap token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>No s'ha trobat el nom d'usuari.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>El compte ha expirat.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Les credencials han expirat.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>El compte està deshabilitat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>El compte està bloquejat.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.cs.xlf b/Core/Resources/translations/security.cs.xlf
new file mode 100644
index 0000000..bd146c6
--- /dev/null
+++ b/Core/Resources/translations/security.cs.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Při ověřování došlo k chybě.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Ověřovací údaje nebyly nalezeny.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Požadavek na ověření nemohl být zpracován kvůli systémové chybě.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neplatné přihlašovací údaje.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie již bylo použité někým jiným.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemáte oprávnění přistupovat k prostředku.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neplatný CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Platnost inicializačního vektoru (digest nonce) vypršela.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Poskytovatel pro ověřovací token nebyl nalezen.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Session není k dispozici, vypršela její platnost, nebo jsou zakázané cookies.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token nebyl nalezen.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Přihlašovací jméno nebylo nalezeno.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Platnost účtu vypršela.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Platnost přihlašovacích údajů vypršela.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Účet je zakázaný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Účet je zablokovaný.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.da.xlf b/Core/Resources/translations/security.da.xlf
new file mode 100644
index 0000000..2ac4150
--- /dev/null
+++ b/Core/Resources/translations/security.da.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>En fejl indtraf ved godkendelse.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Loginoplysninger kan findes.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Godkendelsesanmodning kan ikke behandles på grund af et systemfejl.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ugyldige loginoplysninger.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie er allerede brugt af en anden.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Ingen tilladselese at anvende kilden.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ugyldigt CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen godkendelsesudbyder er fundet til understøttelsen af godkendelsestoken.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen session tilgængelig, sessionen er enten udløbet eller cookies er ikke aktiveret.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kan findes.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Brugernavn kan ikke findes.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Brugerkonto er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Loginoplysninger er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Brugerkonto er deaktiveret.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Brugerkonto er låst.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.de.xlf b/Core/Resources/translations/security.de.xlf
new file mode 100644
index 0000000..e5946ed
--- /dev/null
+++ b/Core/Resources/translations/security.de.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Es ist ein Fehler bei der Authentifikation aufgetreten.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Es konnten keine Zugangsdaten gefunden werden.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Die Authentifikation konnte wegen eines Systemproblems nicht bearbeitet werden.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Fehlerhafte Zugangsdaten.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie wurde bereits von jemand anderem verwendet.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Keine Rechte, um die Ressource anzufragen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ungültiges CSRF-Token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce ist abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Es wurde kein Authentifizierungs-Provider gefunden, der das Authentifizierungs-Token unterstützt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Keine Session verfügbar, entweder ist diese abgelaufen oder Cookies sind nicht aktiviert.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Es wurde kein Token gefunden.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Der Benutzername wurde nicht gefunden.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Der Account ist abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Die Zugangsdaten sind abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Der Account ist deaktiviert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Der Account ist gesperrt.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.el.xlf b/Core/Resources/translations/security.el.xlf
new file mode 100644
index 0000000..07eabe7
--- /dev/null
+++ b/Core/Resources/translations/security.el.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Συνέβη ένα σφάλμα πιστοποίησης.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Τα στοιχεία πιστοποίησης δε βρέθηκαν.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Το αίτημα πιστοποίησης δε μπορεί να επεξεργαστεί λόγω σφάλματος του συστήματος.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Λανθασμένα στοιχεία σύνδεσης.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Το Cookie έχει ήδη χρησιμοποιηθεί από κάποιον άλλο.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Δεν είστε εξουσιοδοτημένος για πρόσβαση στο συγκεκριμένο περιεχόμενο.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Μη έγκυρο CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Το digest nonce έχει λήξει.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Δε βρέθηκε κάποιος πάροχος πιστοποίησης που να υποστηρίζει το token πιστοποίησης.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Δεν υπάρχει ενεργή σύνοδος (session), είτε έχει λήξει ή τα cookies δεν είναι ενεργοποιημένα.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Δεν ήταν δυνατόν να βρεθεί κάποιο token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Το Username δε βρέθηκε.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Ο λογαριασμός έχει λήξει.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Τα στοιχεία σύνδεσης έχουν λήξει.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Ο λογαριασμός είναι απενεργοποιημένος.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Ο λογαριασμός είναι κλειδωμένος.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.en.xlf b/Core/Resources/translations/security.en.xlf
new file mode 100644
index 0000000..3640698
--- /dev/null
+++ b/Core/Resources/translations/security.en.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>An authentication exception occurred.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Authentication credentials could not be found.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Authentication request could not be processed due to a system problem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Invalid credentials.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie has already been used by someone else.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Not privileged to request the resource.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Invalid CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce has expired.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No authentication provider found to support the authentication token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No session available, it either timed out or cookies are not enabled.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No token could be found.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username could not be found.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account has expired.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Credentials have expired.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Account is disabled.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Account is locked.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.es.xlf b/Core/Resources/translations/security.es.xlf
new file mode 100644
index 0000000..00cefbb
--- /dev/null
+++ b/Core/Resources/translations/security.es.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ocurrió un error de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>No se encontraron las credenciales de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La solicitud de autenticación no se pudo procesar debido a un problema del sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciales no válidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>La cookie ya ha sido usada por otra persona.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>No tiene privilegios para solicitar el recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF no válido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>El vector de inicialización (digest nonce) ha expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No se encontró un proveedor de autenticación que soporte el token de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No hay ninguna sesión disponible, ha expirado o las cookies no están habilitados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No se encontró ningún token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>No se encontró el nombre de usuario.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>La cuenta ha expirado.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Las credenciales han expirado.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>La cuenta está deshabilitada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>La cuenta está bloqueada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.fa.xlf b/Core/Resources/translations/security.fa.xlf
new file mode 100644
index 0000000..0b76290
--- /dev/null
+++ b/Core/Resources/translations/security.fa.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>خطایی هنگام تعیین اعتبار اتفاق افتاد.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>شرایط تعیین اعتبار پیدا نشد.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>درخواست تعیین اعتبار به دلیل مشکل سیستم قابل بررسی نیست.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>شرایط نامعتبر.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>کوکی قبلا برای شخص دیگری استفاده شده است.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>دسترسی لازم برای درخواست این منبع را ندارید.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>توکن CSRF معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce منقضی شده است.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>هیچ ارایه کننده تعیین اعتباری برای ساپورت توکن تعیین اعتبار پیدا نشد.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>جلسه‌ای در دسترس نیست. این میتواند یا به دلیل پایان یافتن زمان باشد یا اینکه کوکی ها فعال نیستند.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>هیچ توکنی پیدا نشد.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>نام ‌کاربری پیدا نشد.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>حساب کاربری منقضی شده است.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>پارامترهای تعیین اعتبار منقضی شده‌اند.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>حساب کاربری غیرفعال است.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>حساب کاربری قفل شده است.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.fr.xlf b/Core/Resources/translations/security.fr.xlf
new file mode 100644
index 0000000..5a77c6e
--- /dev/null
+++ b/Core/Resources/translations/security.fr.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Une exception d'authentification s'est produite.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Les identifiants d'authentification n'ont pas pu être trouvés.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La requête d'authentification n'a pas pu être executée à cause d'un problème système.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Identifiants invalides.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Le cookie a déjà été utilisé par quelqu'un d'autre.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Privilèges insuffisants pour accéder à la ressource.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Jeton CSRF invalide.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Le digest nonce a expiré.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Aucun fournisseur d'authentification n'a été trouvé pour supporter le jeton d'authentification.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Aucune session disponible, celle-ci a expiré ou les cookies ne sont pas activés.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Aucun jeton n'a pu être trouvé.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Le nom d'utilisateur n'a pas pu être trouvé.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Le compte a expiré.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Les identifiants ont expiré.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Le compte est désactivé.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Le compte est bloqué.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.gl.xlf b/Core/Resources/translations/security.gl.xlf
new file mode 100644
index 0000000..ed6491f
--- /dev/null
+++ b/Core/Resources/translations/security.gl.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ocorreu un erro de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Non se atoparon as credenciais de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A solicitude de autenticación no puido ser procesada debido a un problema do sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais non válidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>A cookie xa foi empregado por outro usuario.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Non ten privilexios para solicitar o recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF non válido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>O vector de inicialización (digest nonce) expirou.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Non se atopou un provedor de autenticación que soporte o token de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Non hai ningunha sesión dispoñible, expirou ou as cookies non están habilitadas.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Non se atopou ningún token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Non se atopou o nome de usuario.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta expirou.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais expiraron.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>A conta está deshabilitada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta está bloqueada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.he.xlf b/Core/Resources/translations/security.he.xlf
new file mode 100644
index 0000000..3640698
--- /dev/null
+++ b/Core/Resources/translations/security.he.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>An authentication exception occurred.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Authentication credentials could not be found.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Authentication request could not be processed due to a system problem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Invalid credentials.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie has already been used by someone else.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Not privileged to request the resource.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Invalid CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce has expired.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No authentication provider found to support the authentication token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No session available, it either timed out or cookies are not enabled.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No token could be found.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username could not be found.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account has expired.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Credentials have expired.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Account is disabled.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Account is locked.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.hr.xlf b/Core/Resources/translations/security.hr.xlf
new file mode 100644
index 0000000..147b6e3
--- /dev/null
+++ b/Core/Resources/translations/security.hr.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Dogodila se autentifikacijske iznimka.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Autentifikacijski podaci nisu pronađeni.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentifikacijski zahtjev nije moguće provesti uslijed sistemskog problema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neispravni akreditacijski podaci.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie je već netko drugi iskoristio.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemate privilegije zahtijevati resurs.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neispravan CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce je isteko.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nije pronađen autentifikacijski provider koji bi podržao autentifikacijski token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesija nije dostupna, ili je istekla ili cookies nisu omogućeni.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token nije pronađen.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Korisničko ime nije pronađeno.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Račun je isteko.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Akreditacijski podaci su istekli.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Račun je onemogućen.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Račun je zaključan.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.hu.xlf b/Core/Resources/translations/security.hu.xlf
new file mode 100644
index 0000000..7243970
--- /dev/null
+++ b/Core/Resources/translations/security.hu.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Hitelesítési hiba lépett fel.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Nem találhatók hitelesítési információk.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A hitelesítési kérést rendszerhiba miatt nem lehet feldolgozni.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Érvénytelen hitelesítési információk.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Ezt a sütit valaki más már felhasználta.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nem rendelkezik az erőforrás eléréséhez szükséges jogosultsággal.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Érvénytelen CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>A kivonat bélyege (nonce) lejárt.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nem található a hitelesítési tokent támogató hitelesítési szolgáltatás.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Munkamenet nem áll rendelkezésre, túllépte az időkeretet vagy a sütik le vannak tiltva.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nem található token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>A felhasználónév nem található.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A fiók lejárt.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>A hitelesítési információk lejártak.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Felfüggesztett fiók.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Zárolt fiók.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.id.xlf b/Core/Resources/translations/security.id.xlf
new file mode 100644
index 0000000..ab1153b
--- /dev/null
+++ b/Core/Resources/translations/security.id.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Terjadi sebuah pengecualian otentikasi.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Kredensial otentikasi tidak bisa ditemukan.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Permintaan otentikasi tidak bisa diproses karena masalah sistem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Kredensial salah.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie sudah digunakan oleh orang lain.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Tidak berhak untuk meminta sumber daya.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF salah.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce telah berakhir.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Tidak ditemukan penyedia otentikasi untuk mendukung token otentikasi.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Tidak ada sesi yang tersedia, mungkin waktu sudah habis atau cookie tidak diaktifkan</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Tidak ada token yang bisa ditemukan.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username tidak bisa ditemukan.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Akun telah berakhir.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Kredensial telah berakhir.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Akun dinonaktifkan.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Akun terkunci.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.it.xlf b/Core/Resources/translations/security.it.xlf
new file mode 100644
index 0000000..75d81cc
--- /dev/null
+++ b/Core/Resources/translations/security.it.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Si è verificato un errore di autenticazione.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Impossibile trovare le credenziali di autenticazione.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La richiesta di autenticazione non può essere processata a causa di un errore di sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenziali non valide.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Il cookie è già stato usato da qualcun altro.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Non hai i privilegi per richiedere questa risorsa.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF token non valido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Il numero di autenticazione è scaduto.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Non è stato trovato un valido fornitore di autenticazione per supportare il token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Nessuna sessione disponibile, può essere scaduta o i cookie non sono abilitati.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nessun token trovato.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username non trovato.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account scaduto.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Credenziali scadute.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>L'account è disabilitato.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>L'account è bloccato.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.ja.xlf b/Core/Resources/translations/security.ja.xlf
new file mode 100644
index 0000000..6a6b062
--- /dev/null
+++ b/Core/Resources/translations/security.ja.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>認証エラーが発生しました。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>認証資格がありません。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>システムの問題により認証要求を処理できませんでした。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>資格が無効です。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie が別のユーザーで使用されています。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>リソースをリクエストする権限がありません。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF トークンが無効です。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest の nonce 値が期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>認証トークンをサポートする認証プロバイダーが見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>利用可能なセッションがありません。タイムアウトしたか、Cookie が無効になっています。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>トークンが見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>ユーザー名が見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>アカウントが有効期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>資格が有効期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>アカウントが無効です。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>アカウントはロックされています。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.lb.xlf b/Core/Resources/translations/security.lb.xlf
new file mode 100644
index 0000000..3dc76d5
--- /dev/null
+++ b/Core/Resources/translations/security.lb.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" target-language="lb" datatype="plaintext" original="security.en.xlf">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Bei der Authentifikatioun ass e Feeler opgetrueden.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Et konnte keng Zouganksdate fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>D'Ufro fir eng Authentifikatioun konnt wéinst engem Problem vum System net beaarbecht ginn.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ongëlteg Zouganksdaten.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>De Cookie gouf scho vun engem anere benotzt.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Keng Rechter fir d'Ressource unzefroen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ongëltegen CSRF-Token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Den eemolege Schlëssel ass ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Et gouf keen Authentifizéierungs-Provider fonnt deen den Authentifizéierungs-Token ënnerstëtzt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Keng Sëtzung disponibel. Entweder ass se ofgelaf oder Cookies sinn net aktivéiert.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Et konnt keen Token fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>De Benotzernumm konnt net fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Den Account ass ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>D'Zouganksdate sinn ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>De Konto ass deaktivéiert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>De Konto ass gespaart.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.lt.xlf b/Core/Resources/translations/security.lt.xlf
new file mode 100644
index 0000000..da6c332
--- /dev/null
+++ b/Core/Resources/translations/security.lt.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Įvyko autentifikacijos klaida.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Nepavyko rasti autentifikacijos duomneų.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentifikacijos užklausos nepavyko įvykdyti dėl sistemos klaidų.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Klaidingi duomenys.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Slapukas buvo panaudotas kažkam kitam.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Neturite teisių pasiektį resursą.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neteisingas CSRF raktas.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Prieigos kodas yra pasibaigęs.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nerastas autentifikacijos tiekėjas, kuris palaikytų autentifikacijos raktą.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesija yra nepasiekiama, pasibaigė galiojimo laikas arba slapukai yra išjungti.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nepavyko rasti rakto.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Tokio naudotojo vardo nepavyko rasti.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Paskyros galiojimo laikas baigėsi.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Autentifikacijos duomenų galiojimo laikas baigėsi.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Paskyra yra išjungta.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Paskyra yra užblokuota.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.nl.xlf b/Core/Resources/translations/security.nl.xlf
new file mode 100644
index 0000000..8969e9e
--- /dev/null
+++ b/Core/Resources/translations/security.nl.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Er heeft zich een authenticatieprobleem voorgedaan.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Authenticatiegegevens konden niet worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Authenticatieaanvraag kon niet worden verwerkt door een technisch probleem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ongeldige inloggegevens.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie is al door een ander persoon gebruikt.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Onvoldoende rechten om de aanvraag te verwerken.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF-code is ongeldig.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Serverauthenticatiesleutel (digest nonce) is verlopen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Geen authenticatieprovider gevonden die de authenticatietoken ondersteunt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Geen sessie beschikbaar, mogelijk is deze verlopen of cookies zijn uitgeschakeld.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Er kon geen authenticatietoken worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Gebruikersnaam kon niet worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account is verlopen.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Authenticatiegegevens zijn verlopen.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Account is gedeactiveerd.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Account is geblokkeerd.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.no.xlf b/Core/Resources/translations/security.no.xlf
new file mode 100644
index 0000000..3635916
--- /dev/null
+++ b/Core/Resources/translations/security.no.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>En autentiseringsfeil har skjedd.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Påloggingsinformasjonen kunne ikke bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentiserings forespørselen kunne ikke bli prosessert grunnet en system feil.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ugyldig påloggingsinformasjonen.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie har allerede blitt brukt av noen andre.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Ingen tilgang til å be om gitt ressurs.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ugyldig CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce er utløpt.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen autentiserings tilbyder funnet som støtter gitt autentiserings token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen sesjon tilgjengelig, sesjonen er enten utløpt eller cookies ikke skrudd på.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kunne bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Brukernavn kunne ikke bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Brukerkonto har utgått.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Påloggingsinformasjon har utløpt.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Brukerkonto er deaktivert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Brukerkonto er sperret.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.pl.xlf b/Core/Resources/translations/security.pl.xlf
new file mode 100644
index 0000000..8d563d2
--- /dev/null
+++ b/Core/Resources/translations/security.pl.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Wystąpił błąd uwierzytelniania.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Dane uwierzytelniania nie zostały znalezione.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Żądanie uwierzytelniania nie mogło zostać pomyślnie zakończone z powodu problemu z systemem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Nieprawidłowe dane.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>To ciasteczko jest używane przez kogoś innego.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Brak uprawnień dla żądania wskazanego zasobu.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Nieprawidłowy token CSRF.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Kod dostępu wygasł.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nie znaleziono mechanizmu uwierzytelniania zdolnego do obsługi przesłanego tokenu.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Brak danych sesji, sesja wygasła lub ciasteczka nie są włączone.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nie znaleziono tokenu.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Użytkownik o podanej nazwie nie istnieje.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Konto wygasło.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Dane uwierzytelniania wygasły.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Konto jest wyłączone.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Konto jest zablokowane.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.pt_BR.xlf b/Core/Resources/translations/security.pt_BR.xlf
new file mode 100644
index 0000000..61685d9
--- /dev/null
+++ b/Core/Resources/translations/security.pt_BR.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Uma exceção ocorreu durante a autenticação.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>As credenciais de autenticação não foram encontradas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A autenticação não pôde ser concluída devido a um problema no sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais inválidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Este cookie já está em uso.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Não possui privilégios o bastante para requisitar este recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF inválido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nenhum provedor de autenticação encontrado para suportar o token de autenticação.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Nenhuma sessão disponível, ela expirou ou os cookies estão desativados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nenhum token foi encontrado.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Nome de usuário não encontrado.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta está expirada.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais estão expiradas.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Conta desativada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta está travada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.pt_PT.xlf b/Core/Resources/translations/security.pt_PT.xlf
new file mode 100644
index 0000000..f2af13e
--- /dev/null
+++ b/Core/Resources/translations/security.pt_PT.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ocorreu uma excepção durante a autenticação.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>As credenciais de autenticação não foram encontradas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>O pedido de autenticação não foi concluído devido a um problema no sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais inválidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Este cookie já está em uso.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Não possui privilégios para aceder a este recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF inválido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nenhum fornecedor de autenticação encontrado para suportar o token de autenticação.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Não existe sessão disponível, esta expirou ou os cookies estão desativados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>O token não foi encontrado.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Nome de utilizador não encontrado.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta expirou.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais expiraram.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Conta desativada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta está trancada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.ro.xlf b/Core/Resources/translations/security.ro.xlf
new file mode 100644
index 0000000..440f110
--- /dev/null
+++ b/Core/Resources/translations/security.ro.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>A apărut o eroare de autentificare.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Informațiile de autentificare nu au fost găsite.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Sistemul nu a putut procesa cererea de autentificare din cauza unei erori.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Date de autentificare invalide.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookieul este folosit deja de altcineva.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Permisiuni insuficiente pentru resursa cerută.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Tokenul CSRF este invalid.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Tokenul temporar a expirat.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nu a fost găsit nici un agent de autentificare pentru tokenul specificat.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesiunea nu mai este disponibilă, a expirat sau suportul pentru cookieuri nu este activat.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Tokenul nu a putut fi găsit.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Numele de utilizator nu a fost găsit.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Contul a expirat.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Datele de autentificare au expirat.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Contul este dezactivat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Contul este blocat.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.ru.xlf b/Core/Resources/translations/security.ru.xlf
new file mode 100644
index 0000000..1964f95
--- /dev/null
+++ b/Core/Resources/translations/security.ru.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ошибка аутентификации.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Аутентификационные данные не найдены.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Запрос аутентификации не может быть обработан в связи с проблемой в системе.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Недействительные аутентификационные данные.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie уже был использован кем-то другим.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Отсутствуют права на запрос этого ресурса.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Недействительный токен CSRF.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Время действия одноразового ключа дайджеста истекло.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Не найден провайдер аутентификации, поддерживающий токен аутентификации.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Сессия не найдена, ее время истекло, либо cookies не включены.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Токен не найден.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Имя пользователя не найдено.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Время действия учетной записи истекло.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Время действия аутентификационных данных истекло.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Учетная запись отключена.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Учетная запись заблокирована.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.sk.xlf b/Core/Resources/translations/security.sk.xlf
new file mode 100644
index 0000000..e6552a6
--- /dev/null
+++ b/Core/Resources/translations/security.sk.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Pri overovaní došlo k chybe.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Overovacie údaje neboli nájdené.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Požiadavok na overenie nemohol byť spracovaný kvôli systémovej chybe.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neplatné prihlasovacie údaje.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie už bolo použité niekým iným.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemáte oprávnenie pristupovať k prostriedku.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neplatný CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Platnosť inicializačného vektoru (digest nonce) skončila.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Poskytovateľ pre overovací token nebol nájdený.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Session nie je k dispozíci, vypršala jej platnosť, alebo sú zakázané cookies.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token nebol nájdený.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Prihlasovacie meno nebolo nájdené.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Platnosť účtu skončila.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Platnosť prihlasovacích údajov skončila.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Účet je zakázaný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Účet je zablokovaný.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.sl.xlf b/Core/Resources/translations/security.sl.xlf
new file mode 100644
index 0000000..ee70c9a
--- /dev/null
+++ b/Core/Resources/translations/security.sl.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Prišlo je do izjeme pri preverjanju avtentikacije.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Poverilnic za avtentikacijo ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Zahteve za avtentikacijo ni bilo mogoče izvesti zaradi sistemske težave.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neveljavne pravice.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Piškotek je uporabil že nekdo drug.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nimate privilegijev za zahtevani vir.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neveljaven CSRF žeton.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Začasni žeton je potekel.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ponudnika avtentikacije za podporo prijavnega žetona ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Seja ni na voljo, ali je potekla ali pa piškotki niso omogočeni.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Žetona ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Uporabniškega imena ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Račun je potekel.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Poverilnice so potekle.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Račun je onemogočen.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Račun je zaklenjen.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.sr_Cyrl.xlf b/Core/Resources/translations/security.sr_Cyrl.xlf
new file mode 100644
index 0000000..35e4ddf
--- /dev/null
+++ b/Core/Resources/translations/security.sr_Cyrl.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Изузетак при аутентификацији.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Аутентификациони подаци нису пронађени.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Захтев за аутентификацију не може бити обрађен због системских проблема.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Невалидни подаци за аутентификацију.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Колачић је већ искоришћен од стране неког другог.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Немате права приступа овом ресурсу.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Невалидан CSRF токен.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Време криптографског кључа је истекло.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Аутентификациони провајдер за подршку токена није пронађен.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Сесија није доступна, истекла је или су колачићи искључени.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Токен не може бити пронађен.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Корисничко име не може бити пронађено.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Налог је истекао.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Подаци за аутентификацију су истекли.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Налог је онемогућен.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Налог је закључан.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.sr_Latn.xlf b/Core/Resources/translations/security.sr_Latn.xlf
new file mode 100644
index 0000000..ddc4807
--- /dev/null
+++ b/Core/Resources/translations/security.sr_Latn.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Izuzetak pri autentifikaciji.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Autentifikacioni podaci nisu pronađeni.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Zahtev za autentifikaciju ne može biti obrađen zbog sistemskih problema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Nevalidni podaci za autentifikaciju.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Kolačić je već iskorišćen od strane nekog drugog.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemate prava pristupa ovom resursu.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Nevalidan CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Vreme kriptografskog ključa je isteklo.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Autentifikacioni provajder za podršku tokena nije pronađen.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesija nije dostupna, istekla je ili su kolačići isključeni.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token ne može biti pronađen.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Korisničko ime ne može biti pronađeno.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Nalog je istekao.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Podaci za autentifikaciju su istekli.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Nalog je onemogućen.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Nalog je zaključan.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.sv.xlf b/Core/Resources/translations/security.sv.xlf
new file mode 100644
index 0000000..b5f6209
--- /dev/null
+++ b/Core/Resources/translations/security.sv.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Ett autentiseringsfel har inträffat.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Uppgifterna för autentisering kunde inte hittas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentiseringen kunde inte genomföras på grund av systemfel.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Felaktiga uppgifter.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookien har redan använts av någon annan.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Saknar rättigheter för resursen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ogiltig CSRF-token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Förfallen digest nonce.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen leverantör för autentisering hittades för angiven autentiseringstoken.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen session finns tillgänglig, antingen har den förfallit eller är cookies inte aktiverat.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kunde hittas.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Användarnamnet kunde inte hittas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Kontot har förfallit.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Uppgifterna har förfallit.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Kontot är inaktiverat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Kontot är låst.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.th.xlf b/Core/Resources/translations/security.th.xlf
new file mode 100644
index 0000000..a8cb8d5
--- /dev/null
+++ b/Core/Resources/translations/security.th.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>พบความผิดพลาดในการรับรองตัวตน</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>ไม่พบข้อมูลในการรับรองตัวตน (credentials) </target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>คำร้องในการรับรองตัวตนไม่สามารถดำเนินการได้ เนื่องมาจากปัญหาของระบบ</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>ข้อมูลการรับรองตัวตนไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie ถูกใช้งานไปแล้วด้วยผู้อื่น</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>ไม่ได้รับสิทธิ์ให้ใช้งานส่วนนี้ได้</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF token ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce หมดอายุ</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>ไม่พบ authentication provider ที่รองรับสำหรับ authentication token</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>ไม่มี session ที่พร้อมใช้งาน, Session หมดอายุไปแล้วหรือ cookies ไม่ถูกเปิดใช้งาน</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>ไม่พบ token</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>ไม่พบ Username</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>บัญชีหมดอายุไปแล้ว</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>ข้อมูลการระบุตัวตนหมดอายุแล้ว</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>บัญชีถูกระงับแล้ว</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>บัญชีถูกล็อกแล้ว</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.tr.xlf b/Core/Resources/translations/security.tr.xlf
new file mode 100644
index 0000000..68c4421
--- /dev/null
+++ b/Core/Resources/translations/security.tr.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Bir yetkilendirme istisnası oluştu.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Kimlik bilgileri bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Bir sistem hatası nedeniyle yetkilendirme isteği işleme alınamıyor.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Geçersiz kimlik bilgileri.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Çerez bir başkası tarafından zaten kullanılmıştı.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Kaynak talebi için imtiyaz bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Geçersiz CSRF fişi.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Derleme zaman aşımına uğradı.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Yetkilendirme fişini destekleyecek yetkilendirme sağlayıcısı bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Oturum bulunamadı, zaman aşımına uğradı veya çerezler etkin değil.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Fiş bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Kullanıcı adı bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Hesap zaman aşımına uğradı.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Kimlik bilgileri zaman aşımına uğradı.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Hesap engellenmiş.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Hesap kilitlenmiş.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.ua.xlf b/Core/Resources/translations/security.ua.xlf
new file mode 100644
index 0000000..7972121
--- /dev/null
+++ b/Core/Resources/translations/security.ua.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Помилка автентифікації.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Автентифікаційні дані не знайдено.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Запит на автентифікацію не може бути опрацьовано у зв’язку з проблемою в системі.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Невірні автентифікаційні дані.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Хтось інший вже використав цей сookie.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Відсутні права на запит цього ресурсу.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Невірний токен CSRF.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Закінчився термін дії одноразового ключа дайджесту.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Не знайдено провайдера автентифікації, що підтримує токен автентифікаціії.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Сесія недоступна, її час вийшов, або cookies вимкнено.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Токен не знайдено.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Ім’я користувача не знайдено.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Термін дії облікового запису вичерпано.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Термін дії автентифікаційних даних вичерпано.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Обліковий запис відключено.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Обліковий запис заблоковано.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.vi.xlf b/Core/Resources/translations/security.vi.xlf
new file mode 100644
index 0000000..b85a439
--- /dev/null
+++ b/Core/Resources/translations/security.vi.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Có lỗi trong quá trình xác thực.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Thông tin dùng để xác thực không tìm thấy.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Yêu cầu xác thực không thể thực hiện do lỗi của hệ thống.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Thông tin dùng để xác thực không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie đã được dùng bởi người dùng khác.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Không được phép yêu cầu tài nguyên.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Mã CSRF không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Mã dùng một lần đã hết hạn.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Không tìm thấy nhà cung cấp dịch vụ xác thực nào cho mã xác thực mà bạn sử dụng.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Không tìm thấy phiên làm việc. Phiên làm việc hoặc cookie có thể bị tắt.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Không tìm thấy mã token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Không tìm thấy tên người dùng username.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Tài khoản đã hết hạn.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Thông tin xác thực đã hết hạn.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Tài khoản bị tạm ngừng.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Tài khoản bị khóa.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Resources/translations/security.zh_CN.xlf b/Core/Resources/translations/security.zh_CN.xlf
new file mode 100644
index 0000000..2d6affe
--- /dev/null
+++ b/Core/Resources/translations/security.zh_CN.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>身份验证发生异常。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>没有找到身份验证的凭证。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>由于系统故障,身份验证的请求无法被处理。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>无效的凭证。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie 已经被其他人使用。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>没有权限请求此资源。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>无效的 CSRF token 。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>摘要随机串(digest nonce)已过期。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>没有找到支持此 token 的身份验证服务提供方。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Session 不可用。会话超时或没有启用 cookies 。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>找不到 token 。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>找不到用户名。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>帐号已过期。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>凭证已过期。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>帐号已被禁用。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>帐号已被锁定。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Core/Role/RoleHierarchy.php b/Core/Role/RoleHierarchy.php
index 2e7df0e..793007e 100644
--- a/Core/Role/RoleHierarchy.php
+++ b/Core/Role/RoleHierarchy.php
@@ -19,7 +19,7 @@ namespace Symfony\Component\Security\Core\Role;
class RoleHierarchy implements RoleHierarchyInterface
{
private $hierarchy;
- private $map;
+ protected $map;
/**
* Constructor.
@@ -52,7 +52,7 @@ class RoleHierarchy implements RoleHierarchyInterface
return $reachableRoles;
}
- private function buildRoleMap()
+ protected function buildRoleMap()
{
$this->map = array();
foreach ($this->hierarchy as $main => $roles) {
diff --git a/Core/Security.php b/Core/Security.php
new file mode 100644
index 0000000..84cc77d
--- /dev/null
+++ b/Core/Security.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core;
+
+/**
+ * This class holds security information.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class Security
+{
+ const ACCESS_DENIED_ERROR = '_security.403_error';
+ const AUTHENTICATION_ERROR = '_security.last_error';
+ const LAST_USERNAME = '_security.last_username';
+ const MAX_USERNAME_LENGTH = 4096;
+}
diff --git a/Core/SecurityContext.php b/Core/SecurityContext.php
index 0326f1d..027ff49 100644
--- a/Core/SecurityContext.php
+++ b/Core/SecurityContext.php
@@ -11,10 +11,15 @@
namespace Symfony\Component\Security\Core;
-use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
-use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
+@trigger_error('The '.__NAMESPACE__.'\SecurityContext class is deprecated since version 2.6 and will be removed in 3.0. Use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage or Symfony\Component\Security\Core\Authorization\AuthorizationChecker instead.', E_USER_DEPRECATED);
+
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
+use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
+use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
* SecurityContext is the main entry point of the Security component.
@@ -23,63 +28,77 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * @deprecated since version 2.6, to be removed in 3.0.
*/
class SecurityContext implements SecurityContextInterface
{
- private $token;
- private $accessDecisionManager;
- private $authenticationManager;
- private $alwaysAuthenticate;
+ /**
+ * @var TokenStorageInterface
+ */
+ private $tokenStorage;
/**
- * Constructor.
- *
- * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManager instance
- * @param AccessDecisionManagerInterface|null $accessDecisionManager An AccessDecisionManager instance
- * @param bool $alwaysAuthenticate
+ * @var AuthorizationCheckerInterface
*/
- public function __construct(AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, $alwaysAuthenticate = false)
- {
- $this->authenticationManager = $authenticationManager;
- $this->accessDecisionManager = $accessDecisionManager;
- $this->alwaysAuthenticate = $alwaysAuthenticate;
- }
+ private $authorizationChecker;
/**
- * {@inheritdoc}
+ * For backwards compatibility, the signature of sf <2.6 still works.
*
- * @throws AuthenticationCredentialsNotFoundException when the security context has no authentication token.
+ * @param TokenStorageInterface|AuthenticationManagerInterface $tokenStorage
+ * @param AuthorizationCheckerInterface|AccessDecisionManagerInterface $authorizationChecker
+ * @param bool $alwaysAuthenticate only applicable with old signature
*/
- final public function isGranted($attributes, $object = null)
+ public function __construct($tokenStorage, $authorizationChecker, $alwaysAuthenticate = false)
{
- if (null === $this->token) {
- throw new AuthenticationCredentialsNotFoundException('The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
- }
+ $oldSignature = $tokenStorage instanceof AuthenticationManagerInterface && $authorizationChecker instanceof AccessDecisionManagerInterface;
+ $newSignature = $tokenStorage instanceof TokenStorageInterface && $authorizationChecker instanceof AuthorizationCheckerInterface;
- if ($this->alwaysAuthenticate || !$this->token->isAuthenticated()) {
- $this->token = $this->authenticationManager->authenticate($this->token);
+ // confirm possible signatures
+ if (!$oldSignature && !$newSignature) {
+ throw new \BadMethodCallException('Unable to construct SecurityContext, please provide the correct arguments');
}
- if (!is_array($attributes)) {
- $attributes = array($attributes);
+ if ($oldSignature) {
+ // renamed for clarity
+ $authenticationManager = $tokenStorage;
+ $accessDecisionManager = $authorizationChecker;
+ $tokenStorage = new TokenStorage();
+ $authorizationChecker = new AuthorizationChecker($tokenStorage, $authenticationManager, $accessDecisionManager, $alwaysAuthenticate);
}
- return $this->accessDecisionManager->decide($this->token, $attributes, $object);
+ $this->tokenStorage = $tokenStorage;
+ $this->authorizationChecker = $authorizationChecker;
}
/**
+ * @deprecated since version 2.6, to be removed in 3.0. Use TokenStorageInterface::getToken() instead.
+ *
* {@inheritdoc}
*/
public function getToken()
{
- return $this->token;
+ return $this->tokenStorage->getToken();
}
/**
+ * @deprecated since version 2.6, to be removed in 3.0. Use TokenStorageInterface::setToken() instead.
+ *
* {@inheritdoc}
*/
public function setToken(TokenInterface $token = null)
{
- $this->token = $token;
+ return $this->tokenStorage->setToken($token);
+ }
+
+ /**
+ * @deprecated since version 2.6, to be removed in 3.0. Use AuthorizationCheckerInterface::isGranted() instead.
+ *
+ * {@inheritdoc}
+ */
+ public function isGranted($attributes, $object = null)
+ {
+ return $this->authorizationChecker->isGranted($attributes, $object);
}
}
diff --git a/Core/SecurityContextInterface.php b/Core/SecurityContextInterface.php
index 0253a6a..73edd23 100644
--- a/Core/SecurityContextInterface.php
+++ b/Core/SecurityContextInterface.php
@@ -11,41 +11,20 @@
namespace Symfony\Component\Security\Core;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
* The SecurityContextInterface.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * @deprecated since version 2.6, to be removed in 3.0.
*/
-interface SecurityContextInterface
+interface SecurityContextInterface extends TokenStorageInterface, AuthorizationCheckerInterface
{
- const ACCESS_DENIED_ERROR = '_security.403_error';
- const AUTHENTICATION_ERROR = '_security.last_error';
- const LAST_USERNAME = '_security.last_username';
- const MAX_USERNAME_LENGTH = 4096;
-
- /**
- * Returns the current security token.
- *
- * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
- */
- public function getToken();
-
- /**
- * Sets the authentication token.
- *
- * @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored
- */
- public function setToken(TokenInterface $token = null);
-
- /**
- * Checks if the attributes are granted against the current authentication token and optionally supplied object.
- *
- * @param mixed $attributes
- * @param mixed $object
- *
- * @return bool
- */
- public function isGranted($attributes, $object = null);
+ const ACCESS_DENIED_ERROR = Security::ACCESS_DENIED_ERROR;
+ const AUTHENTICATION_ERROR = Security::AUTHENTICATION_ERROR;
+ const LAST_USERNAME = Security::LAST_USERNAME;
+ const MAX_USERNAME_LENGTH = Security::MAX_USERNAME_LENGTH;
}
diff --git a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php
index 32e6cf7..cc8b7c0 100644
--- a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
+++ b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication;
+namespace Symfony\Component\Security\Core\Tests\Authentication;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
@@ -27,6 +27,16 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
new AuthenticationProviderManager(array());
}
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAuthenticateWithProvidersWithIncorrectInterface()
+ {
+ new AuthenticationProviderManager(array(
+ new \stdClass(),
+ ));
+ }
+
public function testAuthenticateWhenNoProviderSupportsToken()
{
$manager = new AuthenticationProviderManager(array(
@@ -129,7 +139,7 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
} elseif (null !== $exception) {
$provider->expects($this->once())
->method('authenticate')
- ->will($this->throwException($this->getMock($exception, null, array(), '', true)))
+ ->will($this->throwException($this->getMock($exception, null, array(), '')))
;
}
diff --git a/Tests/Core/Authentication/AuthenticationTrustResolverTest.php b/Core/Tests/Authentication/AuthenticationTrustResolverTest.php
index e2fc593..3640981 100644
--- a/Tests/Core/Authentication/AuthenticationTrustResolverTest.php
+++ b/Core/Tests/Authentication/AuthenticationTrustResolverTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication;
+namespace Symfony\Component\Security\Core\Tests\Authentication;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
diff --git a/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php
index d0da147..5a189b0 100644
--- a/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider;
diff --git a/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php
index 18e9669..3eedb8e 100644
--- a/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder;
use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider;
diff --git a/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
index 17234b6..5fd7b05 100644
--- a/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\PreAuthenticatedAuthenticationProvider;
use Symfony\Component\Security\Core\Exception\LockedException;
diff --git a/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
index 54fb4ea..a6fff4b 100644
--- a/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider;
use Symfony\Component\Security\Core\Exception\DisabledException;
diff --git a/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php
index 32f5b10..0503054 100644
--- a/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
diff --git a/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php b/Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php
index 1739714..3bdf38c 100644
--- a/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php
+++ b/Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\RememberMe;
+namespace Symfony\Component\Security\Core\Tests\Authentication\RememberMe;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider;
diff --git a/Tests/Core/Authentication/RememberMe/PersistentTokenTest.php b/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php
index 3903591..903c030 100644
--- a/Tests/Core/Authentication/RememberMe/PersistentTokenTest.php
+++ b/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\RememberMe;
+namespace Symfony\Component\Security\Core\Tests\Authentication\RememberMe;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
diff --git a/Tests/Core/Authentication/Token/AbstractTokenTest.php b/Core/Tests/Authentication/Token/AbstractTokenTest.php
index efdad4c..1a786d7 100644
--- a/Tests/Core/Authentication/Token/AbstractTokenTest.php
+++ b/Core/Tests/Authentication/Token/AbstractTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Authentication/Token/AnonymousTokenTest.php b/Core/Tests/Authentication/Token/AnonymousTokenTest.php
index 135397b..b5cf006 100644
--- a/Tests/Core/Authentication/Token/AnonymousTokenTest.php
+++ b/Core/Tests/Authentication/Token/AnonymousTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Authentication/Token/PreAuthenticatedTokenTest.php b/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php
index 59a533a..77d2608 100644
--- a/Tests/Core/Authentication/Token/PreAuthenticatedTokenTest.php
+++ b/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Authentication/Token/RememberMeTokenTest.php b/Core/Tests/Authentication/Token/RememberMeTokenTest.php
index 438c1d9..7449204 100644
--- a/Tests/Core/Authentication/Token/RememberMeTokenTest.php
+++ b/Core/Tests/Authentication/Token/RememberMeTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Core/Tests/Authentication/Token/Storage/TokenStorageTest.php b/Core/Tests/Authentication/Token/Storage/TokenStorageTest.php
new file mode 100644
index 0000000..d06e3f0
--- /dev/null
+++ b/Core/Tests/Authentication/Token/Storage/TokenStorageTest.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token\Storage;
+
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
+
+class TokenStorageTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetSetToken()
+ {
+ $tokenStorage = new TokenStorage();
+ $this->assertNull($tokenStorage->getToken());
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $tokenStorage->setToken($token);
+ $this->assertSame($token, $tokenStorage->getToken());
+ }
+}
diff --git a/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php b/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php
index 67f431f..0297eff 100644
--- a/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php
+++ b/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Authorization/AccessDecisionManagerTest.php b/Core/Tests/Authorization/AccessDecisionManagerTest.php
index 5341baf..7a9ab08 100644
--- a/Tests/Core/Authorization/AccessDecisionManagerTest.php
+++ b/Core/Tests/Authorization/AccessDecisionManagerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authorization;
+namespace Symfony\Component\Security\Core\Tests\Authorization;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
@@ -55,6 +55,14 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
}
/**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetUnsupportedStrategy()
+ {
+ new AccessDecisionManager(array($this->getVoter(VoterInterface::ACCESS_GRANTED)), 'fooBar');
+ }
+
+ /**
* @dataProvider getStrategyTests
*/
public function testStrategies($strategy, $voters, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions, $expected)
@@ -111,34 +119,34 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
{
return array(
// affirmative
- array('affirmative', $this->getVoters(1, 0, 0), false, true, true),
- array('affirmative', $this->getVoters(1, 2, 0), false, true, true),
- array('affirmative', $this->getVoters(0, 1, 0), false, true, false),
- array('affirmative', $this->getVoters(0, 0, 1), false, true, false),
- array('affirmative', $this->getVoters(0, 0, 1), true, true, true),
+ array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(1, 0, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(1, 2, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 1, 0), false, true, false),
+ array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 0, 1), false, true, false),
+ array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 0, 1), true, true, true),
// consensus
- array('consensus', $this->getVoters(1, 0, 0), false, true, true),
- array('consensus', $this->getVoters(1, 2, 0), false, true, false),
- array('consensus', $this->getVoters(2, 1, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(1, 0, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(1, 2, 0), false, true, false),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 1, 0), false, true, true),
- array('consensus', $this->getVoters(0, 0, 1), false, true, false),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(0, 0, 1), false, true, false),
- array('consensus', $this->getVoters(0, 0, 1), true, true, true),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(0, 0, 1), true, true, true),
- array('consensus', $this->getVoters(2, 2, 0), false, true, true),
- array('consensus', $this->getVoters(2, 2, 1), false, true, true),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 1), false, true, true),
- array('consensus', $this->getVoters(2, 2, 0), false, false, false),
- array('consensus', $this->getVoters(2, 2, 1), false, false, false),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 0), false, false, false),
+ array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 1), false, false, false),
// unanimous
- array('unanimous', $this->getVoters(1, 0, 0), false, true, true),
- array('unanimous', $this->getVoters(1, 0, 1), false, true, true),
- array('unanimous', $this->getVoters(1, 1, 0), false, true, false),
+ array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 0, 0), false, true, true),
+ array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 0, 1), false, true, true),
+ array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 1, 0), false, true, false),
- array('unanimous', $this->getVoters(0, 0, 2), false, true, false),
- array('unanimous', $this->getVoters(0, 0, 2), true, true, true),
+ array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(0, 0, 2), false, true, false),
+ array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(0, 0, 2), true, true, true),
);
}
diff --git a/Core/Tests/Authorization/AuthorizationCheckerTest.php b/Core/Tests/Authorization/AuthorizationCheckerTest.php
new file mode 100644
index 0000000..aafc12f
--- /dev/null
+++ b/Core/Tests/Authorization/AuthorizationCheckerTest.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Authorization;
+
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
+use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
+
+class AuthorizationCheckerTest extends \PHPUnit_Framework_TestCase
+{
+ private $authenticationManager;
+ private $accessDecisionManager;
+ private $authorizationChecker;
+ private $tokenStorage;
+
+ protected function setUp()
+ {
+ $this->authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ $this->accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
+ $this->tokenStorage = new TokenStorage();
+
+ $this->authorizationChecker = new AuthorizationChecker(
+ $this->tokenStorage,
+ $this->authenticationManager,
+ $this->accessDecisionManager
+ );
+ }
+
+ public function testVoteAuthenticatesTokenIfNecessary()
+ {
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $this->tokenStorage->setToken($token);
+
+ $newToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+
+ $this->authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->with($this->equalTo($token))
+ ->will($this->returnValue($newToken));
+
+ // default with() isn't a strict check
+ $tokenComparison = function ($value) use ($newToken) {
+ // make sure that the new token is used in "decide()" and not the old one
+ return $value === $newToken;
+ };
+
+ $this->accessDecisionManager
+ ->expects($this->once())
+ ->method('decide')
+ ->with($this->callback($tokenComparison))
+ ->will($this->returnValue(true));
+
+ // first run the token has not been re-authenticated yet, after isGranted is called, it should be equal
+ $this->assertFalse($newToken === $this->tokenStorage->getToken());
+ $this->assertTrue($this->authorizationChecker->isGranted('foo'));
+ $this->assertTrue($newToken === $this->tokenStorage->getToken());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
+ */
+ public function testVoteWithoutAuthenticationToken()
+ {
+ $this->authorizationChecker->isGranted('ROLE_FOO');
+ }
+
+ /**
+ * @dataProvider isGrantedProvider
+ */
+ public function testIsGranted($decide)
+ {
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $token
+ ->expects($this->once())
+ ->method('isAuthenticated')
+ ->will($this->returnValue(true));
+
+ $this->accessDecisionManager
+ ->expects($this->once())
+ ->method('decide')
+ ->will($this->returnValue($decide));
+ $this->tokenStorage->setToken($token);
+ $this->assertTrue($decide === $this->authorizationChecker->isGranted('ROLE_FOO'));
+ }
+
+ public function isGrantedProvider()
+ {
+ return array(array(true), array(false));
+ }
+}
diff --git a/Core/Tests/Authorization/ExpressionLanguageTest.php b/Core/Tests/Authorization/ExpressionLanguageTest.php
new file mode 100644
index 0000000..5b4aca6
--- /dev/null
+++ b/Core/Tests/Authorization/ExpressionLanguageTest.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Authorization;
+
+use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
+use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
+use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
+use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\User\User;
+
+class ExpressionLanguageTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testIsAuthenticated($token, $expression, $result, array $roles = array())
+ {
+ $anonymousTokenClass = 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken';
+ $rememberMeTokenClass = 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken';
+ $expressionLanguage = new ExpressionLanguage();
+ $trustResolver = new AuthenticationTrustResolver($anonymousTokenClass, $rememberMeTokenClass);
+
+ $context = array();
+ $context['trust_resolver'] = $trustResolver;
+ $context['token'] = $token;
+ $context['roles'] = $roles;
+
+ $this->assertEquals($result, $expressionLanguage->evaluate($expression, $context));
+ }
+
+ public function provider()
+ {
+ $roles = array('ROLE_USER', 'ROLE_ADMIN');
+ $user = new User('username', 'password', $roles);
+
+ $noToken = null;
+ $anonymousToken = new AnonymousToken('firewall', 'anon.');
+ $rememberMeToken = new RememberMeToken($user, 'providerkey', 'firewall');
+ $usernamePasswordToken = new UsernamePasswordToken('username', 'password', 'providerkey', $roles);
+
+ return array(
+ array($noToken, 'is_anonymous()', false),
+ array($noToken, 'is_authenticated()', false),
+ array($noToken, 'is_fully_authenticated()', false),
+ array($noToken, 'is_remember_me()', false),
+ array($noToken, "has_role('ROLE_USER')", false),
+
+ array($anonymousToken, 'is_anonymous()', true),
+ array($anonymousToken, 'is_authenticated()', false),
+ array($anonymousToken, 'is_fully_authenticated()', false),
+ array($anonymousToken, 'is_remember_me()', false),
+ array($anonymousToken, "has_role('ROLE_USER')", false),
+
+ array($rememberMeToken, 'is_anonymous()', false),
+ array($rememberMeToken, 'is_authenticated()', true),
+ array($rememberMeToken, 'is_fully_authenticated()', false),
+ array($rememberMeToken, 'is_remember_me()', true),
+ array($rememberMeToken, "has_role('ROLE_FOO')", false, $roles),
+ array($rememberMeToken, "has_role('ROLE_USER')", true, $roles),
+
+ array($usernamePasswordToken, 'is_anonymous()', false),
+ array($usernamePasswordToken, 'is_authenticated()', true),
+ array($usernamePasswordToken, 'is_fully_authenticated()', true),
+ array($usernamePasswordToken, 'is_remember_me()', false),
+ array($usernamePasswordToken, "has_role('ROLE_FOO')", false, $roles),
+ array($usernamePasswordToken, "has_role('ROLE_USER')", true, $roles),
+ );
+ }
+}
diff --git a/Core/Tests/Authorization/Voter/AbstractVoterTest.php b/Core/Tests/Authorization/Voter/AbstractVoterTest.php
new file mode 100644
index 0000000..2ab943b
--- /dev/null
+++ b/Core/Tests/Authorization/Voter/AbstractVoterTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
+
+use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
+use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
+
+class AbstractVoterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $token;
+
+ protected function setUp()
+ {
+ $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ }
+
+ public function getTests()
+ {
+ return array(
+ array(array('EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'),
+ array(array('CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if attribute and class are supported and attribute does not grant access'),
+
+ array(array('DELETE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute is supported and grants access'),
+ array(array('DELETE', 'CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if one attribute is supported and denies access'),
+
+ array(array('CREATE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute grants access'),
+
+ array(array('DELETE'), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attribute is supported'),
+
+ array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, $this, 'ACCESS_ABSTAIN if class is not supported'),
+
+ array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, null, 'ACCESS_ABSTAIN if object is null'),
+
+ array(array(), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attributes were provided'),
+ );
+ }
+
+ /**
+ * @dataProvider getTests
+ */
+ public function testVote(array $attributes, $expectedVote, $object, $message)
+ {
+ $voter = new AbstractVoterTest_Voter();
+
+ $this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
+ }
+}
+
+class AbstractVoterTest_Voter extends AbstractVoter
+{
+ protected function getSupportedClasses()
+ {
+ return array('stdClass');
+ }
+
+ protected function getSupportedAttributes()
+ {
+ return array('EDIT', 'CREATE');
+ }
+
+ protected function isGranted($attribute, $object, $user = null)
+ {
+ return 'EDIT' === $attribute;
+ }
+}
diff --git a/Tests/Core/Authorization/Voter/AuthenticatedVoterTest.php b/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php
index b077712..4679c0f 100644
--- a/Tests/Core/Authorization/Voter/AuthenticatedVoterTest.php
+++ b/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authorization\Voter;
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
diff --git a/Core/Tests/Authorization/Voter/ExpressionVoterTest.php b/Core/Tests/Authorization/Voter/ExpressionVoterTest.php
new file mode 100644
index 0000000..dc8ea79
--- /dev/null
+++ b/Core/Tests/Authorization/Voter/ExpressionVoterTest.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
+
+use Symfony\Component\Security\Core\Authorization\Voter\ExpressionVoter;
+use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
+use Symfony\Component\Security\Core\Role\Role;
+
+class ExpressionVoterTest extends \PHPUnit_Framework_TestCase
+{
+ public function testSupportsAttribute()
+ {
+ $expression = $this->createExpression();
+ $expressionLanguage = $this->getMock('Symfony\Component\Security\Core\Authorization\ExpressionLanguage');
+ $voter = new ExpressionVoter($expressionLanguage, $this->createTrustResolver(), $this->createRoleHierarchy());
+
+ $this->assertTrue($voter->supportsAttribute($expression));
+ }
+
+ /**
+ * @dataProvider getVoteTests
+ */
+ public function testVote($roles, $attributes, $expected, $tokenExpectsGetRoles = true, $expressionLanguageExpectsEvaluate = true)
+ {
+ $voter = new ExpressionVoter($this->createExpressionLanguage($expressionLanguageExpectsEvaluate), $this->createTrustResolver());
+
+ $this->assertSame($expected, $voter->vote($this->getToken($roles, $tokenExpectsGetRoles), null, $attributes));
+ }
+
+ public function getVoteTests()
+ {
+ return array(
+ array(array(), array(), VoterInterface::ACCESS_ABSTAIN, false, false),
+ array(array(), array('FOO'), VoterInterface::ACCESS_ABSTAIN, false, false),
+
+ array(array(), array($this->createExpression()), VoterInterface::ACCESS_DENIED, true, false),
+
+ array(array('ROLE_FOO'), array($this->createExpression(), $this->createExpression()), VoterInterface::ACCESS_GRANTED),
+ array(array('ROLE_BAR', 'ROLE_FOO'), array($this->createExpression()), VoterInterface::ACCESS_GRANTED),
+ );
+ }
+
+ protected function getToken(array $roles, $tokenExpectsGetRoles = true)
+ {
+ foreach ($roles as $i => $role) {
+ $roles[$i] = new Role($role);
+ }
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+
+ if ($tokenExpectsGetRoles) {
+ $token->expects($this->once())
+ ->method('getRoles')
+ ->will($this->returnValue($roles));
+ }
+
+ return $token;
+ }
+
+ protected function createExpressionLanguage($expressionLanguageExpectsEvaluate = true)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Authorization\ExpressionLanguage');
+
+ if ($expressionLanguageExpectsEvaluate) {
+ $mock->expects($this->once())
+ ->method('evaluate')
+ ->will($this->returnValue(true));
+ }
+
+ return $mock;
+ }
+
+ protected function createTrustResolver()
+ {
+ return $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface');
+ }
+
+ protected function createRoleHierarchy()
+ {
+ return $this->getMock('Symfony\Component\Security\Core\Role\RoleHierarchyInterface');
+ }
+
+ protected function createExpression()
+ {
+ return $this->getMockBuilder('Symfony\Component\ExpressionLanguage\Expression')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+}
diff --git a/Tests/Core/Authorization/Voter/RoleHierarchyVoterTest.php b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php
index a50fa79..c50ecf3 100644
--- a/Tests/Core/Authorization/Voter/RoleHierarchyVoterTest.php
+++ b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authorization\Voter;
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\RoleHierarchyVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
diff --git a/Tests/Core/Authorization/Voter/RoleVoterTest.php b/Core/Tests/Authorization/Voter/RoleVoterTest.php
index 8a5cdc5..03ab2da 100644
--- a/Tests/Core/Authorization/Voter/RoleVoterTest.php
+++ b/Core/Tests/Authorization/Voter/RoleVoterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Authorization\Voter;
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
diff --git a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php b/Core/Tests/Encoder/BCryptPasswordEncoderTest.php
index 9894c6f..40de8af 100644
--- a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
+++ b/Core/Tests/Encoder/BCryptPasswordEncoderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
@@ -45,9 +45,6 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
}
}
- /**
- * @requires PHP 5.3.7
- */
public function testResultLength()
{
$encoder = new BCryptPasswordEncoder(self::VALID_COST);
@@ -55,9 +52,6 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(60, strlen($result));
}
- /**
- * @requires PHP 5.3.7
- */
public function testValidation()
{
$encoder = new BCryptPasswordEncoder(self::VALID_COST);
@@ -76,9 +70,6 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
$encoder->encodePassword(str_repeat('a', 73), 'salt');
}
- /**
- * @requires PHP 5.3.7
- */
public function testCheckPasswordLength()
{
$encoder = new BCryptPasswordEncoder(self::VALID_COST);
diff --git a/Tests/Core/Encoder/BasePasswordEncoderTest.php b/Core/Tests/Encoder/BasePasswordEncoderTest.php
index 702efb0..14c488b 100644
--- a/Tests/Core/Encoder/BasePasswordEncoderTest.php
+++ b/Core/Tests/Encoder/BasePasswordEncoderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
diff --git a/Tests/Core/Encoder/EncoderFactoryTest.php b/Core/Tests/Encoder/EncoderFactoryTest.php
index 4fe60ad..21aaae4 100644
--- a/Tests/Core/Encoder/EncoderFactoryTest.php
+++ b/Core/Tests/Encoder/EncoderFactoryTest.php
@@ -9,10 +9,11 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
+use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;
@@ -52,7 +53,7 @@ class EncoderFactoryTest extends \PHPUnit_Framework_TestCase
'Symfony\Component\Security\Core\User\UserInterface' => new MessageDigestPasswordEncoder('sha1'),
));
- $encoder = $factory->getEncoder('Symfony\Component\Security\Tests\Core\Encoder\SomeChildUser');
+ $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\SomeChildUser');
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}
@@ -71,10 +72,63 @@ class EncoderFactoryTest extends \PHPUnit_Framework_TestCase
public function testGetEncoderConfiguredForConcreteClassWithClassName()
{
$factory = new EncoderFactory(array(
- 'Symfony\Component\Security\Tests\Core\Encoder\SomeUser' => new MessageDigestPasswordEncoder('sha1'),
+ 'Symfony\Component\Security\Core\Tests\Encoder\SomeUser' => new MessageDigestPasswordEncoder('sha1'),
));
- $encoder = $factory->getEncoder('Symfony\Component\Security\Tests\Core\Encoder\SomeChildUser');
+ $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\SomeChildUser');
+ $expectedEncoder = new MessageDigestPasswordEncoder('sha1');
+ $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
+ }
+
+ public function testGetNamedEncoderForEncoderAware()
+ {
+ $factory = new EncoderFactory(array(
+ 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha256'),
+ 'encoder_name' => new MessageDigestPasswordEncoder('sha1'),
+ ));
+
+ $encoder = $factory->getEncoder(new EncAwareUser('user', 'pass'));
+ $expectedEncoder = new MessageDigestPasswordEncoder('sha1');
+ $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
+ }
+
+ public function testGetNullNamedEncoderForEncoderAware()
+ {
+ $factory = new EncoderFactory(array(
+ 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
+ 'encoder_name' => new MessageDigestPasswordEncoder('sha256'),
+ ));
+
+ $user = new EncAwareUser('user', 'pass');
+ $user->encoderName = null;
+ $encoder = $factory->getEncoder($user);
+ $expectedEncoder = new MessageDigestPasswordEncoder('sha1');
+ $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testGetInvalidNamedEncoderForEncoderAware()
+ {
+ $factory = new EncoderFactory(array(
+ 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
+ 'encoder_name' => new MessageDigestPasswordEncoder('sha256'),
+ ));
+
+ $user = new EncAwareUser('user', 'pass');
+ $user->encoderName = 'invalid_encoder_name';
+ $encoder = $factory->getEncoder($user);
+ }
+
+ public function testGetEncoderForEncoderAwareWithClassName()
+ {
+ $factory = new EncoderFactory(array(
+ 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
+ 'encoder_name' => new MessageDigestPasswordEncoder('sha256'),
+ ));
+
+ $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser');
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}
@@ -106,3 +160,13 @@ class SomeUser implements UserInterface
class SomeChildUser extends SomeUser
{
}
+
+class EncAwareUser extends SomeUser implements EncoderAwareInterface
+{
+ public $encoderName = 'encoder_name';
+
+ public function getEncoderName()
+ {
+ return $this->encoderName;
+ }
+}
diff --git a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php b/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php
index f37d3bc..5189fff 100644
--- a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php
+++ b/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
diff --git a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php b/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php
index ca16f02..3e9452b 100644
--- a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
+++ b/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder;
diff --git a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php b/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php
index 8b1b888..c7e0d2a 100644
--- a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php
+++ b/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Encoder;
+namespace Symfony\Component\Security\Core\Tests\Encoder;
use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder;
diff --git a/Core/Tests/Encoder/UserPasswordEncoderTest.php b/Core/Tests/Encoder/UserPasswordEncoderTest.php
new file mode 100644
index 0000000..590652d
--- /dev/null
+++ b/Core/Tests/Encoder/UserPasswordEncoderTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Encoder;
+
+use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
+
+class UserPasswordEncoderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testEncodePassword()
+ {
+ $userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $userMock->expects($this->any())
+ ->method('getSalt')
+ ->will($this->returnValue('userSalt'));
+
+ $mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
+ $mockEncoder->expects($this->any())
+ ->method('encodePassword')
+ ->with($this->equalTo('plainPassword'), $this->equalTo('userSalt'))
+ ->will($this->returnValue('encodedPassword'));
+
+ $mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
+ $mockEncoderFactory->expects($this->any())
+ ->method('getEncoder')
+ ->with($this->equalTo($userMock))
+ ->will($this->returnValue($mockEncoder));
+
+ $passwordEncoder = new UserPasswordEncoder($mockEncoderFactory);
+
+ $encoded = $passwordEncoder->encodePassword($userMock, 'plainPassword');
+ $this->assertEquals('encodedPassword', $encoded);
+ }
+
+ public function testIsPasswordValid()
+ {
+ $userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $userMock->expects($this->any())
+ ->method('getSalt')
+ ->will($this->returnValue('userSalt'));
+ $userMock->expects($this->any())
+ ->method('getPassword')
+ ->will($this->returnValue('encodedPassword'));
+
+ $mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
+ $mockEncoder->expects($this->any())
+ ->method('isPasswordValid')
+ ->with($this->equalTo('encodedPassword'), $this->equalTo('plainPassword'), $this->equalTo('userSalt'))
+ ->will($this->returnValue(true));
+
+ $mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
+ $mockEncoderFactory->expects($this->any())
+ ->method('getEncoder')
+ ->with($this->equalTo($userMock))
+ ->will($this->returnValue($mockEncoder));
+
+ $passwordEncoder = new UserPasswordEncoder($mockEncoderFactory);
+
+ $isValid = $passwordEncoder->isPasswordValid($userMock, 'plainPassword');
+ $this->assertTrue($isValid);
+ }
+}
diff --git a/Core/Tests/Exception/UsernameNotFoundExceptionTest.php b/Core/Tests/Exception/UsernameNotFoundExceptionTest.php
new file mode 100644
index 0000000..98ea374
--- /dev/null
+++ b/Core/Tests/Exception/UsernameNotFoundExceptionTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Exception;
+
+use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+
+class UsernameNotFoundExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetMessageData()
+ {
+ $exception = new UsernameNotFoundException('Username could not be found.');
+ $this->assertEquals(array('{{ username }}' => null), $exception->getMessageData());
+ $exception->setUsername('username');
+ $this->assertEquals(array('{{ username }}' => 'username'), $exception->getMessageData());
+ }
+}
diff --git a/Core/Tests/LegacySecurityContextInterfaceTest.php b/Core/Tests/LegacySecurityContextInterfaceTest.php
new file mode 100644
index 0000000..a45ecf9
--- /dev/null
+++ b/Core/Tests/LegacySecurityContextInterfaceTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests;
+
+use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * @group legacy
+ */
+class LegacySecurityContextInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * Test if the BC Layer is working as intended.
+ */
+ public function testConstantSync()
+ {
+ $this->assertSame(Security::ACCESS_DENIED_ERROR, SecurityContextInterface::ACCESS_DENIED_ERROR);
+ $this->assertSame(Security::AUTHENTICATION_ERROR, SecurityContextInterface::AUTHENTICATION_ERROR);
+ $this->assertSame(Security::LAST_USERNAME, SecurityContextInterface::LAST_USERNAME);
+ }
+}
diff --git a/Core/Tests/LegacySecurityContextTest.php b/Core/Tests/LegacySecurityContextTest.php
new file mode 100644
index 0000000..92d7c16
--- /dev/null
+++ b/Core/Tests/LegacySecurityContextTest.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests;
+
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
+use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
+use Symfony\Component\Security\Core\SecurityContext;
+
+/**
+ * @group legacy
+ */
+class LegacySecurityContextTest extends \PHPUnit_Framework_TestCase
+{
+ private $tokenStorage;
+ private $authorizationChecker;
+ private $securityContext;
+
+ protected function setUp()
+ {
+ $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $this->authorizationChecker = $this->getMock('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');
+ $this->securityContext = new SecurityContext($this->tokenStorage, $this->authorizationChecker);
+ }
+
+ public function testGetTokenDelegation()
+ {
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+
+ $this->tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue($token));
+
+ $this->assertTrue($token === $this->securityContext->getToken());
+ }
+
+ public function testSetTokenDelegation()
+ {
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+
+ $this->tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($token);
+
+ $this->securityContext->setToken($token);
+ }
+
+ /**
+ * @dataProvider isGrantedDelegationProvider
+ */
+ public function testIsGrantedDelegation($attributes, $object, $return)
+ {
+ $this->authorizationChecker
+ ->expects($this->once())
+ ->method('isGranted')
+ ->with($attributes, $object)
+ ->will($this->returnValue($return));
+
+ $this->assertEquals($return, $this->securityContext->isGranted($attributes, $object));
+ }
+
+ public function isGrantedDelegationProvider()
+ {
+ return array(
+ array(array(), new \stdClass(), true),
+ array(array('henk'), new \stdClass(), false),
+ array(null, new \stdClass(), false),
+ array('henk', null, true),
+ array(array(1), 'henk', true),
+ );
+ }
+
+ /**
+ * Test dedicated to check if the backwards compatibility is still working.
+ */
+ public function testOldConstructorSignature()
+ {
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ $accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
+ new SecurityContext($authenticationManager, $accessDecisionManager);
+ }
+
+ /**
+ * @dataProvider oldConstructorSignatureFailuresProvider
+ * @expectedException \BadMethodCallException
+ */
+ public function testOldConstructorSignatureFailures($first, $second)
+ {
+ new SecurityContext($first, $second);
+ }
+
+ public function oldConstructorSignatureFailuresProvider()
+ {
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $authorizationChecker = $this->getMock('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ $accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
+
+ return array(
+ array(new \stdClass(), new \stdClass()),
+ array($tokenStorage, $accessDecisionManager),
+ array($accessDecisionManager, $tokenStorage),
+ array($authorizationChecker, $accessDecisionManager),
+ array($accessDecisionManager, $authorizationChecker),
+ array($tokenStorage, $accessDecisionManager),
+ array($authenticationManager, $authorizationChecker),
+ array('henk', 'hans'),
+ array(null, false),
+ array(true, null),
+ );
+ }
+}
diff --git a/Core/Tests/Resources/TranslationFilesTest.php b/Core/Tests/Resources/TranslationFilesTest.php
new file mode 100644
index 0000000..dc38e4a
--- /dev/null
+++ b/Core/Tests/Resources/TranslationFilesTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Resources;
+
+class TranslationFilesTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provideTranslationFiles
+ */
+ public function testTranslationFileIsValid($filePath)
+ {
+ \PHPUnit_Util_XML::loadfile($filePath, false, false, true);
+ }
+
+ public function provideTranslationFiles()
+ {
+ return array_map(
+ function ($filePath) { return (array) $filePath; },
+ glob(dirname(dirname(__DIR__)).'/Resources/translations/*.xlf')
+ );
+ }
+}
diff --git a/Tests/Core/Role/RoleHierarchyTest.php b/Core/Tests/Role/RoleHierarchyTest.php
index a98aed6..df1b6a3 100644
--- a/Tests/Core/Role/RoleHierarchyTest.php
+++ b/Core/Tests/Role/RoleHierarchyTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Role;
+namespace Symfony\Component\Security\Core\Tests\Role;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Role/RoleTest.php b/Core/Tests/Role/RoleTest.php
index e2e7ca8..02be07b 100644
--- a/Tests/Core/Role/RoleTest.php
+++ b/Core/Tests/Role/RoleTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Role;
+namespace Symfony\Component\Security\Core\Tests\Role;
use Symfony\Component\Security\Core\Role\Role;
diff --git a/Tests/Core/Role/SwitchUserRoleTest.php b/Core/Tests/Role/SwitchUserRoleTest.php
index bf9b173..f0ce468 100644
--- a/Tests/Core/Role/SwitchUserRoleTest.php
+++ b/Core/Tests/Role/SwitchUserRoleTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Role;
+namespace Symfony\Component\Security\Core\Tests\Role;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
diff --git a/Tests/Core/User/ChainUserProviderTest.php b/Core/Tests/User/ChainUserProviderTest.php
index 9d38a4c..ab01f47 100644
--- a/Tests/Core/User/ChainUserProviderTest.php
+++ b/Core/Tests/User/ChainUserProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\User;
+namespace Symfony\Component\Security\Core\Tests\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\ChainUserProvider;
diff --git a/Tests/Core/User/InMemoryUserProviderTest.php b/Core/Tests/User/InMemoryUserProviderTest.php
index 266d397..0a1815f 100644
--- a/Tests/Core/User/InMemoryUserProviderTest.php
+++ b/Core/Tests/User/InMemoryUserProviderTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\User;
+namespace Symfony\Component\Security\Core\Tests\User;
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
use Symfony\Component\Security\Core\User\User;
diff --git a/Tests/Core/User/UserCheckerTest.php b/Core/Tests/User/UserCheckerTest.php
index dca6311..ac21781 100644
--- a/Tests/Core/User/UserCheckerTest.php
+++ b/Core/Tests/User/UserCheckerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\User;
+namespace Symfony\Component\Security\Core\Tests\User;
use Symfony\Component\Security\Core\User\UserChecker;
diff --git a/Tests/Core/User/UserTest.php b/Core/Tests/User/UserTest.php
index eb21503..b589b4a 100644
--- a/Tests/Core/User/UserTest.php
+++ b/Core/Tests/User/UserTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\User;
+namespace Symfony\Component\Security\Core\Tests\User;
use Symfony\Component\Security\Core\User\User;
@@ -92,4 +92,10 @@ class UserTest extends \PHPUnit_Framework_TestCase
$user->eraseCredentials();
$this->assertEquals('superpass', $user->getPassword());
}
+
+ public function testToString()
+ {
+ $user = new User('fabien', 'superpass');
+ $this->assertEquals('fabien', (string) $user);
+ }
}
diff --git a/Tests/Core/Util/ClassUtilsTest.php b/Core/Tests/Util/ClassUtilsTest.php
index 8359236..e8f0143 100644
--- a/Tests/Core/Util/ClassUtilsTest.php
+++ b/Core/Tests/Util/ClassUtilsTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Util
+namespace Symfony\Component\Security\Core\Tests\Util
{
use Symfony\Component\Security\Core\Util\ClassUtils;
@@ -22,9 +22,9 @@ namespace Symfony\Component\Security\Tests\Core\Util
array('Symfony\Component\Security\Core\Util\ClassUtils', 'Symfony\Component\Security\Core\Util\ClassUtils'),
array('MyProject\Proxies\__CG__\stdClass', 'stdClass'),
array('MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass', 'stdClass'),
- array('MyProject\Proxies\__CG__\Symfony\Component\Security\Tests\Core\Util\ChildObject', 'Symfony\Component\Security\Tests\Core\Util\ChildObject'),
- array(new TestObject(), 'Symfony\Component\Security\Tests\Core\Util\TestObject'),
- array(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Core\Util\TestObject(), 'Symfony\Component\Security\Tests\Core\Util\TestObject'),
+ array('MyProject\Proxies\__CG__\Symfony\Component\Security\Core\Tests\Util\ChildObject', 'Symfony\Component\Security\Core\Tests\Util\ChildObject'),
+ array(new TestObject(), 'Symfony\Component\Security\Core\Tests\Util\TestObject'),
+ array(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Core\Tests\Util\TestObject(), 'Symfony\Component\Security\Core\Tests\Util\TestObject'),
);
}
@@ -42,9 +42,9 @@ namespace Symfony\Component\Security\Tests\Core\Util
}
}
-namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Core\Util
+namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Core\Tests\Util
{
- class TestObject extends \Symfony\Component\Security\Tests\Core\Util\TestObject
+ class TestObject extends \Symfony\Component\Security\Core\Tests\Util\TestObject
{
}
}
diff --git a/Tests/Core/Util/StringUtilsTest.php b/Core/Tests/Util/StringUtilsTest.php
index 3b18d48..faeaf25 100644
--- a/Tests/Core/Util/StringUtilsTest.php
+++ b/Core/Tests/Util/StringUtilsTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Core\Util;
+namespace Symfony\Component\Security\Core\Tests\Util;
use Symfony\Component\Security\Core\Util\StringUtils;
diff --git a/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorTest.php b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorTest.php
new file mode 100644
index 0000000..8053732
--- /dev/null
+++ b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorTest.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Validator\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyUserPasswordValidatorTest extends UserPasswordValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php
new file mode 100644
index 0000000..047c929
--- /dev/null
+++ b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Tests\Validator\Constraints;
+
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
+use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
+use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
+use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator;
+use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class UserPasswordValidatorTest extends AbstractConstraintValidatorTest
+{
+ const PASSWORD = 's3Cr3t';
+
+ const SALT = '^S4lt$';
+
+ /**
+ * @var TokenStorageInterface
+ */
+ protected $tokenStorage;
+
+ /**
+ * @var PasswordEncoderInterface
+ */
+ protected $encoder;
+
+ /**
+ * @var EncoderFactoryInterface
+ */
+ protected $encoderFactory;
+
+ protected function createValidator()
+ {
+ return new UserPasswordValidator($this->tokenStorage, $this->encoderFactory);
+ }
+
+ protected function setUp()
+ {
+ $user = $this->createUser();
+ $this->tokenStorage = $this->createTokenStorage($user);
+ $this->encoder = $this->createPasswordEncoder();
+ $this->encoderFactory = $this->createEncoderFactory($this->encoder);
+
+ parent::setUp();
+ }
+
+ public function testPasswordIsValid()
+ {
+ $constraint = new UserPassword(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->encoder->expects($this->once())
+ ->method('isPasswordValid')
+ ->with(static::PASSWORD, 'secret', static::SALT)
+ ->will($this->returnValue(true));
+
+ $this->validator->validate('secret', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testPasswordIsNotValid()
+ {
+ $constraint = new UserPassword(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->encoder->expects($this->once())
+ ->method('isPasswordValid')
+ ->with(static::PASSWORD, 'secret', static::SALT)
+ ->will($this->returnValue(false));
+
+ $this->validator->validate('secret', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->assertRaised();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testUserIsNotValid()
+ {
+ $user = $this->getMock('Foo\Bar\User');
+
+ $this->tokenStorage = $this->createTokenStorage($user);
+ $this->validator = $this->createValidator();
+ $this->validator->initialize($this->context);
+
+ $this->validator->validate('secret', new UserPassword());
+ }
+
+ protected function createUser()
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+
+ $mock
+ ->expects($this->any())
+ ->method('getPassword')
+ ->will($this->returnValue(static::PASSWORD))
+ ;
+
+ $mock
+ ->expects($this->any())
+ ->method('getSalt')
+ ->will($this->returnValue(static::SALT))
+ ;
+
+ return $mock;
+ }
+
+ protected function createPasswordEncoder($isPasswordValid = true)
+ {
+ return $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
+ }
+
+ protected function createEncoderFactory($encoder = null)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
+
+ $mock
+ ->expects($this->any())
+ ->method('getEncoder')
+ ->will($this->returnValue($encoder))
+ ;
+
+ return $mock;
+ }
+
+ protected function createTokenStorage($user = null)
+ {
+ $token = $this->createAuthenticationToken($user);
+
+ $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $mock
+ ->expects($this->any())
+ ->method('getToken')
+ ->will($this->returnValue($token))
+ ;
+
+ return $mock;
+ }
+
+ protected function createAuthenticationToken($user = null)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $mock
+ ->expects($this->any())
+ ->method('getUser')
+ ->will($this->returnValue($user))
+ ;
+
+ return $mock;
+ }
+}
diff --git a/Core/User/User.php b/Core/User/User.php
index 86f1acd..bc81f7f 100644
--- a/Core/User/User.php
+++ b/Core/User/User.php
@@ -43,6 +43,11 @@ final class User implements AdvancedUserInterface
$this->roles = $roles;
}
+ public function __toString()
+ {
+ return $this->getUsername();
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/Core/Validator/Constraints/UserPassword.php b/Core/Validator/Constraints/UserPassword.php
index aee4cda..35537b3 100644
--- a/Core/Validator/Constraints/UserPassword.php
+++ b/Core/Validator/Constraints/UserPassword.php
@@ -19,7 +19,7 @@ use Symfony\Component\Validator\Constraint;
*/
class UserPassword extends Constraint
{
- public $message = 'This value should be the user current password.';
+ public $message = 'This value should be the user\'s current password.';
public $service = 'security.validator.user_password';
/**
diff --git a/Core/Validator/Constraints/UserPasswordValidator.php b/Core/Validator/Constraints/UserPasswordValidator.php
index ab455f3..2dc7fee 100644
--- a/Core/Validator/Constraints/UserPasswordValidator.php
+++ b/Core/Validator/Constraints/UserPasswordValidator.php
@@ -12,20 +12,21 @@
namespace Symfony\Component\Security\Core\Validator\Constraints;
use Symfony\Component\Security\Core\User\UserInterface;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class UserPasswordValidator extends ConstraintValidator
{
- private $securityContext;
+ private $tokenStorage;
private $encoderFactory;
- public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory)
+ public function __construct(TokenStorageInterface $tokenStorage, EncoderFactoryInterface $encoderFactory)
{
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->encoderFactory = $encoderFactory;
}
@@ -34,7 +35,11 @@ class UserPasswordValidator extends ConstraintValidator
*/
public function validate($password, Constraint $constraint)
{
- $user = $this->securityContext->getToken()->getUser();
+ if (!$constraint instanceof UserPassword) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword');
+ }
+
+ $user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof UserInterface) {
throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.');
diff --git a/Core/composer.json b/Core/composer.json
new file mode 100644
index 0000000..354c55e
--- /dev/null
+++ b/Core/composer.json
@@ -0,0 +1,49 @@
+{
+ "name": "symfony/security-core",
+ "type": "library",
+ "description": "Symfony Security Component - Core Library",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.9",
+ "paragonie/random_compat": "~1.0"
+ },
+ "require-dev": {
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/expression-language": "~2.6",
+ "symfony/http-foundation": "~2.4",
+ "symfony/validator": "~2.5,>=2.5.9",
+ "psr/log": "~1.0",
+ "ircmaxell/password-compat": "1.0.*"
+ },
+ "suggest": {
+ "symfony/event-dispatcher": "",
+ "symfony/http-foundation": "",
+ "symfony/validator": "For using the user password constraint",
+ "symfony/expression-language": "For using the expression voter",
+ "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Security\\Core\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ }
+}
diff --git a/Core/phpunit.xml.dist b/Core/phpunit.xml.dist
new file mode 100644
index 0000000..2dc341a
--- /dev/null
+++ b/Core/phpunit.xml.dist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Security Component Core Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/Csrf/.gitignore b/Csrf/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/Csrf/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/Csrf/CsrfToken.php b/Csrf/CsrfToken.php
new file mode 100644
index 0000000..9ccaaeb
--- /dev/null
+++ b/Csrf/CsrfToken.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf;
+
+/**
+ * A CSRF token.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CsrfToken
+{
+ /**
+ * @var string
+ */
+ private $id;
+
+ /**
+ * @var string
+ */
+ private $value;
+
+ /**
+ * Constructor.
+ *
+ * @param string $id The token ID
+ * @param string $value The actual token value
+ */
+ public function __construct($id, $value)
+ {
+ $this->id = (string) $id;
+ $this->value = (string) $value;
+ }
+
+ /**
+ * Returns the ID of the CSRF token.
+ *
+ * @return string The token ID
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Returns the value of the CSRF token.
+ *
+ * @return string The token value
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Returns the value of the CSRF token.
+ *
+ * @return string The token value
+ */
+ public function __toString()
+ {
+ return $this->value;
+ }
+}
diff --git a/Csrf/CsrfTokenManager.php b/Csrf/CsrfTokenManager.php
new file mode 100644
index 0000000..e129502
--- /dev/null
+++ b/Csrf/CsrfTokenManager.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf;
+
+use Symfony\Component\Security\Core\Util\StringUtils;
+use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
+use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
+use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
+use Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface;
+
+/**
+ * Default implementation of {@link CsrfTokenManagerInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CsrfTokenManager implements CsrfTokenManagerInterface
+{
+ /**
+ * @var TokenGeneratorInterface
+ */
+ private $generator;
+
+ /**
+ * @var TokenStorageInterface
+ */
+ private $storage;
+
+ /**
+ * Creates a new CSRF provider using PHP's native session storage.
+ *
+ * @param TokenGeneratorInterface|null $generator The token generator
+ * @param TokenStorageInterface|null $storage The storage for storing
+ * generated CSRF tokens
+ */
+ public function __construct(TokenGeneratorInterface $generator = null, TokenStorageInterface $storage = null)
+ {
+ $this->generator = $generator ?: new UriSafeTokenGenerator();
+ $this->storage = $storage ?: new NativeSessionTokenStorage();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getToken($tokenId)
+ {
+ if ($this->storage->hasToken($tokenId)) {
+ $value = $this->storage->getToken($tokenId);
+ } else {
+ $value = $this->generator->generateToken();
+
+ $this->storage->setToken($tokenId, $value);
+ }
+
+ return new CsrfToken($tokenId, $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function refreshToken($tokenId)
+ {
+ $value = $this->generator->generateToken();
+
+ $this->storage->setToken($tokenId, $value);
+
+ return new CsrfToken($tokenId, $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeToken($tokenId)
+ {
+ return $this->storage->removeToken($tokenId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isTokenValid(CsrfToken $token)
+ {
+ if (!$this->storage->hasToken($token->getId())) {
+ return false;
+ }
+
+ return StringUtils::equals($this->storage->getToken($token->getId()), $token->getValue());
+ }
+}
diff --git a/Csrf/CsrfTokenManagerInterface.php b/Csrf/CsrfTokenManagerInterface.php
new file mode 100644
index 0000000..bccabe6
--- /dev/null
+++ b/Csrf/CsrfTokenManagerInterface.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf;
+
+/**
+ * Manages CSRF tokens.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface CsrfTokenManagerInterface
+{
+ /**
+ * Returns a CSRF token for the given ID.
+ *
+ * If previously no token existed for the given ID, a new token is
+ * generated. Otherwise the existing token is returned (with the same value,
+ * not the same instance).
+ *
+ * @param string $tokenId The token ID. You may choose an arbitrary value
+ * for the ID
+ *
+ * @return CsrfToken The CSRF token
+ */
+ public function getToken($tokenId);
+
+ /**
+ * Generates a new token value for the given ID.
+ *
+ * This method will generate a new token for the given token ID, independent
+ * of whether a token value previously existed or not. It can be used to
+ * enforce once-only tokens in environments with high security needs.
+ *
+ * @param string $tokenId The token ID. You may choose an arbitrary value
+ * for the ID
+ *
+ * @return CsrfToken The CSRF token
+ */
+ public function refreshToken($tokenId);
+
+ /**
+ * Invalidates the CSRF token with the given ID, if one exists.
+ *
+ * @param string $tokenId The token ID
+ *
+ * @return string|null Returns the removed token value if one existed, NULL
+ * otherwise
+ */
+ public function removeToken($tokenId);
+
+ /**
+ * Returns whether the given CSRF token is valid.
+ *
+ * @param CsrfToken $token A CSRF token
+ *
+ * @return bool Returns true if the token is valid, false otherwise
+ */
+ public function isTokenValid(CsrfToken $token);
+}
diff --git a/Csrf/Exception/TokenNotFoundException.php b/Csrf/Exception/TokenNotFoundException.php
new file mode 100644
index 0000000..936afde
--- /dev/null
+++ b/Csrf/Exception/TokenNotFoundException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\Exception;
+
+use Symfony\Component\Security\Core\Exception\RuntimeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class TokenNotFoundException extends RuntimeException
+{
+}
diff --git a/Csrf/LICENSE b/Csrf/LICENSE
new file mode 100644
index 0000000..12a7453
--- /dev/null
+++ b/Csrf/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2016 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Csrf/README.md b/Csrf/README.md
new file mode 100644
index 0000000..aff72a0
--- /dev/null
+++ b/Csrf/README.md
@@ -0,0 +1,14 @@
+Security Component - CSRF
+=========================
+
+The Security CSRF (cross-site request forgery) component provides a class
+`CsrfTokenManager` for generating and validating CSRF tokens.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/Csrf/Tests/CsrfTokenManagerTest.php b/Csrf/Tests/CsrfTokenManagerTest.php
new file mode 100644
index 0000000..3112038
--- /dev/null
+++ b/Csrf/Tests/CsrfTokenManagerTest.php
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\Tests;
+
+use Symfony\Component\Security\Csrf\CsrfToken;
+use Symfony\Component\Security\Csrf\CsrfTokenManager;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CsrfTokenManagerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $generator;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $storage;
+
+ /**
+ * @var CsrfTokenManager
+ */
+ private $manager;
+
+ protected function setUp()
+ {
+ $this->generator = $this->getMock('Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface');
+ $this->storage = $this->getMock('Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface');
+ $this->manager = new CsrfTokenManager($this->generator, $this->storage);
+ }
+
+ protected function tearDown()
+ {
+ $this->generator = null;
+ $this->storage = null;
+ $this->manager = null;
+ }
+
+ public function testGetNonExistingToken()
+ {
+ $this->storage->expects($this->once())
+ ->method('hasToken')
+ ->with('token_id')
+ ->will($this->returnValue(false));
+
+ $this->generator->expects($this->once())
+ ->method('generateToken')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->storage->expects($this->once())
+ ->method('setToken')
+ ->with('token_id', 'TOKEN');
+
+ $token = $this->manager->getToken('token_id');
+
+ $this->assertInstanceOf('Symfony\Component\Security\Csrf\CsrfToken', $token);
+ $this->assertSame('token_id', $token->getId());
+ $this->assertSame('TOKEN', $token->getValue());
+ }
+
+ public function testUseExistingTokenIfAvailable()
+ {
+ $this->storage->expects($this->once())
+ ->method('hasToken')
+ ->with('token_id')
+ ->will($this->returnValue(true));
+
+ $this->storage->expects($this->once())
+ ->method('getToken')
+ ->with('token_id')
+ ->will($this->returnValue('TOKEN'));
+
+ $token = $this->manager->getToken('token_id');
+
+ $this->assertInstanceOf('Symfony\Component\Security\Csrf\CsrfToken', $token);
+ $this->assertSame('token_id', $token->getId());
+ $this->assertSame('TOKEN', $token->getValue());
+ }
+
+ public function testRefreshTokenAlwaysReturnsNewToken()
+ {
+ $this->storage->expects($this->never())
+ ->method('hasToken');
+
+ $this->generator->expects($this->once())
+ ->method('generateToken')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->storage->expects($this->once())
+ ->method('setToken')
+ ->with('token_id', 'TOKEN');
+
+ $token = $this->manager->refreshToken('token_id');
+
+ $this->assertInstanceOf('Symfony\Component\Security\Csrf\CsrfToken', $token);
+ $this->assertSame('token_id', $token->getId());
+ $this->assertSame('TOKEN', $token->getValue());
+ }
+
+ public function testMatchingTokenIsValid()
+ {
+ $this->storage->expects($this->once())
+ ->method('hasToken')
+ ->with('token_id')
+ ->will($this->returnValue(true));
+
+ $this->storage->expects($this->once())
+ ->method('getToken')
+ ->with('token_id')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->assertTrue($this->manager->isTokenValid(new CsrfToken('token_id', 'TOKEN')));
+ }
+
+ public function testNonMatchingTokenIsNotValid()
+ {
+ $this->storage->expects($this->once())
+ ->method('hasToken')
+ ->with('token_id')
+ ->will($this->returnValue(true));
+
+ $this->storage->expects($this->once())
+ ->method('getToken')
+ ->with('token_id')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->assertFalse($this->manager->isTokenValid(new CsrfToken('token_id', 'FOOBAR')));
+ }
+
+ public function testNonExistingTokenIsNotValid()
+ {
+ $this->storage->expects($this->once())
+ ->method('hasToken')
+ ->with('token_id')
+ ->will($this->returnValue(false));
+
+ $this->storage->expects($this->never())
+ ->method('getToken');
+
+ $this->assertFalse($this->manager->isTokenValid(new CsrfToken('token_id', 'FOOBAR')));
+ }
+
+ public function testRemoveToken()
+ {
+ $this->storage->expects($this->once())
+ ->method('removeToken')
+ ->with('token_id')
+ ->will($this->returnValue('REMOVED_TOKEN'));
+
+ $this->assertSame('REMOVED_TOKEN', $this->manager->removeToken('token_id'));
+ }
+}
diff --git a/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php b/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php
new file mode 100644
index 0000000..1b325e5
--- /dev/null
+++ b/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\Tests\TokenGenerator;
+
+use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class UriSafeTokenGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+ const ENTROPY = 1000;
+
+ /**
+ * A non alpha-numeric byte string.
+ *
+ * @var string
+ */
+ private static $bytes;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $random;
+
+ /**
+ * @var UriSafeTokenGenerator
+ */
+ private $generator;
+
+ public static function setUpBeforeClass()
+ {
+ self::$bytes = base64_decode('aMf+Tct/RLn2WQ==');
+ }
+
+ protected function setUp()
+ {
+ $this->random = $this->getMock('Symfony\Component\Security\Core\Util\SecureRandomInterface');
+ $this->generator = new UriSafeTokenGenerator($this->random, self::ENTROPY);
+ }
+
+ protected function tearDown()
+ {
+ $this->random = null;
+ $this->generator = null;
+ }
+
+ public function testGenerateToken()
+ {
+ $this->random->expects($this->once())
+ ->method('nextBytes')
+ ->with(self::ENTROPY / 8)
+ ->will($this->returnValue(self::$bytes));
+
+ $token = $this->generator->generateToken();
+
+ $this->assertTrue(ctype_print($token), 'is printable');
+ $this->assertStringNotMatchesFormat('%S+%S', $token, 'is URI safe');
+ $this->assertStringNotMatchesFormat('%S/%S', $token, 'is URI safe');
+ $this->assertStringNotMatchesFormat('%S=%S', $token, 'is URI safe');
+ }
+}
diff --git a/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php b/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php
new file mode 100644
index 0000000..7d3a537
--- /dev/null
+++ b/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\Tests\TokenStorage;
+
+use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class NativeSessionTokenStorageTest extends \PHPUnit_Framework_TestCase
+{
+ const SESSION_NAMESPACE = 'foobar';
+
+ /**
+ * @var NativeSessionTokenStorage
+ */
+ private $storage;
+
+ public static function setUpBeforeClass()
+ {
+ ini_set('session.save_handler', 'files');
+ ini_set('session.save_path', sys_get_temp_dir());
+
+ parent::setUpBeforeClass();
+ }
+
+ protected function setUp()
+ {
+ $_SESSION = array();
+
+ $this->storage = new NativeSessionTokenStorage(self::SESSION_NAMESPACE);
+ }
+
+ public function testStoreTokenInClosedSession()
+ {
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION);
+ }
+
+ /**
+ * @requires PHP 5.4
+ */
+ public function testStoreTokenInClosedSessionWithExistingSessionId()
+ {
+ session_id('foobar');
+
+ $this->assertSame(PHP_SESSION_NONE, session_status());
+
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertSame(PHP_SESSION_ACTIVE, session_status());
+ $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION);
+ }
+
+ public function testStoreTokenInActiveSession()
+ {
+ session_start();
+
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION);
+ }
+
+ /**
+ * @depends testStoreTokenInClosedSession
+ */
+ public function testCheckToken()
+ {
+ $this->assertFalse($this->storage->hasToken('token_id'));
+
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertTrue($this->storage->hasToken('token_id'));
+ }
+
+ /**
+ * @depends testStoreTokenInClosedSession
+ */
+ public function testGetExistingToken()
+ {
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertSame('TOKEN', $this->storage->getToken('token_id'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Csrf\Exception\TokenNotFoundException
+ */
+ public function testGetNonExistingToken()
+ {
+ $this->storage->getToken('token_id');
+ }
+
+ /**
+ * @depends testCheckToken
+ */
+ public function testRemoveNonExistingToken()
+ {
+ $this->assertNull($this->storage->removeToken('token_id'));
+ $this->assertFalse($this->storage->hasToken('token_id'));
+ }
+
+ /**
+ * @depends testCheckToken
+ */
+ public function testRemoveExistingToken()
+ {
+ $this->storage->setToken('token_id', 'TOKEN');
+
+ $this->assertSame('TOKEN', $this->storage->removeToken('token_id'));
+ $this->assertFalse($this->storage->hasToken('token_id'));
+ }
+}
diff --git a/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php b/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php
new file mode 100644
index 0000000..0eac0a8
--- /dev/null
+++ b/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php
@@ -0,0 +1,258 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\Tests\TokenStorage;
+
+use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class SessionTokenStorageTest extends \PHPUnit_Framework_TestCase
+{
+ const SESSION_NAMESPACE = 'foobar';
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $session;
+
+ /**
+ * @var SessionTokenStorage
+ */
+ private $storage;
+
+ protected function setUp()
+ {
+ $this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storage = new SessionTokenStorage($this->session, self::SESSION_NAMESPACE);
+ }
+
+ public function testStoreTokenInClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('set')
+ ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN');
+
+ $this->storage->setToken('token_id', 'TOKEN');
+ }
+
+ public function testStoreTokenInActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('set')
+ ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN');
+
+ $this->storage->setToken('token_id', 'TOKEN');
+ }
+
+ public function testCheckTokenInClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->storage->hasToken('token_id'));
+ }
+
+ public function testCheckTokenInActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->storage->hasToken('token_id'));
+ }
+
+ public function testGetExistingTokenFromClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->once())
+ ->method('get')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->storage->getToken('token_id'));
+ }
+
+ public function testGetExistingTokenFromActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->once())
+ ->method('get')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->storage->getToken('token_id'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Csrf\Exception\TokenNotFoundException
+ */
+ public function testGetNonExistingTokenFromClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(false));
+
+ $this->storage->getToken('token_id');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Csrf\Exception\TokenNotFoundException
+ */
+ public function testGetNonExistingTokenFromActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('has')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(false));
+
+ $this->storage->getToken('token_id');
+ }
+
+ public function testRemoveNonExistingTokenFromClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('remove')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(null));
+
+ $this->assertNull($this->storage->removeToken('token_id'));
+ }
+
+ public function testRemoveNonExistingTokenFromActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('remove')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue(null));
+
+ $this->assertNull($this->storage->removeToken('token_id'));
+ }
+
+ public function testRemoveExistingTokenFromClosedSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(false));
+
+ $this->session->expects($this->once())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('remove')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->assertSame('TOKEN', $this->storage->removeToken('token_id'));
+ }
+
+ public function testRemoveExistingTokenFromActiveSession()
+ {
+ $this->session->expects($this->any())
+ ->method('isStarted')
+ ->will($this->returnValue(true));
+
+ $this->session->expects($this->never())
+ ->method('start');
+
+ $this->session->expects($this->once())
+ ->method('remove')
+ ->with(self::SESSION_NAMESPACE.'/token_id')
+ ->will($this->returnValue('TOKEN'));
+
+ $this->assertSame('TOKEN', $this->storage->removeToken('token_id'));
+ }
+}
diff --git a/Csrf/TokenGenerator/TokenGeneratorInterface.php b/Csrf/TokenGenerator/TokenGeneratorInterface.php
new file mode 100644
index 0000000..1405b84
--- /dev/null
+++ b/Csrf/TokenGenerator/TokenGeneratorInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\TokenGenerator;
+
+/**
+ * Generates CSRF tokens.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface TokenGeneratorInterface
+{
+ /**
+ * Generates a CSRF token.
+ *
+ * @return string The generated CSRF token
+ */
+ public function generateToken();
+}
diff --git a/Csrf/TokenGenerator/UriSafeTokenGenerator.php b/Csrf/TokenGenerator/UriSafeTokenGenerator.php
new file mode 100644
index 0000000..edeb435
--- /dev/null
+++ b/Csrf/TokenGenerator/UriSafeTokenGenerator.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\TokenGenerator;
+
+use Symfony\Component\Security\Core\Util\SecureRandomInterface;
+use Symfony\Component\Security\Core\Util\SecureRandom;
+
+/**
+ * Generates CSRF tokens.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bernhard.schussek@symfony.com>
+ */
+class UriSafeTokenGenerator implements TokenGeneratorInterface
+{
+ /**
+ * The generator for random values.
+ *
+ * @var SecureRandomInterface
+ */
+ private $random;
+
+ /**
+ * The amount of entropy collected for each token (in bits).
+ *
+ * @var int
+ */
+ private $entropy;
+
+ /**
+ * Generates URI-safe CSRF tokens.
+ *
+ * @param SecureRandomInterface|null $random The random value generator used for
+ * generating entropy
+ * @param int $entropy The amount of entropy collected for
+ * each token (in bits)
+ */
+ public function __construct(SecureRandomInterface $random = null, $entropy = 256)
+ {
+ $this->random = $random ?: new SecureRandom();
+ $this->entropy = $entropy;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function generateToken()
+ {
+ // Generate an URI safe base64 encoded string that does not contain "+",
+ // "/" or "=" which need to be URL encoded and make URLs unnecessarily
+ // longer.
+ $bytes = $this->random->nextBytes($this->entropy / 8);
+
+ return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');
+ }
+}
diff --git a/Csrf/TokenStorage/NativeSessionTokenStorage.php b/Csrf/TokenStorage/NativeSessionTokenStorage.php
new file mode 100644
index 0000000..2620156
--- /dev/null
+++ b/Csrf/TokenStorage/NativeSessionTokenStorage.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\TokenStorage;
+
+use Symfony\Component\Security\Csrf\Exception\TokenNotFoundException;
+
+/**
+ * Token storage that uses PHP's native session handling.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class NativeSessionTokenStorage implements TokenStorageInterface
+{
+ /**
+ * The namespace used to store values in the session.
+ *
+ * @var string
+ */
+ const SESSION_NAMESPACE = '_csrf';
+
+ /**
+ * @var bool
+ */
+ private $sessionStarted = false;
+
+ /**
+ * @var string
+ */
+ private $namespace;
+
+ /**
+ * Initializes the storage with a session namespace.
+ *
+ * @param string $namespace The namespace under which the token is stored
+ * in the session
+ */
+ public function __construct($namespace = self::SESSION_NAMESPACE)
+ {
+ $this->namespace = $namespace;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getToken($tokenId)
+ {
+ if (!$this->sessionStarted) {
+ $this->startSession();
+ }
+
+ if (!isset($_SESSION[$this->namespace][$tokenId])) {
+ throw new TokenNotFoundException('The CSRF token with ID '.$tokenId.' does not exist.');
+ }
+
+ return (string) $_SESSION[$this->namespace][$tokenId];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setToken($tokenId, $token)
+ {
+ if (!$this->sessionStarted) {
+ $this->startSession();
+ }
+
+ $_SESSION[$this->namespace][$tokenId] = (string) $token;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasToken($tokenId)
+ {
+ if (!$this->sessionStarted) {
+ $this->startSession();
+ }
+
+ return isset($_SESSION[$this->namespace][$tokenId]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeToken($tokenId)
+ {
+ if (!$this->sessionStarted) {
+ $this->startSession();
+ }
+
+ $token = isset($_SESSION[$this->namespace][$tokenId])
+ ? (string) $_SESSION[$this->namespace][$tokenId]
+ : null;
+
+ unset($_SESSION[$this->namespace][$tokenId]);
+
+ return $token;
+ }
+
+ private function startSession()
+ {
+ if (PHP_VERSION_ID >= 50400) {
+ if (PHP_SESSION_NONE === session_status()) {
+ session_start();
+ }
+ } elseif (!session_id()) {
+ session_start();
+ }
+
+ $this->sessionStarted = true;
+ }
+}
diff --git a/Csrf/TokenStorage/SessionTokenStorage.php b/Csrf/TokenStorage/SessionTokenStorage.php
new file mode 100644
index 0000000..a6a6ea3
--- /dev/null
+++ b/Csrf/TokenStorage/SessionTokenStorage.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\TokenStorage;
+
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+use Symfony\Component\Security\Csrf\Exception\TokenNotFoundException;
+
+/**
+ * Token storage that uses a Symfony2 Session object.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class SessionTokenStorage implements TokenStorageInterface
+{
+ /**
+ * The namespace used to store values in the session.
+ *
+ * @var string
+ */
+ const SESSION_NAMESPACE = '_csrf';
+
+ /**
+ * The user session from which the session ID is returned.
+ *
+ * @var SessionInterface
+ */
+ private $session;
+
+ /**
+ * @var string
+ */
+ private $namespace;
+
+ /**
+ * Initializes the storage with a Session object and a session namespace.
+ *
+ * @param SessionInterface $session The user session
+ * @param string $namespace The namespace under which the token
+ * is stored in the session
+ */
+ public function __construct(SessionInterface $session, $namespace = self::SESSION_NAMESPACE)
+ {
+ $this->session = $session;
+ $this->namespace = $namespace;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getToken($tokenId)
+ {
+ if (!$this->session->isStarted()) {
+ $this->session->start();
+ }
+
+ if (!$this->session->has($this->namespace.'/'.$tokenId)) {
+ throw new TokenNotFoundException('The CSRF token with ID '.$tokenId.' does not exist.');
+ }
+
+ return (string) $this->session->get($this->namespace.'/'.$tokenId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setToken($tokenId, $token)
+ {
+ if (!$this->session->isStarted()) {
+ $this->session->start();
+ }
+
+ $this->session->set($this->namespace.'/'.$tokenId, (string) $token);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasToken($tokenId)
+ {
+ if (!$this->session->isStarted()) {
+ $this->session->start();
+ }
+
+ return $this->session->has($this->namespace.'/'.$tokenId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeToken($tokenId)
+ {
+ if (!$this->session->isStarted()) {
+ $this->session->start();
+ }
+
+ return $this->session->remove($this->namespace.'/'.$tokenId);
+ }
+}
diff --git a/Csrf/TokenStorage/TokenStorageInterface.php b/Csrf/TokenStorage/TokenStorageInterface.php
new file mode 100644
index 0000000..5efe72f
--- /dev/null
+++ b/Csrf/TokenStorage/TokenStorageInterface.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Csrf\TokenStorage;
+
+/**
+ * Stores CSRF tokens.
+ *
+ * @since 2.4
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface TokenStorageInterface
+{
+ /**
+ * Reads a stored CSRF token.
+ *
+ * @param string $tokenId The token ID
+ *
+ * @return string The stored token
+ *
+ * @throws \Symfony\Component\Security\Csrf\Exception\TokenNotFoundException If the token ID does not exist
+ */
+ public function getToken($tokenId);
+
+ /**
+ * Stores a CSRF token.
+ *
+ * @param string $tokenId The token ID
+ * @param string $token The CSRF token
+ */
+ public function setToken($tokenId, $token);
+
+ /**
+ * Removes a CSRF token.
+ *
+ * @param string $tokenId The token ID
+ *
+ * @return string|null Returns the removed token if one existed, NULL
+ * otherwise
+ */
+ public function removeToken($tokenId);
+
+ /**
+ * Checks whether a token with the given token ID exists.
+ *
+ * @param string $tokenId The token ID
+ *
+ * @return bool Whether a token exists with the given ID
+ */
+ public function hasToken($tokenId);
+}
diff --git a/Csrf/composer.json b/Csrf/composer.json
new file mode 100644
index 0000000..2930e32
--- /dev/null
+++ b/Csrf/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "symfony/security-csrf",
+ "type": "library",
+ "description": "Symfony Security Component - CSRF Library",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/security-core": "~2.4"
+ },
+ "require-dev": {
+ "symfony/http-foundation": "~2.1"
+ },
+ "suggest": {
+ "symfony/http-foundation": "For using the class SessionTokenStorage."
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Security\\Csrf\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ }
+}
diff --git a/Csrf/phpunit.xml.dist b/Csrf/phpunit.xml.dist
new file mode 100644
index 0000000..f5b1e65
--- /dev/null
+++ b/Csrf/phpunit.xml.dist
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Security Component CSRF Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/Http/.gitignore b/Http/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/Http/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/Http/AccessMap.php b/Http/AccessMap.php
index 14fcbe1..116874a 100644
--- a/Http/AccessMap.php
+++ b/Http/AccessMap.php
@@ -28,12 +28,12 @@ class AccessMap implements AccessMapInterface
* Constructor.
*
* @param RequestMatcherInterface $requestMatcher A RequestMatcherInterface instance
- * @param array $roles An array of roles needed to access the resource
+ * @param array $attributes An array of attributes to pass to the access decision manager (like roles)
* @param string|null $channel The channel to enforce (http, https, or null)
*/
- public function add(RequestMatcherInterface $requestMatcher, array $roles = array(), $channel = null)
+ public function add(RequestMatcherInterface $requestMatcher, array $attributes = array(), $channel = null)
{
- $this->map[] = array($requestMatcher, $roles, $channel);
+ $this->map[] = array($requestMatcher, $attributes, $channel);
}
/**
diff --git a/Http/Authentication/AuthenticationUtils.php b/Http/Authentication/AuthenticationUtils.php
new file mode 100644
index 0000000..4d5c71a
--- /dev/null
+++ b/Http/Authentication/AuthenticationUtils.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * Extracts Security Errors from Request.
+ *
+ * @author Boris Vujicic <boris.vujicic@gmail.com>
+ */
+class AuthenticationUtils
+{
+ /**
+ * @var RequestStack
+ */
+ private $requestStack;
+
+ /**
+ * @param RequestStack $requestStack
+ */
+ public function __construct(RequestStack $requestStack)
+ {
+ $this->requestStack = $requestStack;
+ }
+
+ /**
+ * @param bool $clearSession
+ *
+ * @return AuthenticationException|null
+ */
+ public function getLastAuthenticationError($clearSession = true)
+ {
+ $request = $this->getRequest();
+ $session = $request->getSession();
+ $authenticationException = null;
+
+ if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
+ $authenticationException = $request->attributes->get(Security::AUTHENTICATION_ERROR);
+ } elseif ($session !== null && $session->has(Security::AUTHENTICATION_ERROR)) {
+ $authenticationException = $session->get(Security::AUTHENTICATION_ERROR);
+
+ if ($clearSession) {
+ $session->remove(Security::AUTHENTICATION_ERROR);
+ }
+ }
+
+ return $authenticationException;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLastUsername()
+ {
+ $session = $this->getRequest()->getSession();
+
+ return null === $session ? '' : $session->get(Security::LAST_USERNAME);
+ }
+
+ /**
+ * @return Request
+ *
+ * @throws \LogicException
+ */
+ private function getRequest()
+ {
+ $request = $this->requestStack->getCurrentRequest();
+
+ if (null === $request) {
+ throw new \LogicException('Request should exist so it can be processed for error.');
+ }
+
+ return $request;
+ }
+}
diff --git a/Http/Authentication/CustomAuthenticationFailureHandler.php b/Http/Authentication/CustomAuthenticationFailureHandler.php
new file mode 100644
index 0000000..36d4a78
--- /dev/null
+++ b/Http/Authentication/CustomAuthenticationFailureHandler.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CustomAuthenticationFailureHandler implements AuthenticationFailureHandlerInterface
+{
+ private $handler;
+
+ /**
+ * Constructor.
+ *
+ * @param AuthenticationFailureHandlerInterface $handler An AuthenticationFailureHandlerInterface instance
+ * @param array $options Options for processing a successful authentication attempt
+ */
+ public function __construct(AuthenticationFailureHandlerInterface $handler, array $options)
+ {
+ $this->handler = $handler;
+ if (method_exists($handler, 'setOptions')) {
+ $this->handler->setOptions($options);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ return $this->handler->onAuthenticationFailure($request, $exception);
+ }
+}
diff --git a/Http/Authentication/CustomAuthenticationSuccessHandler.php b/Http/Authentication/CustomAuthenticationSuccessHandler.php
new file mode 100644
index 0000000..2d1b26e
--- /dev/null
+++ b/Http/Authentication/CustomAuthenticationSuccessHandler.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
+{
+ private $handler;
+
+ /**
+ * Constructor.
+ *
+ * @param AuthenticationSuccessHandlerInterface $handler An AuthenticationSuccessHandlerInterface instance
+ * @param array $options Options for processing a successful authentication attempt
+ * @param string $providerKey The provider key
+ */
+ public function __construct(AuthenticationSuccessHandlerInterface $handler, array $options, $providerKey)
+ {
+ $this->handler = $handler;
+ if (method_exists($handler, 'setOptions')) {
+ $this->handler->setOptions($options);
+ }
+ if (method_exists($handler, 'setProviderKey')) {
+ $this->handler->setProviderKey($providerKey);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
+ {
+ return $this->handler->onAuthenticationSuccess($request, $token);
+ }
+}
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
index b3c5c4d..f8004d6 100644
--- a/Http/Authentication/DefaultAuthenticationFailureHandler.php
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
/**
@@ -34,6 +34,12 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
protected $httpUtils;
protected $logger;
protected $options;
+ protected $defaultOptions = array(
+ 'failure_path' => null,
+ 'failure_forward' => false,
+ 'login_path' => '/login',
+ 'failure_path_parameter' => '_failure_path',
+ );
/**
* Constructor.
@@ -43,18 +49,32 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
* @param array $options Options for processing a failed authentication attempt.
* @param LoggerInterface $logger Optional logger
*/
- public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null)
+ public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options = array(), LoggerInterface $logger = null)
{
$this->httpKernel = $httpKernel;
$this->httpUtils = $httpUtils;
$this->logger = $logger;
+ $this->setOptions($options);
+ }
- $this->options = array_merge(array(
- 'failure_path' => null,
- 'failure_forward' => false,
- 'login_path' => '/login',
- 'failure_path_parameter' => '_failure_path',
- ), $options);
+ /**
+ * Gets the options.
+ *
+ * @return array An array of options
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Sets the options.
+ *
+ * @param array $options An array of options
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array_merge($this->defaultOptions, $options);
}
/**
@@ -72,20 +92,20 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
if ($this->options['failure_forward']) {
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Forwarding to %s', $this->options['failure_path']));
+ $this->logger->debug('Authentication failure, forward triggered.', array('failure_path' => $this->options['failure_path']));
}
$subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
- $subRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+ $subRequest->attributes->set(Security::AUTHENTICATION_ERROR, $exception);
return $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Redirecting to %s', $this->options['failure_path']));
+ $this->logger->debug('Authentication failure, redirect triggered.', array('failure_path' => $this->options['failure_path']));
}
- $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+ $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
return $this->httpUtils->createRedirectResponse($request, $this->options['failure_path']);
}
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
index 591a28d..5fa7071 100644
--- a/Http/Authentication/DefaultAuthenticationSuccessHandler.php
+++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
@@ -27,6 +27,13 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
protected $httpUtils;
protected $options;
protected $providerKey;
+ protected $defaultOptions = array(
+ 'always_use_default_target_path' => false,
+ 'default_target_path' => '/',
+ 'login_path' => '/login',
+ 'target_path_parameter' => '_target_path',
+ 'use_referer' => false,
+ );
/**
* Constructor.
@@ -34,17 +41,10 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
* @param HttpUtils $httpUtils
* @param array $options Options for processing a successful authentication attempt.
*/
- public function __construct(HttpUtils $httpUtils, array $options)
+ public function __construct(HttpUtils $httpUtils, array $options = array())
{
$this->httpUtils = $httpUtils;
-
- $this->options = array_merge(array(
- 'always_use_default_target_path' => false,
- 'default_target_path' => '/',
- 'login_path' => '/login',
- 'target_path_parameter' => '_target_path',
- 'use_referer' => false,
- ), $options);
+ $this->setOptions($options);
}
/**
@@ -56,6 +56,26 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
}
/**
+ * Gets the options.
+ *
+ * @return array An array of options
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Sets the options.
+ *
+ * @param array $options An array of options
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array_merge($this->defaultOptions, $options);
+ }
+
+ /**
* Get the provider key.
*
* @return string
diff --git a/Http/Authentication/SimpleAuthenticationHandler.php b/Http/Authentication/SimpleAuthenticationHandler.php
new file mode 100644
index 0000000..c5c43f2
--- /dev/null
+++ b/Http/Authentication/SimpleAuthenticationHandler.php
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface;
+
+/**
+ * Class to proxy authentication success/failure handlers.
+ *
+ * Events are sent to the SimpleAuthenticatorInterface if it implements
+ * the right interface, otherwise (or if it fails to return a Response)
+ * the default handlers are triggered.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class SimpleAuthenticationHandler implements AuthenticationFailureHandlerInterface, AuthenticationSuccessHandlerInterface
+{
+ protected $successHandler;
+ protected $failureHandler;
+ protected $simpleAuthenticator;
+ protected $logger;
+
+ /**
+ * Constructor.
+ *
+ * @param SimpleAuthenticatorInterface $authenticator SimpleAuthenticatorInterface instance
+ * @param AuthenticationSuccessHandlerInterface $successHandler Default success handler
+ * @param AuthenticationFailureHandlerInterface $failureHandler Default failure handler
+ * @param LoggerInterface $logger Optional logger
+ */
+ public function __construct(SimpleAuthenticatorInterface $authenticator, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, LoggerInterface $logger = null)
+ {
+ $this->simpleAuthenticator = $authenticator;
+ $this->successHandler = $successHandler;
+ $this->failureHandler = $failureHandler;
+ $this->logger = $logger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
+ {
+ if ($this->simpleAuthenticator instanceof AuthenticationSuccessHandlerInterface) {
+ if ($this->logger) {
+ $this->logger->debug('Selected an authentication success handler.', array('handler' => get_class($this->simpleAuthenticator)));
+ }
+
+ $response = $this->simpleAuthenticator->onAuthenticationSuccess($request, $token);
+ if ($response instanceof Response) {
+ return $response;
+ }
+
+ if (null !== $response) {
+ throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationSuccess method must return null to use the default success handler, or a Response object', get_class($this->simpleAuthenticator)));
+ }
+ }
+
+ if ($this->logger) {
+ $this->logger->debug('Fallback to the default authentication success handler.');
+ }
+
+ return $this->successHandler->onAuthenticationSuccess($request, $token);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ if ($this->simpleAuthenticator instanceof AuthenticationFailureHandlerInterface) {
+ if ($this->logger) {
+ $this->logger->debug('Selected an authentication failure handler.', array('handler' => get_class($this->simpleAuthenticator)));
+ }
+
+ $response = $this->simpleAuthenticator->onAuthenticationFailure($request, $exception);
+ if ($response instanceof Response) {
+ return $response;
+ }
+
+ if (null !== $response) {
+ throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationFailure method must return null to use the default failure handler, or a Response object', get_class($this->simpleAuthenticator)));
+ }
+ }
+
+ if ($this->logger) {
+ $this->logger->debug('Fallback to the default authentication failure handler.');
+ }
+
+ return $this->failureHandler->onAuthenticationFailure($request, $exception);
+ }
+}
diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
index 5a7aa1a..89f80ad 100644
--- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
@@ -54,7 +54,7 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
}
if (null !== $this->logger) {
- $this->logger->debug(sprintf('WWW-Authenticate header sent to user agent: "%s"', $authenticateHeader));
+ $this->logger->debug('WWW-Authenticate header sent.', array('header' => $authenticateHeader));
}
$response = new Response();
diff --git a/Http/Firewall.php b/Http/Firewall.php
index 7499c6f..7bad47a 100644
--- a/Http/Firewall.php
+++ b/Http/Firewall.php
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -31,6 +31,7 @@ class Firewall implements EventSubscriberInterface
{
private $map;
private $dispatcher;
+ private $exceptionListeners;
/**
* Constructor.
@@ -42,6 +43,7 @@ class Firewall implements EventSubscriberInterface
{
$this->map = $map;
$this->dispatcher = $dispatcher;
+ $this->exceptionListeners = new \SplObjectStorage();
}
/**
@@ -51,14 +53,15 @@ class Firewall implements EventSubscriberInterface
*/
public function onKernelRequest(GetResponseEvent $event)
{
- if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+ if (!$event->isMasterRequest()) {
return;
}
// register listeners for this firewall
- list($listeners, $exception) = $this->map->getListeners($event->getRequest());
- if (null !== $exception) {
- $exception->register($this->dispatcher);
+ list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest());
+ if (null !== $exceptionListener) {
+ $this->exceptionListeners[$event->getRequest()] = $exceptionListener;
+ $exceptionListener->register($this->dispatcher);
}
// initiate the listener chain
@@ -71,11 +74,24 @@ class Firewall implements EventSubscriberInterface
}
}
+ public function onKernelFinishRequest(FinishRequestEvent $event)
+ {
+ $request = $event->getRequest();
+
+ if (isset($this->exceptionListeners[$request])) {
+ $this->exceptionListeners[$request]->unregister($this->dispatcher);
+ unset($this->exceptionListeners[$request]);
+ }
+ }
+
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
- return array(KernelEvents::REQUEST => array('onKernelRequest', 8));
+ return array(
+ KernelEvents::REQUEST => array('onKernelRequest', 8),
+ KernelEvents::FINISH_REQUEST => 'onKernelFinishRequest',
+ );
}
}
diff --git a/Http/Firewall/AbstractAuthenticationListener.php b/Http/Firewall/AbstractAuthenticationListener.php
index f71089f..09a4f55 100644
--- a/Http/Firewall/AbstractAuthenticationListener.php
+++ b/Http/Firewall/AbstractAuthenticationListener.php
@@ -15,8 +15,9 @@ use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterfa
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
@@ -55,7 +56,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
protected $providerKey;
protected $httpUtils;
- private $securityContext;
+ private $tokenStorage;
private $sessionStrategy;
private $dispatcher;
private $successHandler;
@@ -65,7 +66,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
/**
* Constructor.
*
- * @param SecurityContextInterface $securityContext A SecurityContext instance
+ * @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param SessionAuthenticationStrategyInterface $sessionStrategy
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
@@ -79,13 +80,13 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
*
* @throws \InvalidArgumentException
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->authenticationManager = $authenticationManager;
$this->sessionStrategy = $sessionStrategy;
$this->providerKey = $providerKey;
@@ -149,14 +150,14 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
if ($returnValue instanceof TokenInterface) {
$this->sessionStrategy->onAuthentication($request, $returnValue);
- $response = $this->onSuccess($event, $request, $returnValue);
+ $response = $this->onSuccess($request, $returnValue);
} elseif ($returnValue instanceof Response) {
$response = $returnValue;
} else {
throw new \RuntimeException('attemptAuthentication() must either return a Response, an implementation of TokenInterface, or null.');
}
} catch (AuthenticationException $e) {
- $response = $this->onFailure($event, $request, $e);
+ $response = $this->onFailure($request, $e);
}
$event->setResponse($response);
@@ -189,15 +190,15 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
*/
abstract protected function attemptAuthentication(Request $request);
- private function onFailure(GetResponseEvent $event, Request $request, AuthenticationException $failed)
+ private function onFailure(Request $request, AuthenticationException $failed)
{
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication request failed: %s', $failed->getMessage()));
+ $this->logger->info('Authentication request failed.', array('exception' => $failed));
}
- $token = $this->securityContext->getToken();
+ $token = $this->tokenStorage->getToken();
if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) {
- $this->securityContext->setToken(null);
+ $this->tokenStorage->setToken(null);
}
$response = $this->failureHandler->onAuthenticationFailure($request, $failed);
@@ -209,17 +210,17 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
return $response;
}
- private function onSuccess(GetResponseEvent $event, Request $request, TokenInterface $token)
+ private function onSuccess(Request $request, TokenInterface $token)
{
if (null !== $this->logger) {
- $this->logger->info(sprintf('User "%s" has been authenticated successfully', $token->getUsername()));
+ $this->logger->info('User has been authenticated successfully.', array('username' => $token->getUsername()));
}
- $this->securityContext->setToken($token);
+ $this->tokenStorage->setToken($token);
$session = $request->getSession();
- $session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
- $session->remove(SecurityContextInterface::LAST_USERNAME);
+ $session->remove(Security::AUTHENTICATION_ERROR);
+ $session->remove(Security::LAST_USERNAME);
if (null !== $this->dispatcher) {
$loginEvent = new InteractiveLoginEvent($request, $token);
diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php
index 9973683..b793310 100644
--- a/Http/Firewall/AbstractPreAuthenticatedListener.php
+++ b/Http/Firewall/AbstractPreAuthenticatedListener.php
@@ -11,9 +11,9 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
@@ -33,14 +33,14 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
abstract class AbstractPreAuthenticatedListener implements ListenerInterface
{
protected $logger;
- private $securityContext;
+ private $tokenStorage;
private $authenticationManager;
private $providerKey;
private $dispatcher;
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->authenticationManager = $authenticationManager;
$this->providerKey = $providerKey;
$this->logger = $logger;
@@ -56,10 +56,6 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
{
$request = $event->getRequest();
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Checking secure context token: %s', $this->securityContext->getToken()));
- }
-
try {
list($user, $credentials) = $this->getPreAuthenticatedData($request);
} catch (BadCredentialsException $e) {
@@ -68,23 +64,27 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
return;
}
- if (null !== $token = $this->securityContext->getToken()) {
+ if (null !== $this->logger) {
+ $this->logger->debug('Checking current security token.', array('token' => (string) $this->tokenStorage->getToken()));
+ }
+
+ if (null !== $token = $this->tokenStorage->getToken()) {
if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getProviderKey() && $token->isAuthenticated() && $token->getUsername() === $user) {
return;
}
}
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Trying to pre-authenticate user "%s"', $user));
+ $this->logger->debug('Trying to pre-authenticate user.', array('username' => (string) $user));
}
try {
$token = $this->authenticationManager->authenticate(new PreAuthenticatedToken($user, $credentials, $this->providerKey));
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication success: %s', $token));
+ $this->logger->info('Pre-authentication successful.', array('token' => (string) $token));
}
- $this->securityContext->setToken($token);
+ $this->tokenStorage->setToken($token);
if (null !== $this->dispatcher) {
$loginEvent = new InteractiveLoginEvent($request, $token);
@@ -102,12 +102,12 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
*/
private function clearToken(AuthenticationException $exception)
{
- $token = $this->securityContext->getToken();
+ $token = $this->tokenStorage->getToken();
if ($token instanceof PreAuthenticatedToken && $this->providerKey === $token->getProviderKey()) {
- $this->securityContext->setToken(null);
+ $this->tokenStorage->setToken(null);
if (null !== $this->logger) {
- $this->logger->info(sprintf('Cleared security context due to exception: %s', $exception->getMessage()));
+ $this->logger->info('Cleared security token due to an exception.', array('exception' => $exception));
}
}
}
diff --git a/Http/Firewall/AccessListener.php b/Http/Firewall/AccessListener.php
index ecb6a09..c234317 100644
--- a/Http/Firewall/AccessListener.php
+++ b/Http/Firewall/AccessListener.php
@@ -11,10 +11,10 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
@@ -26,14 +26,14 @@ use Symfony\Component\Security\Core\Exception\AccessDeniedException;
*/
class AccessListener implements ListenerInterface
{
- private $context;
+ private $tokenStorage;
private $accessDecisionManager;
private $map;
private $authManager;
- public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager)
+ public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager)
{
- $this->context = $context;
+ $this->tokenStorage = $tokenStorage;
$this->accessDecisionManager = $accessDecisionManager;
$this->map = $map;
$this->authManager = $authManager;
@@ -49,8 +49,8 @@ class AccessListener implements ListenerInterface
*/
public function handle(GetResponseEvent $event)
{
- if (null === $token = $this->context->getToken()) {
- throw new AuthenticationCredentialsNotFoundException('A Token was not found in the SecurityContext.');
+ if (null === $token = $this->tokenStorage->getToken()) {
+ throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.');
}
$request = $event->getRequest();
@@ -63,7 +63,7 @@ class AccessListener implements ListenerInterface
if (!$token->isAuthenticated()) {
$token = $this->authManager->authenticate($token);
- $this->context->setToken($token);
+ $this->tokenStorage->setToken($token);
}
if (!$this->accessDecisionManager->decide($token, $attributes, $request)) {
diff --git a/Http/Firewall/AnonymousAuthenticationListener.php b/Http/Firewall/AnonymousAuthenticationListener.php
index 446dfec..f7feee8 100644
--- a/Http/Firewall/AnonymousAuthenticationListener.php
+++ b/Http/Firewall/AnonymousAuthenticationListener.php
@@ -11,7 +11,9 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
@@ -24,14 +26,16 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
*/
class AnonymousAuthenticationListener implements ListenerInterface
{
- private $context;
+ private $tokenStorage;
private $key;
+ private $authenticationManager;
private $logger;
- public function __construct(SecurityContextInterface $context, $key, LoggerInterface $logger = null)
+ public function __construct(TokenStorageInterface $tokenStorage, $key, LoggerInterface $logger = null, AuthenticationManagerInterface $authenticationManager = null)
{
- $this->context = $context;
+ $this->tokenStorage = $tokenStorage;
$this->key = $key;
+ $this->authenticationManager = $authenticationManager;
$this->logger = $logger;
}
@@ -42,14 +46,25 @@ class AnonymousAuthenticationListener implements ListenerInterface
*/
public function handle(GetResponseEvent $event)
{
- if (null !== $this->context->getToken()) {
+ if (null !== $this->tokenStorage->getToken()) {
return;
}
- $this->context->setToken(new AnonymousToken($this->key, 'anon.', array()));
+ try {
+ $token = new AnonymousToken($this->key, 'anon.', array());
+ if (null !== $this->authenticationManager) {
+ $token = $this->authenticationManager->authenticate($token);
+ }
- if (null !== $this->logger) {
- $this->logger->info('Populated SecurityContext with an anonymous Token');
+ $this->tokenStorage->setToken($token);
+
+ if (null !== $this->logger) {
+ $this->logger->info('Populated the TokenStorage with an anonymous Token.');
+ }
+ } catch (AuthenticationException $failed) {
+ if (null !== $this->logger) {
+ $this->logger->info('Anonymous authentication failed.', array('exception' => $failed));
+ }
}
}
}
diff --git a/Http/Firewall/BasicAuthenticationListener.php b/Http/Firewall/BasicAuthenticationListener.php
index eed9838..ebe96ea 100644
--- a/Http/Firewall/BasicAuthenticationListener.php
+++ b/Http/Firewall/BasicAuthenticationListener.php
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -26,20 +26,20 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
*/
class BasicAuthenticationListener implements ListenerInterface
{
- private $securityContext;
+ private $tokenStorage;
private $authenticationManager;
private $providerKey;
private $authenticationEntryPoint;
private $logger;
private $ignoreFailure;
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->authenticationManager = $authenticationManager;
$this->providerKey = $providerKey;
$this->authenticationEntryPoint = $authenticationEntryPoint;
@@ -60,27 +60,27 @@ class BasicAuthenticationListener implements ListenerInterface
return;
}
- if (null !== $token = $this->securityContext->getToken()) {
+ if (null !== $token = $this->tokenStorage->getToken()) {
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
return;
}
}
if (null !== $this->logger) {
- $this->logger->info(sprintf('Basic Authentication Authorization header found for user "%s"', $username));
+ $this->logger->info('Basic authentication Authorization header found for user.', array('username' => $username));
}
try {
$token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
- $this->securityContext->setToken($token);
+ $this->tokenStorage->setToken($token);
} catch (AuthenticationException $e) {
- $token = $this->securityContext->getToken();
+ $token = $this->tokenStorage->getToken();
if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) {
- $this->securityContext->setToken(null);
+ $this->tokenStorage->setToken(null);
}
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $e->getMessage()));
+ $this->logger->info('Basic authentication failed for user.', array('username' => $username, 'exception' => $e));
}
if ($this->ignoreFailure) {
diff --git a/Http/Firewall/ChannelListener.php b/Http/Firewall/ChannelListener.php
index 9e4a6ee..637a7f5 100644
--- a/Http/Firewall/ChannelListener.php
+++ b/Http/Firewall/ChannelListener.php
@@ -44,11 +44,11 @@ class ChannelListener implements ListenerInterface
{
$request = $event->getRequest();
- list($attributes, $channel) = $this->map->getPatterns($request);
+ list(, $channel) = $this->map->getPatterns($request);
if ('https' === $channel && !$request->isSecure()) {
if (null !== $this->logger) {
- $this->logger->info('Redirecting to HTTPS');
+ $this->logger->info('Redirecting to HTTPS.');
}
$response = $this->authenticationEntryPoint->start($request);
@@ -60,7 +60,7 @@ class ChannelListener implements ListenerInterface
if ('http' === $channel && $request->isSecure()) {
if (null !== $this->logger) {
- $this->logger->info('Redirecting to HTTP');
+ $this->logger->info('Redirecting to HTTP.');
}
$response = $this->authenticationEntryPoint->start($request);
diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php
index 43ad31d..9ac37cd 100644
--- a/Http/Firewall/ContextListener.php
+++ b/Http/Firewall/ContextListener.php
@@ -11,16 +11,15 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -33,14 +32,15 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class ContextListener implements ListenerInterface
{
- private $context;
+ private $tokenStorage;
private $contextKey;
+ private $sessionKey;
private $logger;
private $userProviders;
private $dispatcher;
private $registered;
- public function __construct(SecurityContextInterface $context, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
if (empty($contextKey)) {
throw new \InvalidArgumentException('$contextKey must not be empty.');
@@ -52,21 +52,22 @@ class ContextListener implements ListenerInterface
}
}
- $this->context = $context;
+ $this->tokenStorage = $tokenStorage;
$this->userProviders = $userProviders;
$this->contextKey = $contextKey;
+ $this->sessionKey = '_security_'.$contextKey;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
}
/**
- * Reads the SecurityContext from the session.
+ * Reads the Security Token from the session.
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
- if (!$this->registered && null !== $this->dispatcher && HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
+ if (!$this->registered && null !== $this->dispatcher && $event->isMasterRequest()) {
$this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
$this->registered = true;
}
@@ -74,8 +75,8 @@ class ContextListener implements ListenerInterface
$request = $event->getRequest();
$session = $request->hasPreviousSession() ? $request->getSession() : null;
- if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) {
- $this->context->setToken(null);
+ if (null === $session || null === $token = $session->get($this->sessionKey)) {
+ $this->tokenStorage->setToken(null);
return;
}
@@ -83,30 +84,30 @@ class ContextListener implements ListenerInterface
$token = unserialize($token);
if (null !== $this->logger) {
- $this->logger->debug('Read SecurityContext from the session');
+ $this->logger->debug('Read existing security token from the session.', array('key' => $this->sessionKey));
}
if ($token instanceof TokenInterface) {
$token = $this->refreshUser($token);
} elseif (null !== $token) {
if (null !== $this->logger) {
- $this->logger->warning(sprintf('Session includes a "%s" where a security token is expected', is_object($token) ? get_class($token) : gettype($token)));
+ $this->logger->warning('Expected a security token from the session, got something else.', array('key' => $this->sessionKey, 'received' => $token));
}
$token = null;
}
- $this->context->setToken($token);
+ $this->tokenStorage->setToken($token);
}
/**
- * Writes the SecurityContext to the session.
+ * Writes the security token into the session.
*
* @param FilterResponseEvent $event A FilterResponseEvent instance
*/
public function onKernelResponse(FilterResponseEvent $event)
{
- if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+ if (!$event->isMasterRequest()) {
return;
}
@@ -117,23 +118,19 @@ class ContextListener implements ListenerInterface
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
$this->registered = false;
- if (null !== $this->logger) {
- $this->logger->debug('Write SecurityContext in the session');
- }
-
$request = $event->getRequest();
$session = $request->getSession();
- if (null === $session) {
- return;
- }
-
- if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
+ if ((null === $token = $this->tokenStorage->getToken()) || ($token instanceof AnonymousToken)) {
if ($request->hasPreviousSession()) {
- $session->remove('_security_'.$this->contextKey);
+ $session->remove($this->sessionKey);
}
} else {
- $session->set('_security_'.$this->contextKey, serialize($token));
+ $session->set($this->sessionKey, serialize($token));
+
+ if (null !== $this->logger) {
+ $this->logger->debug('Stored the security token in the session.', array('key' => $this->sessionKey));
+ }
}
}
@@ -146,24 +143,20 @@ class ContextListener implements ListenerInterface
*
* @throws \RuntimeException
*/
- private function refreshUser(TokenInterface $token)
+ protected function refreshUser(TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return $token;
}
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Reloading user from user provider.'));
- }
-
foreach ($this->userProviders as $provider) {
try {
$refreshedUser = $provider->refreshUser($user);
$token->setUser($refreshedUser);
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $refreshedUser->getUsername()));
+ $this->logger->debug('User was reloaded from a user provider.', array('username' => $refreshedUser->getUsername(), 'provider' => get_class($provider)));
}
return $token;
@@ -171,7 +164,7 @@ class ContextListener implements ListenerInterface
// let's try the next user provider
} catch (UsernameNotFoundException $e) {
if (null !== $this->logger) {
- $this->logger->warning(sprintf('Username "%s" could not be found.', $e->getUsername()));
+ $this->logger->warning('Username could not be found in the selected user provider.', array('username' => $e->getUsername(), 'provider' => get_class($provider)));
}
return;
diff --git a/Http/Firewall/DigestAuthenticationListener.php b/Http/Firewall/DigestAuthenticationListener.php
index 4e57667..702cf33 100644
--- a/Http/Firewall/DigestAuthenticationListener.php
+++ b/Http/Firewall/DigestAuthenticationListener.php
@@ -11,13 +11,13 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Util\StringUtils;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
@@ -32,19 +32,19 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
*/
class DigestAuthenticationListener implements ListenerInterface
{
- private $securityContext;
+ private $tokenStorage;
private $provider;
private $providerKey;
private $authenticationEntryPoint;
private $logger;
- public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, $providerKey, DigestAuthenticationEntryPoint $authenticationEntryPoint, LoggerInterface $logger = null)
+ public function __construct(TokenStorageInterface $tokenStorage, UserProviderInterface $provider, $providerKey, DigestAuthenticationEntryPoint $authenticationEntryPoint, LoggerInterface $logger = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->provider = $provider;
$this->providerKey = $providerKey;
$this->authenticationEntryPoint = $authenticationEntryPoint;
@@ -68,14 +68,14 @@ class DigestAuthenticationListener implements ListenerInterface
$digestAuth = new DigestData($header);
- if (null !== $token = $this->securityContext->getToken()) {
+ if (null !== $token = $this->tokenStorage->getToken()) {
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $digestAuth->getUsername()) {
return;
}
}
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Digest Authorization header received from user agent: %s', $header));
+ $this->logger->debug('Digest Authorization header received from user agent.', array('header' => $header));
}
try {
@@ -90,7 +90,7 @@ class DigestAuthenticationListener implements ListenerInterface
$user = $this->provider->loadUserByUsername($digestAuth->getUsername());
if (null === $user) {
- throw new AuthenticationServiceException('AuthenticationDao returned null, which is an interface contract violation');
+ throw new AuthenticationServiceException('Digest User provider returned null, which is an interface contract violation');
}
$serverDigestMd5 = $digestAuth->calculateServerDigest($user->getPassword(), $request->getMethod());
@@ -102,7 +102,7 @@ class DigestAuthenticationListener implements ListenerInterface
if (!StringUtils::equals($serverDigestMd5, $digestAuth->getResponse())) {
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Expected response: "%s" but received: "%s"; is AuthenticationDao returning clear text passwords?', $serverDigestMd5, $digestAuth->getResponse()));
+ $this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', array('expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()));
}
$this->fail($event, $request, new BadCredentialsException('Incorrect response'));
@@ -117,21 +117,21 @@ class DigestAuthenticationListener implements ListenerInterface
}
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication success for user "%s" with response "%s"', $digestAuth->getUsername(), $digestAuth->getResponse()));
+ $this->logger->info('Digest authentication successful.', array('username' => $digestAuth->getUsername(), 'received' => $digestAuth->getResponse()));
}
- $this->securityContext->setToken(new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey));
+ $this->tokenStorage->setToken(new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey));
}
private function fail(GetResponseEvent $event, Request $request, AuthenticationException $authException)
{
- $token = $this->securityContext->getToken();
+ $token = $this->tokenStorage->getToken();
if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) {
- $this->securityContext->setToken(null);
+ $this->tokenStorage->setToken(null);
}
if (null !== $this->logger) {
- $this->logger->info($authException);
+ $this->logger->info('Digest authentication failed.', array('exception' => $authException));
}
$event->setResponse($this->authenticationEntryPoint->start($request, $authException));
@@ -140,7 +140,7 @@ class DigestAuthenticationListener implements ListenerInterface
class DigestData
{
- private $elements;
+ private $elements = array();
private $header;
private $nonceExpiryTime;
@@ -148,7 +148,6 @@ class DigestData
{
$this->header = $header;
preg_match_all('/(\w+)=("((?:[^"\\\\]|\\\\.)+)"|([^\s,$]+))/', $header, $matches, PREG_SET_ORDER);
- $this->elements = array();
foreach ($matches as $match) {
if (isset($match[1]) && isset($match[3])) {
$this->elements[$match[1]] = isset($match[4]) ? $match[4] : $match[3];
diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php
index 8553c75..a1cae2a 100644
--- a/Http/Firewall/ExceptionListener.php
+++ b/Http/Firewall/ExceptionListener.php
@@ -13,8 +13,9 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
@@ -38,7 +39,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class ExceptionListener
{
- private $context;
+ private $tokenStorage;
private $providerKey;
private $accessDeniedHandler;
private $authenticationEntryPoint;
@@ -48,9 +49,9 @@ class ExceptionListener
private $httpUtils;
private $stateless;
- public function __construct(SecurityContextInterface $context, AuthenticationTrustResolverInterface $trustResolver, HttpUtils $httpUtils, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null, $stateless = false)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationTrustResolverInterface $trustResolver, HttpUtils $httpUtils, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null, $stateless = false)
{
- $this->context = $context;
+ $this->tokenStorage = $tokenStorage;
$this->accessDeniedHandler = $accessDeniedHandler;
$this->httpUtils = $httpUtils;
$this->providerKey = $providerKey;
@@ -72,16 +73,22 @@ class ExceptionListener
}
/**
+ * Unregisters the dispatcher.
+ *
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ */
+ public function unregister(EventDispatcherInterface $dispatcher)
+ {
+ $dispatcher->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
+ }
+
+ /**
* Handles security related exceptions.
*
* @param GetResponseForExceptionEvent $event An GetResponseForExceptionEvent instance
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
- // we need to remove ourselves as the exception listener can be
- // different depending on the Request
- $event->getDispatcher()->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
-
$exception = $event->getException();
do {
if ($exception instanceof AuthenticationException) {
@@ -97,7 +104,7 @@ class ExceptionListener
private function handleAuthenticationException(GetResponseForExceptionEvent $event, AuthenticationException $exception)
{
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication exception occurred; redirecting to authentication entry point (%s)', $exception->getMessage()));
+ $this->logger->info('An AuthenticationException was thrown; redirecting to authentication entry point.', array('exception' => $exception));
}
try {
@@ -111,10 +118,10 @@ class ExceptionListener
{
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
- $token = $this->context->getToken();
+ $token = $this->tokenStorage->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
+ $this->logger->debug('Access denied, the user is not fully authenticated; redirecting to authentication entry point.', array('exception' => $exception));
}
try {
@@ -130,7 +137,7 @@ class ExceptionListener
}
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
+ $this->logger->debug('Access denied, the user is neither anonymous, nor remember-me.', array('exception' => $exception));
}
try {
@@ -142,13 +149,13 @@ class ExceptionListener
}
} elseif (null !== $this->errorPage) {
$subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage);
- $subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
+ $subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
}
} catch (\Exception $e) {
if (null !== $this->logger) {
- $this->logger->error(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
+ $this->logger->error('An exception was thrown when handling an AccessDeniedException.', array('exception' => $e));
}
$event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
@@ -158,7 +165,7 @@ class ExceptionListener
private function handleLogoutException(LogoutException $exception)
{
if (null !== $this->logger) {
- $this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
+ $this->logger->info('A LogoutException was thrown.', array('exception' => $exception));
}
}
@@ -177,7 +184,7 @@ class ExceptionListener
}
if (null !== $this->logger) {
- $this->logger->debug('Calling Authentication entry point');
+ $this->logger->debug('Calling Authentication entry point.');
}
if (!$this->stateless) {
@@ -186,7 +193,11 @@ class ExceptionListener
if ($authException instanceof AccountStatusException) {
// remove the security token to prevent infinite redirect loops
- $this->context->setToken(null);
+ $this->tokenStorage->setToken(null);
+
+ if (null !== $this->logger) {
+ $this->logger->info('The security token was removed due to an AccountStatusException.', array('exception' => $authException));
+ }
}
return $this->authenticationEntryPoint->start($request, $authException);
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index 5a68670..96f5685 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -11,12 +11,16 @@
namespace Symfony\Component\Security\Http\Firewall;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
use Symfony\Component\Security\Core\Exception\LogoutException;
+use Symfony\Component\Security\Csrf\CsrfToken;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
@@ -28,25 +32,31 @@ use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
*/
class LogoutListener implements ListenerInterface
{
- private $securityContext;
+ private $tokenStorage;
private $options;
private $handlers;
private $successHandler;
private $httpUtils;
- private $csrfProvider;
+ private $csrfTokenManager;
/**
* Constructor.
*
- * @param SecurityContextInterface $securityContext
- * @param HttpUtils $httpUtils An HttpUtilsInterface instance
- * @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance
- * @param array $options An array of options to process a logout attempt
- * @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance
+ * @param TokenStorageInterface $tokenStorage
+ * @param HttpUtils $httpUtils An HttpUtilsInterface instance
+ * @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance
+ * @param array $options An array of options to process a logout attempt
+ * @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance
*/
- public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), CsrfProviderInterface $csrfProvider = null)
+ public function __construct(TokenStorageInterface $tokenStorage, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), $csrfTokenManager = null)
{
- $this->securityContext = $securityContext;
+ if ($csrfTokenManager instanceof CsrfProviderInterface) {
+ $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager);
+ } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) {
+ throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
+ }
+
+ $this->tokenStorage = $tokenStorage;
$this->httpUtils = $httpUtils;
$this->options = array_merge(array(
'csrf_parameter' => '_csrf_token',
@@ -54,7 +64,7 @@ class LogoutListener implements ListenerInterface
'logout_path' => '/logout',
), $options);
$this->successHandler = $successHandler;
- $this->csrfProvider = $csrfProvider;
+ $this->csrfTokenManager = $csrfTokenManager;
$this->handlers = array();
}
@@ -71,7 +81,7 @@ class LogoutListener implements ListenerInterface
/**
* Performs the logout if requested.
*
- * If a CsrfProviderInterface instance is available, it will be used to
+ * If a CsrfTokenManagerInterface instance is available, it will be used to
* validate the request.
*
* @param GetResponseEvent $event A GetResponseEvent instance
@@ -87,10 +97,10 @@ class LogoutListener implements ListenerInterface
return;
}
- if (null !== $this->csrfProvider) {
+ if (null !== $this->csrfTokenManager) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);
- if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
throw new LogoutException('Invalid CSRF token.');
}
}
@@ -101,13 +111,13 @@ class LogoutListener implements ListenerInterface
}
// handle multiple logout attempts gracefully
- if ($token = $this->securityContext->getToken()) {
+ if ($token = $this->tokenStorage->getToken()) {
foreach ($this->handlers as $handler) {
$handler->logout($request, $response, $token);
}
}
- $this->securityContext->setToken(null);
+ $this->tokenStorage->setToken(null);
$event->setResponse($response);
}
diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php
index 52a231c..4186430 100644
--- a/Http/Firewall/RememberMeListener.php
+++ b/Http/Firewall/RememberMeListener.php
@@ -14,12 +14,13 @@ namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
/**
@@ -29,30 +30,34 @@ use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
*/
class RememberMeListener implements ListenerInterface
{
- private $securityContext;
+ private $tokenStorage;
private $rememberMeServices;
private $authenticationManager;
private $logger;
private $dispatcher;
+ private $catchExceptions = true;
private $sessionStrategy;
/**
* Constructor.
*
- * @param SecurityContextInterface $securityContext
- * @param RememberMeServicesInterface $rememberMeServices
- * @param AuthenticationManagerInterface $authenticationManager
- * @param LoggerInterface $logger
- * @param EventDispatcherInterface $dispatcher
+ * @param TokenStorageInterface $tokenStorage
+ * @param RememberMeServicesInterface $rememberMeServices
+ * @param AuthenticationManagerInterface $authenticationManager
+ * @param LoggerInterface $logger
+ * @param EventDispatcherInterface $dispatcher
+ * @param bool $catchExceptions
+ * @param SessionAuthenticationStrategyInterface $sessionStrategy
*/
- public function __construct(SecurityContextInterface $securityContext, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $catchExceptions = true, SessionAuthenticationStrategyInterface $sessionStrategy = null)
{
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->rememberMeServices = $rememberMeServices;
$this->authenticationManager = $authenticationManager;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
- $this->sessionStrategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE);
+ $this->catchExceptions = $catchExceptions;
+ $this->sessionStrategy = null === $sessionStrategy ? new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE) : $sessionStrategy;
}
/**
@@ -62,7 +67,7 @@ class RememberMeListener implements ListenerInterface
*/
public function handle(GetResponseEvent $event)
{
- if (null !== $this->securityContext->getToken()) {
+ if (null !== $this->tokenStorage->getToken()) {
return;
}
@@ -73,12 +78,10 @@ class RememberMeListener implements ListenerInterface
try {
$token = $this->authenticationManager->authenticate($token);
-
if ($request->hasSession() && $request->getSession()->isStarted()) {
$this->sessionStrategy->onAuthentication($request, $token);
}
-
- $this->securityContext->setToken($token);
+ $this->tokenStorage->setToken($token);
if (null !== $this->dispatcher) {
$loginEvent = new InteractiveLoginEvent($request, $token);
@@ -86,18 +89,22 @@ class RememberMeListener implements ListenerInterface
}
if (null !== $this->logger) {
- $this->logger->debug('SecurityContext populated with remember-me token.');
+ $this->logger->debug('Populated the token storage with a remember-me token.');
}
} catch (AuthenticationException $e) {
if (null !== $this->logger) {
$this->logger->warning(
- 'SecurityContext not populated with remember-me token as the'
+ 'The token storage was not populated with remember-me token as the'
.' AuthenticationManager rejected the AuthenticationToken returned'
- .' by the RememberMeServices: '.$e->getMessage()
+ .' by the RememberMeServices.', array('exception' => $e)
);
}
$this->rememberMeServices->loginFail($request);
+
+ if (!$this->catchExceptions) {
+ throw $e;
+ }
}
}
}
diff --git a/Http/Firewall/RemoteUserAuthenticationListener.php b/Http/Firewall/RemoteUserAuthenticationListener.php
new file mode 100644
index 0000000..c42badf
--- /dev/null
+++ b/Http/Firewall/RemoteUserAuthenticationListener.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Firewall;
+
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * REMOTE_USER authentication listener.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Maxime Douailin <maxime.douailin@gmail.com>
+ */
+class RemoteUserAuthenticationListener extends AbstractPreAuthenticatedListener
+{
+ private $userKey;
+
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, $userKey = 'REMOTE_USER', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ {
+ parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher);
+
+ $this->userKey = $userKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getPreAuthenticatedData(Request $request)
+ {
+ if (!$request->server->has($this->userKey)) {
+ throw new BadCredentialsException(sprintf('User key was not found: %s', $this->userKey));
+ }
+
+ return array($request->server->get($this->userKey), null);
+ }
+}
diff --git a/Http/Firewall/SimpleFormAuthenticationListener.php b/Http/Firewall/SimpleFormAuthenticationListener.php
new file mode 100644
index 0000000..8123e0e
--- /dev/null
+++ b/Http/Firewall/SimpleFormAuthenticationListener.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Firewall;
+
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
+use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
+use Symfony\Component\Security\Csrf\CsrfToken;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
+use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\Security\Core\Security;
+use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
+{
+ private $simpleAuthenticator;
+ private $csrfTokenManager;
+
+ /**
+ * Constructor.
+ *
+ * @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
+ * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
+ * @param SessionAuthenticationStrategyInterface $sessionStrategy
+ * @param HttpUtils $httpUtils An HttpUtilsInterface instance
+ * @param string $providerKey
+ * @param AuthenticationSuccessHandlerInterface $successHandler
+ * @param AuthenticationFailureHandlerInterface $failureHandler
+ * @param array $options An array of options for the processing of a
+ * successful, or failed authentication attempt
+ * @param LoggerInterface $logger A LoggerInterface instance
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ * @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance
+ * @param SimpleFormAuthenticatorInterface $simpleAuthenticator A SimpleFormAuthenticatorInterface instance
+ *
+ * @throws \InvalidArgumentException In case no simple authenticator is provided
+ * @throws InvalidArgumentException In case an invalid CSRF token manager is passed
+ */
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $csrfTokenManager = null, SimpleFormAuthenticatorInterface $simpleAuthenticator = null)
+ {
+ if (!$simpleAuthenticator) {
+ throw new \InvalidArgumentException('Missing simple authenticator');
+ }
+
+ if ($csrfTokenManager instanceof CsrfProviderInterface) {
+ $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager);
+ } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) {
+ throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
+ }
+
+ $this->simpleAuthenticator = $simpleAuthenticator;
+ $this->csrfTokenManager = $csrfTokenManager;
+
+ $options = array_merge(array(
+ 'username_parameter' => '_username',
+ 'password_parameter' => '_password',
+ 'csrf_parameter' => '_csrf_token',
+ 'intention' => 'authenticate',
+ 'post_only' => true,
+ ), $options);
+
+ parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, $options, $logger, $dispatcher);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function requiresAuthentication(Request $request)
+ {
+ if ($this->options['post_only'] && !$request->isMethod('POST')) {
+ return false;
+ }
+
+ return parent::requiresAuthentication($request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function attemptAuthentication(Request $request)
+ {
+ if (null !== $this->csrfTokenManager) {
+ $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
+ throw new InvalidCsrfTokenException('Invalid CSRF token.');
+ }
+ }
+
+ if ($this->options['post_only']) {
+ $username = trim($request->request->get($this->options['username_parameter'], null, true));
+ $password = $request->request->get($this->options['password_parameter'], null, true);
+ } else {
+ $username = trim($request->get($this->options['username_parameter'], null, true));
+ $password = $request->get($this->options['password_parameter'], null, true);
+ }
+
+ if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
+ throw new BadCredentialsException('Invalid username.');
+ }
+
+ $request->getSession()->set(Security::LAST_USERNAME, $username);
+
+ $token = $this->simpleAuthenticator->createToken($request, $username, $password, $this->providerKey);
+
+ return $this->authenticationManager->authenticate($token);
+ }
+}
diff --git a/Http/Firewall/SimplePreAuthenticationListener.php b/Http/Firewall/SimplePreAuthenticationListener.php
new file mode 100644
index 0000000..8f1f6fd
--- /dev/null
+++ b/Http/Firewall/SimplePreAuthenticationListener.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Firewall;
+
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface;
+use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
+use Symfony\Component\Security\Http\SecurityEvents;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * SimplePreAuthenticationListener implements simple proxying to an authenticator.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class SimplePreAuthenticationListener implements ListenerInterface
+{
+ private $tokenStorage;
+ private $authenticationManager;
+ private $providerKey;
+ private $simpleAuthenticator;
+ private $logger;
+ private $dispatcher;
+
+ /**
+ * Constructor.
+ *
+ * @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance
+ * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
+ * @param string $providerKey
+ * @param SimplePreAuthenticatorInterface $simpleAuthenticator A SimplePreAuthenticatorInterface instance
+ * @param LoggerInterface $logger A LoggerInterface instance
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ */
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, SimplePreAuthenticatorInterface $simpleAuthenticator, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ {
+ if (empty($providerKey)) {
+ throw new \InvalidArgumentException('$providerKey must not be empty.');
+ }
+
+ $this->tokenStorage = $tokenStorage;
+ $this->authenticationManager = $authenticationManager;
+ $this->providerKey = $providerKey;
+ $this->simpleAuthenticator = $simpleAuthenticator;
+ $this->logger = $logger;
+ $this->dispatcher = $dispatcher;
+ }
+
+ /**
+ * Handles basic authentication.
+ *
+ * @param GetResponseEvent $event A GetResponseEvent instance
+ */
+ public function handle(GetResponseEvent $event)
+ {
+ $request = $event->getRequest();
+
+ if (null !== $this->logger) {
+ $this->logger->info('Attempting SimplePreAuthentication.', array('key' => $this->providerKey, 'authenticator' => get_class($this->simpleAuthenticator)));
+ }
+
+ if (null !== $this->tokenStorage->getToken() && !$this->tokenStorage->getToken() instanceof AnonymousToken) {
+ return;
+ }
+
+ try {
+ $token = $this->simpleAuthenticator->createToken($request, $this->providerKey);
+
+ // allow null to be returned to skip authentication
+ if (null === $token) {
+ return;
+ }
+
+ $token = $this->authenticationManager->authenticate($token);
+ $this->tokenStorage->setToken($token);
+
+ if (null !== $this->dispatcher) {
+ $loginEvent = new InteractiveLoginEvent($request, $token);
+ $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent);
+ }
+ } catch (AuthenticationException $e) {
+ $this->tokenStorage->setToken(null);
+
+ if (null !== $this->logger) {
+ $this->logger->info('SimplePreAuthentication request failed.', array('exception' => $e, 'authenticator' => get_class($this->simpleAuthenticator)));
+ }
+
+ if ($this->simpleAuthenticator instanceof AuthenticationFailureHandlerInterface) {
+ $response = $this->simpleAuthenticator->onAuthenticationFailure($request, $e);
+ if ($response instanceof Response) {
+ $event->setResponse($response);
+ } elseif (null !== $response) {
+ throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationFailure method must return null or a Response object', get_class($this->simpleAuthenticator)));
+ }
+ }
+
+ return;
+ }
+
+ if ($this->simpleAuthenticator instanceof AuthenticationSuccessHandlerInterface) {
+ $response = $this->simpleAuthenticator->onAuthenticationSuccess($request, $token);
+ if ($response instanceof Response) {
+ $event->setResponse($response);
+ } elseif (null !== $response) {
+ throw new \UnexpectedValueException(sprintf('The %s::onAuthenticationSuccess method must return null or a Response object', get_class($this->simpleAuthenticator)));
+ }
+ }
+ }
+}
diff --git a/Http/Firewall/SwitchUserListener.php b/Http/Firewall/SwitchUserListener.php
index b983b68..7de83d2 100644
--- a/Http/Firewall/SwitchUserListener.php
+++ b/Http/Firewall/SwitchUserListener.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
@@ -24,6 +23,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
@@ -38,7 +38,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class SwitchUserListener implements ListenerInterface
{
- private $securityContext;
+ private $tokenStorage;
private $provider;
private $userChecker;
private $providerKey;
@@ -48,16 +48,13 @@ class SwitchUserListener implements ListenerInterface
private $logger;
private $dispatcher;
- /**
- * Constructor.
- */
- public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventDispatcherInterface $dispatcher = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
- $this->securityContext = $securityContext;
+ $this->tokenStorage = $tokenStorage;
$this->provider = $provider;
$this->userChecker = $userChecker;
$this->providerKey = $providerKey;
@@ -84,16 +81,18 @@ class SwitchUserListener implements ListenerInterface
}
if ('_exit' === $request->get($this->usernameParameter)) {
- $this->securityContext->setToken($this->attemptExitUser($request));
+ $this->tokenStorage->setToken($this->attemptExitUser($request));
} else {
try {
- $this->securityContext->setToken($this->attemptSwitchUser($request));
+ $this->tokenStorage->setToken($this->attemptSwitchUser($request));
} catch (AuthenticationException $e) {
throw new \LogicException(sprintf('Switch User failed: "%s"', $e->getMessage()));
}
}
- $request->server->set('QUERY_STRING', '');
+ $request->query->remove($this->usernameParameter);
+ $request->server->set('QUERY_STRING', http_build_query($request->query->all()));
+
$response = new RedirectResponse($request->getUri(), 302);
$event->setResponse($response);
@@ -111,7 +110,7 @@ class SwitchUserListener implements ListenerInterface
*/
private function attemptSwitchUser(Request $request)
{
- $token = $this->securityContext->getToken();
+ $token = $this->tokenStorage->getToken();
$originalToken = $this->getOriginalToken($token);
if (false !== $originalToken) {
@@ -129,14 +128,14 @@ class SwitchUserListener implements ListenerInterface
$username = $request->get($this->usernameParameter);
if (null !== $this->logger) {
- $this->logger->info(sprintf('Attempt to switch to user "%s"', $username));
+ $this->logger->info('Attempting to switch to user.', array('username' => $username));
}
$user = $this->provider->loadUserByUsername($username);
$this->userChecker->checkPostAuth($user);
$roles = $user->getRoles();
- $roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->securityContext->getToken());
+ $roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken());
$token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey, $roles);
@@ -159,7 +158,7 @@ class SwitchUserListener implements ListenerInterface
*/
private function attemptExitUser(Request $request)
{
- if (false === $original = $this->getOriginalToken($this->securityContext->getToken())) {
+ if (false === $original = $this->getOriginalToken($this->tokenStorage->getToken())) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 26aeb67..ba4329b 100644
--- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -11,18 +11,23 @@
namespace Symfony\Component\Security\Http\Firewall;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Csrf\CsrfToken;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
@@ -33,14 +38,17 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationListener
{
- private $csrfProvider;
+ private $csrfTokenManager;
- /**
- * {@inheritdoc}
- */
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $csrfTokenManager = null)
{
- parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
+ if ($csrfTokenManager instanceof CsrfProviderInterface) {
+ $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager);
+ } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) {
+ throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
+ }
+
+ parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
@@ -48,7 +56,7 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
'post_only' => true,
), $options), $logger, $dispatcher);
- $this->csrfProvider = $csrfProvider;
+ $this->csrfTokenManager = $csrfTokenManager;
}
/**
@@ -68,10 +76,10 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
*/
protected function attemptAuthentication(Request $request)
{
- if (null !== $this->csrfProvider) {
+ if (null !== $this->csrfTokenManager) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);
- if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}
@@ -84,11 +92,11 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
$password = $request->get($this->options['password_parameter'], null, true);
}
- if (strlen($username) > SecurityContextInterface::MAX_USERNAME_LENGTH) {
+ if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
throw new BadCredentialsException('Invalid username.');
}
- $request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);
+ $request->getSession()->set(Security::LAST_USERNAME, $username);
return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey));
}
diff --git a/Http/Firewall/X509AuthenticationListener.php b/Http/Firewall/X509AuthenticationListener.php
index 9c07be1..326c9af 100644
--- a/Http/Firewall/X509AuthenticationListener.php
+++ b/Http/Firewall/X509AuthenticationListener.php
@@ -11,8 +11,8 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
@@ -28,9 +28,9 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener
private $userKey;
private $credentialKey;
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, $userKey = 'SSL_CLIENT_S_DN_Email', $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $providerKey, $userKey = 'SSL_CLIENT_S_DN_Email', $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
- parent::__construct($securityContext, $authenticationManager, $providerKey, $logger, $dispatcher);
+ parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher);
$this->userKey = $userKey;
$this->credentialKey = $credentialKey;
diff --git a/Http/HttpUtils.php b/Http/HttpUtils.php
index 0f47809..ed737a2 100644
--- a/Http/HttpUtils.php
+++ b/Http/HttpUtils.php
@@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Http;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
@@ -19,6 +18,7 @@ use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Security\Core\Security;
/**
* Encapsulates the logic needed to create sub-requests, redirect the user, and match URLs.
@@ -71,19 +71,19 @@ class HttpUtils
*/
public function createRequest(Request $request, $path)
{
- $newRequest = $request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
+ $newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
if ($request->hasSession()) {
$newRequest->setSession($request->getSession());
}
- if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
- $newRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR));
+ if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
+ $newRequest->attributes->set(Security::AUTHENTICATION_ERROR, $request->attributes->get(Security::AUTHENTICATION_ERROR));
}
- if ($request->attributes->has(SecurityContextInterface::ACCESS_DENIED_ERROR)) {
- $newRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $request->attributes->get(SecurityContextInterface::ACCESS_DENIED_ERROR));
+ if ($request->attributes->has(Security::ACCESS_DENIED_ERROR)) {
+ $newRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $request->attributes->get(Security::ACCESS_DENIED_ERROR));
}
- if ($request->attributes->has(SecurityContextInterface::LAST_USERNAME)) {
- $newRequest->attributes->set(SecurityContextInterface::LAST_USERNAME, $request->attributes->get(SecurityContextInterface::LAST_USERNAME));
+ if ($request->attributes->has(Security::LAST_USERNAME)) {
+ $newRequest->attributes->set(Security::LAST_USERNAME, $request->attributes->get(Security::LAST_USERNAME));
}
return $newRequest;
diff --git a/Http/LICENSE b/Http/LICENSE
new file mode 100644
index 0000000..12a7453
--- /dev/null
+++ b/Http/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2016 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Http/Logout/LogoutUrlGenerator.php b/Http/Logout/LogoutUrlGenerator.php
new file mode 100644
index 0000000..4ad63cc
--- /dev/null
+++ b/Http/Logout/LogoutUrlGenerator.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Logout;
+
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
+
+/**
+ * Provides generator functions for the logout URL.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jeremy Mikola <jmikola@gmail.com>
+ */
+class LogoutUrlGenerator
+{
+ private $requestStack;
+ private $router;
+ private $tokenStorage;
+ private $listeners = array();
+
+ public function __construct(RequestStack $requestStack = null, UrlGeneratorInterface $router = null, TokenStorageInterface $tokenStorage = null)
+ {
+ $this->requestStack = $requestStack;
+ $this->router = $router;
+ $this->tokenStorage = $tokenStorage;
+ }
+
+ /**
+ * Registers a firewall's LogoutListener, allowing its URL to be generated.
+ *
+ * @param string $key The firewall key
+ * @param string $logoutPath The path that starts the logout process
+ * @param string $csrfTokenId The ID of the CSRF token
+ * @param string $csrfParameter The CSRF token parameter name
+ * @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance
+ */
+ public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager = null)
+ {
+ if ($csrfTokenManager instanceof CsrfProviderInterface) {
+ $csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager);
+ } elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) {
+ throw new \InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
+ }
+
+ $this->listeners[$key] = array($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager);
+ }
+
+ /**
+ * Generates the absolute logout path for the firewall.
+ *
+ * @param string|null $key The firewall key or null to use the current firewall key
+ *
+ * @return string The logout path
+ */
+ public function getLogoutPath($key = null)
+ {
+ return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * Generates the absolute logout URL for the firewall.
+ *
+ * @param string|null $key The firewall key or null to use the current firewall key
+ *
+ * @return string The logout URL
+ */
+ public function getLogoutUrl($key = null)
+ {
+ return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * Generates the logout URL for the firewall.
+ *
+ * @param string|null $key The firewall key or null to use the current firewall key
+ * @param bool|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
+ *
+ * @return string The logout URL
+ *
+ * @throws \InvalidArgumentException if no LogoutListener is registered for the key or the key could not be found automatically.
+ */
+ private function generateLogoutUrl($key, $referenceType)
+ {
+ // Fetch the current provider key from token, if possible
+ if (null === $key && null !== $this->tokenStorage) {
+ $token = $this->tokenStorage->getToken();
+ if (null !== $token && method_exists($token, 'getProviderKey')) {
+ $key = $token->getProviderKey();
+ }
+ }
+
+ if (null === $key) {
+ throw new \InvalidArgumentException('Unable to find the current firewall LogoutListener, please provide the provider key manually.');
+ }
+
+ if (!array_key_exists($key, $this->listeners)) {
+ throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
+ }
+
+ list($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager) = $this->listeners[$key];
+
+ $parameters = null !== $csrfTokenManager ? array($csrfParameter => (string) $csrfTokenManager->getToken($csrfTokenId)) : array();
+
+ if ('/' === $logoutPath[0]) {
+ if (!$this->requestStack) {
+ throw new \LogicException('Unable to generate the logout URL without a RequestStack.');
+ }
+
+ $request = $this->requestStack->getCurrentRequest();
+
+ $url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBaseUrl().$logoutPath;
+
+ if (!empty($parameters)) {
+ $url .= '?'.http_build_query($parameters);
+ }
+ } else {
+ if (!$this->router) {
+ throw new \LogicException('Unable to generate the logout URL without a Router.');
+ }
+
+ $url = $this->router->generate($logoutPath, $parameters, $referenceType);
+ }
+
+ return $url;
+ }
+}
diff --git a/Http/README.md b/Http/README.md
new file mode 100644
index 0000000..5be2111
--- /dev/null
+++ b/Http/README.md
@@ -0,0 +1,16 @@
+Security Component - HTTP Integration
+=====================================
+
+Security provides an infrastructure for sophisticated authorization systems,
+which makes it possible to easily separate the actual authorization logic from
+so called user providers that hold the users credentials. It is inspired by
+the Java Spring framework.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/security/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index be22a1d..cd8640d 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -140,7 +140,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
} catch (AuthenticationException $e) {
if (null !== $this->logger) {
- $this->logger->debug('Remember-Me authentication failed: '.$e->getMessage());
+ $this->logger->debug('Remember-Me authentication failed.', array('exception' => $e));
}
}
@@ -293,7 +293,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
protected function cancelCookie(Request $request)
{
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Clearing remember-me cookie "%s"', $this->options['name']));
+ $this->logger->debug('Clearing remember-me cookie.', array('name' => $this->options['name']));
}
$request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'], $this->options['httponly']));
@@ -315,7 +315,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
$parameter = $request->get($this->options['remember_me_parameter'], null, true);
if (null === $parameter && null !== $this->logger) {
- $this->logger->debug(sprintf('Did not send remember-me cookie (remember-me parameter "%s" was not sent).', $this->options['remember_me_parameter']));
+ $this->logger->debug('Did not send remember-me cookie.', array('parameter' => $this->options['remember_me_parameter']));
}
return $parameter === 'true' || $parameter === 'on' || $parameter === '1' || $parameter === 'yes';
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index 0fffbfe..cbbbb23 100644
--- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -45,7 +45,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
* @param LoggerInterface $logger
* @param SecureRandomInterface $secureRandom
*/
- public function __construct(array $userProviders, $key, $providerKey, array $options = array(), LoggerInterface $logger = null, SecureRandomInterface $secureRandom)
+ public function __construct(array $userProviders, $key, $providerKey, array $options, LoggerInterface $logger = null, SecureRandomInterface $secureRandom)
{
parent::__construct($userProviders, $key, $providerKey, $options, $logger);
@@ -99,7 +99,6 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
throw new AuthenticationException('The cookie has expired.');
}
- $series = $persistentToken->getSeries();
$tokenValue = base64_encode($this->secureRandom->nextBytes(64));
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
$request->attributes->set(self::COOKIE_ATTR_NAME,
diff --git a/Http/RememberMe/RememberMeServicesInterface.php b/Http/RememberMe/RememberMeServicesInterface.php
index 7adb827..5750a8c 100644
--- a/Http/RememberMe/RememberMeServicesInterface.php
+++ b/Http/RememberMe/RememberMeServicesInterface.php
@@ -36,8 +36,8 @@ interface RememberMeServicesInterface
const COOKIE_ATTR_NAME = '_security_remember_me_cookie';
/**
- * This method will be called whenever the SecurityContext does not contain
- * an TokenInterface object and the framework wishes to provide an implementation
+ * This method will be called whenever the TokenStorage does not contain
+ * a TokenInterface object and the framework wishes to provide an implementation
* with an opportunity to authenticate the request using remember-me capabilities.
*
* No attempt whatsoever is made to determine whether the browser has requested
diff --git a/Http/RememberMe/ResponseListener.php b/Http/RememberMe/ResponseListener.php
index ec5f006..4149fb6 100644
--- a/Http/RememberMe/ResponseListener.php
+++ b/Http/RememberMe/ResponseListener.php
@@ -13,7 +13,6 @@ namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
@@ -28,7 +27,7 @@ class ResponseListener implements EventSubscriberInterface
*/
public function onKernelResponse(FilterResponseEvent $event)
{
- if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+ if (!$event->isMasterRequest()) {
return;
}
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index 1aea5fd..d68ada5 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -54,7 +54,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user)));
}
- if (!StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
+ if (true !== StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
throw new AuthenticationException('The cookie\'s hash is invalid.');
}
@@ -121,6 +121,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function generateCookieHash($class, $username, $expires, $password)
{
- return hash('sha256', $class.$username.$expires.$password.$this->getKey());
+ return hash_hmac('sha256', $class.$username.$expires.$password, $this->getKey());
}
}
diff --git a/Http/Session/SessionAuthenticationStrategyInterface.php b/Http/Session/SessionAuthenticationStrategyInterface.php
index 9cb95d8..dd0c381 100644
--- a/Http/Session/SessionAuthenticationStrategyInterface.php
+++ b/Http/Session/SessionAuthenticationStrategyInterface.php
@@ -27,7 +27,7 @@ interface SessionAuthenticationStrategyInterface
/**
* This performs any necessary changes to the session.
*
- * This method is called before the SecurityContext is populated with a
+ * This method is called before the TokenStorage is populated with a
* Token, and only by classes inheriting from AbstractAuthenticationListener.
*
* @param Request $request
diff --git a/Tests/Http/AccessMapTest.php b/Http/Tests/AccessMapTest.php
index c2d9b7f..d8ab7aa 100644
--- a/Tests/Http/AccessMapTest.php
+++ b/Http/Tests/AccessMapTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http;
+namespace Symfony\Component\Security\Http\Tests;
use Symfony\Component\Security\Http\AccessMap;
diff --git a/Tests/Http/Authentication/DefaultAuthenticationFailureHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
index 38072d6..82b5533 100644
--- a/Tests/Http/Authentication/DefaultAuthenticationFailureHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
@@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Authentication;
+namespace Symfony\Component\Security\Http\Tests\Authentication;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
-use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCase
@@ -47,7 +47,7 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
- ->method('set')->with(SecurityContextInterface::AUTHENTICATION_ERROR, $this->exception);
+ ->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($subRequest));
@@ -79,7 +79,7 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
public function testExceptionIsPersistedInSession()
{
$this->session->expects($this->once())
- ->method('set')->with(SecurityContextInterface::AUTHENTICATION_ERROR, $this->exception);
+ ->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
@@ -91,7 +91,7 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
- ->method('set')->with(SecurityContextInterface::AUTHENTICATION_ERROR, $this->exception);
+ ->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
@@ -105,7 +105,10 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
public function testRedirectIsLogged()
{
- $this->logger->expects($this->once())->method('debug')->with('Redirecting to /login');
+ $this->logger
+ ->expects($this->once())
+ ->method('debug')
+ ->with('Authentication failure, redirect triggered.', array('failure_path' => '/login'));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
@@ -119,7 +122,10 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($this->getRequest()));
- $this->logger->expects($this->once())->method('debug')->with('Forwarding to /login');
+ $this->logger
+ ->expects($this->once())
+ ->method('debug')
+ ->with('Authentication failure, forward triggered.', array('failure_path' => '/login'));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
diff --git a/Tests/Http/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
index 3d8ebf3..4d1847d 100644
--- a/Tests/Http/Authentication/DefaultAuthenticationSuccessHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Authentication;
+namespace Symfony\Component\Security\Http\Tests\Authentication;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
diff --git a/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php b/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php
new file mode 100644
index 0000000..6e79b07
--- /dev/null
+++ b/Http/Tests/Authentication/SimpleAuthenticationHandlerTest.php
@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Tests;
+
+use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\Authentication\SimpleAuthenticationHandler;
+
+class SimpleAuthenticationHandlerTest extends \PHPUnit_Framework_TestCase
+{
+ private $successHandler;
+
+ private $failureHandler;
+
+ private $request;
+
+ private $token;
+
+ private $authenticationException;
+
+ private $response;
+
+ protected function setUp()
+ {
+ $this->successHandler = $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface');
+ $this->failureHandler = $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface');
+
+ $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ // No methods are invoked on the exception; we just assert on its class
+ $this->authenticationException = new AuthenticationException();
+
+ $this->response = $this->getMock('Symfony\Component\HttpFoundation\Response');
+ }
+
+ public function testOnAuthenticationSuccessFallsBackToDefaultHandlerIfSimpleIsNotASuccessHandler()
+ {
+ $authenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface');
+
+ $this->successHandler->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token)
+ ->will($this->returnValue($this->response));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationSuccess($this->request, $this->token);
+
+ $this->assertSame($this->response, $result);
+ }
+
+ public function testOnAuthenticationSuccessCallsSimpleAuthenticator()
+ {
+ $this->successHandler->expects($this->never())
+ ->method('onAuthenticationSuccess');
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token)
+ ->will($this->returnValue($this->response));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationSuccess($this->request, $this->token);
+
+ $this->assertSame($this->response, $result);
+ }
+
+ /**
+ * @expectedException \UnexpectedValueException
+ * @expectedExceptionMessage onAuthenticationSuccess method must return null to use the default success handler, or a Response object
+ */
+ public function testOnAuthenticationSuccessThrowsAnExceptionIfNonResponseIsReturned()
+ {
+ $this->successHandler->expects($this->never())
+ ->method('onAuthenticationSuccess');
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token)
+ ->will($this->returnValue(new \stdClass()));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $handler->onAuthenticationSuccess($this->request, $this->token);
+ }
+
+ public function testOnAuthenticationSuccessFallsBackToDefaultHandlerIfNullIsReturned()
+ {
+ $this->successHandler->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token)
+ ->will($this->returnValue($this->response));
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token)
+ ->will($this->returnValue(null));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationSuccess($this->request, $this->token);
+
+ $this->assertSame($this->response, $result);
+ }
+
+ public function testOnAuthenticationFailureFallsBackToDefaultHandlerIfSimpleIsNotAFailureHandler()
+ {
+ $authenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface');
+
+ $this->failureHandler->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $this->authenticationException)
+ ->will($this->returnValue($this->response));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
+
+ $this->assertSame($this->response, $result);
+ }
+
+ public function testOnAuthenticationFailureCallsSimpleAuthenticator()
+ {
+ $this->failureHandler->expects($this->never())
+ ->method('onAuthenticationFailure');
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $this->authenticationException)
+ ->will($this->returnValue($this->response));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
+
+ $this->assertSame($this->response, $result);
+ }
+
+ /**
+ * @expectedException \UnexpectedValueException
+ * @expectedExceptionMessage onAuthenticationFailure method must return null to use the default failure handler, or a Response object
+ */
+ public function testOnAuthenticationFailureThrowsAnExceptionIfNonResponseIsReturned()
+ {
+ $this->failureHandler->expects($this->never())
+ ->method('onAuthenticationFailure');
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $this->authenticationException)
+ ->will($this->returnValue(new \stdClass()));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $handler->onAuthenticationFailure($this->request, $this->authenticationException);
+ }
+
+ public function testOnAuthenticationFailureFallsBackToDefaultHandlerIfNullIsReturned()
+ {
+ $this->failureHandler->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $this->authenticationException)
+ ->will($this->returnValue($this->response));
+
+ $authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
+ $authenticator->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $this->authenticationException)
+ ->will($this->returnValue(null));
+
+ $handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
+ $result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
+
+ $this->assertSame($this->response, $result);
+ }
+}
+
+interface TestSuccessHandlerInterface extends AuthenticationSuccessHandlerInterface, SimpleAuthenticatorInterface
+{
+}
+
+interface TestFailureHandlerInterface extends AuthenticationFailureHandlerInterface, SimpleAuthenticatorInterface
+{
+}
diff --git a/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php b/Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php
index 5640789..ca5922c 100644
--- a/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php
+++ b/Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\EntryPoint;
+namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
diff --git a/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php b/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php
index 5c6eccc..181e340 100644
--- a/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php
+++ b/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\EntryPoint;
+namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
diff --git a/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php b/Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php
index 097912d..3acb9c2 100644
--- a/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php
+++ b/Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\EntryPoint;
+namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint;
use Symfony\Component\HttpKernel\HttpKernelInterface;
diff --git a/Tests/Http/EntryPoint/RetryAuthenticationEntryPointTest.php b/Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php
index 59ec912..ff5fbc2 100644
--- a/Tests/Http/EntryPoint/RetryAuthenticationEntryPointTest.php
+++ b/Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\EntryPoint;
+namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint;
use Symfony\Component\HttpFoundation\Request;
diff --git a/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php b/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php
index d6373b3..61f086a 100644
--- a/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php
+++ b/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
@@ -26,13 +26,13 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
- $context
+ $tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
@@ -47,7 +47,7 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
));
@@ -72,13 +72,13 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
$request = new Request(array(), array(), array(), array(), array(), array());
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
- $context
+ $tokenStorage
->expects($this->never())
->method('setToken')
;
@@ -93,7 +93,7 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
));
@@ -120,13 +120,13 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
$request = new Request(array(), array(), array(), array(), array(), array());
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
- $context
+ $tokenStorage
->expects($this->never())
->method('setToken')
;
@@ -141,7 +141,7 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
));
@@ -168,8 +168,8 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
@@ -182,7 +182,7 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
));
@@ -209,13 +209,13 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
$token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
- $context
+ $tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo(null))
@@ -231,7 +231,7 @@ class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
));
diff --git a/Tests/Http/Firewall/AccessListenerTest.php b/Http/Tests/Firewall/AccessListenerTest.php
index 961c792..af9d565 100644
--- a/Tests/Http/Firewall/AccessListenerTest.php
+++ b/Http/Tests/Firewall/AccessListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\Security\Http\Firewall\AccessListener;
@@ -37,8 +37,8 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(true))
;
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
@@ -53,7 +53,7 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new AccessListener(
- $context,
+ $tokenStorage,
$accessDecisionManager,
$accessMap,
$this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')
@@ -103,13 +103,13 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($authenticatedToken))
;
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($notAuthenticatedToken))
;
- $context
+ $tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($authenticatedToken))
@@ -124,7 +124,7 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new AccessListener(
- $context,
+ $tokenStorage,
$accessDecisionManager,
$accessMap,
$authManager
@@ -158,15 +158,15 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
->method('isAuthenticated')
;
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$listener = new AccessListener(
- $context,
+ $tokenStorage,
$this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'),
$accessMap,
$this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')
@@ -185,17 +185,17 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
- public function testHandleWhenTheSecurityContextHasNoToken()
+ public function testHandleWhenTheSecurityTokenStorageHasNoToken()
{
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$listener = new AccessListener(
- $context,
+ $tokenStorage,
$this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'),
$this->getMock('Symfony\Component\Security\Http\AccessMapInterface'),
$this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')
diff --git a/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php
new file mode 100644
index 0000000..3450c1e
--- /dev/null
+++ b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Tests\Firewall;
+
+use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener;
+
+class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testHandleWithTokenStorageHavingAToken()
+ {
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
+ ->expects($this->any())
+ ->method('getToken')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
+ ;
+ $tokenStorage
+ ->expects($this->never())
+ ->method('setToken')
+ ;
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ $authenticationManager
+ ->expects($this->never())
+ ->method('authenticate')
+ ;
+
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager);
+ $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
+ }
+
+ public function testHandleWithTokenStorageHavingNoToken()
+ {
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
+ ->expects($this->any())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $anonymousToken = new AnonymousToken('TheKey', 'anon.', array());
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ $authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->with($this->callback(function ($token) {
+ return 'TheKey' === $token->getKey();
+ }))
+ ->will($this->returnValue($anonymousToken))
+ ;
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($anonymousToken)
+ ;
+
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager);
+ $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
+ }
+
+ public function testHandledEventIsLogged()
+ {
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+ $logger->expects($this->once())
+ ->method('info')
+ ->with('Populated the TokenStorage with an anonymous Token.')
+ ;
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', $logger, $authenticationManager);
+ $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
+ }
+}
diff --git a/Tests/Http/Firewall/BasicAuthenticationListenerTest.php b/Http/Tests/Firewall/BasicAuthenticationListenerTest.php
index 65dc185..8901cb2 100644
--- a/Tests/Http/Firewall/BasicAuthenticationListenerTest.php
+++ b/Http/Tests/Firewall/BasicAuthenticationListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
@@ -29,13 +29,13 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
- $context
+ $tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
@@ -50,7 +50,7 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new BasicAuthenticationListener(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
$this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')
@@ -75,13 +75,13 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
- $context
+ $tokenStorage
->expects($this->never())
->method('setToken')
;
@@ -97,7 +97,7 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new BasicAuthenticationListener(
- $context,
+ $tokenStorage,
new AuthenticationProviderManager(array($this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'))),
'TheProviderKey',
$authenticationEntryPoint
@@ -122,14 +122,14 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
{
$request = new Request();
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->never())
->method('getToken')
;
$listener = new BasicAuthenticationListener(
- $context,
+ $tokenStorage,
$this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'),
'TheProviderKey',
$this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')
@@ -151,8 +151,8 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO'));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
@@ -165,7 +165,7 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new BasicAuthenticationListener(
- $context,
+ $tokenStorage,
$authenticationManager,
'TheProviderKey',
$this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')
@@ -188,7 +188,7 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
public function testItRequiresProviderKey()
{
new BasicAuthenticationListener(
- $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
$this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'),
'',
$this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')
@@ -204,13 +204,13 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
- $context
+ $tokenStorage
->expects($this->never())
->method('setToken')
;
@@ -226,7 +226,7 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
;
$listener = new BasicAuthenticationListener(
- $context,
+ $tokenStorage,
new AuthenticationProviderManager(array($this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'))),
'TheProviderKey',
$authenticationEntryPoint
diff --git a/Tests/Http/Firewall/ChannelListenerTest.php b/Http/Tests/Firewall/ChannelListenerTest.php
index 5e583e0..1465224 100644
--- a/Tests/Http/Firewall/ChannelListenerTest.php
+++ b/Http/Tests/Firewall/ChannelListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\Security\Http\Firewall\ChannelListener;
use Symfony\Component\HttpFoundation\Response;
diff --git a/Tests/Http/Firewall/ContextListenerTest.php b/Http/Tests/Firewall/ContextListenerTest.php
index 6b4ef73..ae1199a 100644
--- a/Tests/Http/Firewall/ContextListenerTest.php
+++ b/Http/Tests/Firewall/ContextListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -18,26 +18,13 @@ use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
-use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Http\Firewall\ContextListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
class ContextListenerTest extends \PHPUnit_Framework_TestCase
{
- protected function setUp()
- {
- $this->securityContext = new SecurityContext(
- $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'),
- $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')
- );
- }
-
- protected function tearDown()
- {
- unset($this->securityContext);
- }
-
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $contextKey must not be empty
@@ -45,7 +32,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
public function testItRequiresContextKey()
{
new ContextListener(
- $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
array(),
''
);
@@ -58,7 +45,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
public function testUserProvidersNeedToImplementAnInterface()
{
new ContextListener(
- $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
array(new \stdClass()),
'key123'
);
@@ -100,7 +87,8 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
public function testOnKernelResponseWithoutSession()
{
- $this->securityContext->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
+ $tokenStorage = new TokenStorage();
+ $tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
$request = new Request();
$session = new Session(new MockArraySessionStorage());
$request->setSession($session);
@@ -112,7 +100,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
new Response()
);
- $listener = new ContextListener($this->securityContext, array(), 'session', null, new EventDispatcher());
+ $listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertTrue($session->isStarted());
@@ -131,7 +119,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
new Response()
);
- $listener = new ContextListener($this->securityContext, array(), 'session', null, new EventDispatcher());
+ $listener = new ContextListener(new TokenStorage(), array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertFalse($session->isStarted());
@@ -142,7 +130,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
*/
public function testInvalidTokenInSession($token)
{
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
@@ -162,11 +150,11 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
->method('get')
->with('_security_key123')
->will($this->returnValue($token));
- $context->expects($this->once())
+ $tokenStorage->expects($this->once())
->method('setToken')
->with(null);
- $listener = new ContextListener($context, array(), 'key123');
+ $listener = new ContextListener($tokenStorage, array(), 'key123');
$listener->handle($event);
}
@@ -181,17 +169,17 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
public function testHandleAddsKernelResponseListener()
{
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
- $listener = new ContextListener($context, array(), 'key123', null, $dispatcher);
+ $listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$event->expects($this->any())
- ->method('getRequestType')
- ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST));
+ ->method('isMasterRequest')
+ ->will($this->returnValue(true));
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($this->getMock('Symfony\Component\HttpFoundation\Request')));
@@ -205,13 +193,13 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
public function testOnKernelResponseListenerRemovesItself()
{
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')
->disableOriginalConstructor()
->getMock();
- $listener = new ContextListener($context, array(), 'key123', null, $dispatcher);
+ $listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
$request->expects($this->any())
@@ -219,8 +207,8 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(true));
$event->expects($this->any())
- ->method('getRequestType')
- ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST));
+ ->method('isMasterRequest')
+ ->will($this->returnValue(true));
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
@@ -242,10 +230,10 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context->expects($this->once())->method('setToken')->with(null);
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage->expects($this->once())->method('setToken')->with(null);
- $listener = new ContextListener($context, array(), 'key123');
+ $listener = new ContextListener($tokenStorage, array(), 'key123');
$listener->handle($event);
}
@@ -257,7 +245,8 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
$session->set('_security_session', $original);
}
- $this->securityContext->setToken($newToken);
+ $tokenStorage = new TokenStorage();
+ $tokenStorage->setToken($newToken);
$request = new Request();
$request->setSession($session);
@@ -270,7 +259,7 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
new Response()
);
- $listener = new ContextListener($this->securityContext, array(), 'session', null, new EventDispatcher());
+ $listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
return $session;
diff --git a/Tests/Http/Firewall/DigestDataTest.php b/Http/Tests/Firewall/DigestDataTest.php
index e5be6f8..a7c8d49 100644
--- a/Tests/Http/Firewall/DigestDataTest.php
+++ b/Http/Tests/Firewall/DigestDataTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\Security\Http\Firewall\DigestData;
diff --git a/Tests/Http/Firewall/ExceptionListenerTest.php b/Http/Tests/Firewall/ExceptionListenerTest.php
index 12f18a6..3d409e5 100644
--- a/Tests/Http/Firewall/ExceptionListenerTest.php
+++ b/Http/Tests/Firewall/ExceptionListenerTest.php
@@ -9,16 +9,16 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
@@ -123,10 +123,10 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
{
$event = $this->createEvent($exception);
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context->expects($this->once())->method('getToken')->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')));
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')));
- $listener = $this->createExceptionListener($context, $this->createTrustResolver(false), null, $this->createEntryPoint());
+ $listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint());
$listener->onKernelException($event);
$this->assertEquals('OK', $event->getResponse()->getContent());
@@ -166,18 +166,13 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
}
- $event = new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
-
- $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
- $event->setDispatcher($dispatcher);
-
- return $event;
+ return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
}
- private function createExceptionListener(SecurityContextInterface $context = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
+ private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
{
return new ExceptionListener(
- $context ?: $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $tokenStorage ?: $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'),
$trustResolver ?: $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'),
$httpUtils ?: $this->getMock('Symfony\Component\Security\Http\HttpUtils'),
'key',
diff --git a/Tests/Http/Firewall/LogoutListenerTest.php b/Http/Tests/Firewall/LogoutListenerTest.php
index 9301086..15c996e 100644
--- a/Tests/Http/Firewall/LogoutListenerTest.php
+++ b/Http/Tests/Firewall/LogoutListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -19,7 +19,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
{
public function testHandleUnmatchedPath()
{
- list($listener, $context, $httpUtils, $options) = $this->getListener();
+ list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener();
list($event, $request) = $this->getGetResponseEvent();
@@ -37,22 +37,21 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
public function testHandleMatchedPathWithSuccessHandlerAndCsrfValidation()
{
$successHandler = $this->getSuccessHandler();
- $csrfProvider = $this->getCsrfProvider();
+ $tokenManager = $this->getTokenManager();
- list($listener, $context, $httpUtils, $options) = $this->getListener($successHandler, $csrfProvider);
+ list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler, $tokenManager);
list($event, $request) = $this->getGetResponseEvent();
- $request->query->set('_csrf_token', $csrfToken = 'token');
+ $request->query->set('_csrf_token', 'token');
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
- $csrfProvider->expects($this->once())
- ->method('isCsrfTokenValid')
- ->with('logout', $csrfToken)
+ $tokenManager->expects($this->once())
+ ->method('isTokenValid')
->will($this->returnValue(true));
$successHandler->expects($this->once())
@@ -60,7 +59,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->with($request)
->will($this->returnValue($response = new Response()));
- $context->expects($this->once())
+ $tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
@@ -69,7 +68,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->method('logout')
->with($request, $response, $token);
- $context->expects($this->once())
+ $tokenStorage->expects($this->once())
->method('setToken')
->with(null);
@@ -86,7 +85,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
{
$successHandler = $this->getSuccessHandler();
- list($listener, $context, $httpUtils, $options) = $this->getListener($successHandler);
+ list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
@@ -100,7 +99,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->with($request)
->will($this->returnValue($response = new Response()));
- $context->expects($this->once())
+ $tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
@@ -109,7 +108,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->method('logout')
->with($request, $response, $token);
- $context->expects($this->once())
+ $tokenStorage->expects($this->once())
->method('setToken')
->with(null);
@@ -129,7 +128,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
{
$successHandler = $this->getSuccessHandler();
- list($listener, $context, $httpUtils, $options) = $this->getListener($successHandler);
+ list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
@@ -151,37 +150,34 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
*/
public function testCsrfValidationFails()
{
- $csrfProvider = $this->getCsrfProvider();
+ $tokenManager = $this->getTokenManager();
- list($listener, $context, $httpUtils, $options) = $this->getListener(null, $csrfProvider);
+ list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(null, $tokenManager);
list($event, $request) = $this->getGetResponseEvent();
- $request->query->set('_csrf_token', $csrfToken = 'token');
+ $request->query->set('_csrf_token', 'token');
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
- $csrfProvider->expects($this->once())
- ->method('isCsrfTokenValid')
- ->with('logout', $csrfToken)
+ $tokenManager->expects($this->once())
+ ->method('isTokenValid')
->will($this->returnValue(false));
$listener->handle($event);
}
- private function getCsrfProvider()
+ private function getTokenManager()
{
- return $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface');
+ return $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface');
}
- private function getContext()
+ private function getTokenStorage()
{
- return $this->getMockBuilder('Symfony\Component\Security\Core\SecurityContext')
- ->disableOriginalConstructor()
- ->getMock();
+ return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
}
private function getGetResponseEvent()
@@ -209,10 +205,10 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
}
- private function getListener($successHandler = null, $csrfProvider = null)
+ private function getListener($successHandler = null, $tokenManager = null)
{
$listener = new LogoutListener(
- $context = $this->getContext(),
+ $tokenStorage = $this->getTokenStorage(),
$httpUtils = $this->getHttpUtils(),
$successHandler ?: $this->getSuccessHandler(),
$options = array(
@@ -221,10 +217,10 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
'logout_path' => '/logout',
'target_url' => '/',
),
- $csrfProvider
+ $tokenManager
);
- return array($listener, $context, $httpUtils, $options);
+ return array($listener, $tokenStorage, $httpUtils, $options);
}
private function getSuccessHandler()
diff --git a/Http/Tests/Firewall/RememberMeListenerTest.php b/Http/Tests/Firewall/RememberMeListenerTest.php
new file mode 100644
index 0000000..7309042
--- /dev/null
+++ b/Http/Tests/Firewall/RememberMeListenerTest.php
@@ -0,0 +1,415 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Tests\Firewall;
+
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Firewall\RememberMeListener;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\SecurityEvents;
+
+class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage()
+ {
+ list($listener, $tokenStorage) = $this->getListener();
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
+ ;
+
+ $tokenStorage
+ ->expects($this->never())
+ ->method('setToken')
+ ;
+
+ $this->assertNull($listener->handle($this->getGetResponseEvent()));
+ }
+
+ public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet()
+ {
+ list($listener, $tokenStorage, $service) = $this->getListener();
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue(null))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue(new Request()))
+ ;
+
+ $this->assertNull($listener->handle($event));
+ }
+
+ public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
+ {
+ list($listener, $tokenStorage, $service, $manager) = $this->getListener();
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
+ ;
+
+ $service
+ ->expects($this->once())
+ ->method('loginFail')
+ ;
+
+ $exception = new AuthenticationException('Authentication failed.');
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->throwException($exception))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue(new Request()))
+ ;
+
+ $listener->handle($event);
+ }
+
+ /**
+ * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
+ * @expectedExceptionMessage Authentication failed.
+ */
+ public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation()
+ {
+ list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, false);
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
+ ;
+
+ $service
+ ->expects($this->once())
+ ->method('loginFail')
+ ;
+
+ $exception = new AuthenticationException('Authentication failed.');
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->throwException($exception))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue(new Request()))
+ ;
+
+ $listener->handle($event);
+ }
+
+ public function testOnCoreSecurity()
+ {
+ list($listener, $tokenStorage, $service, $manager) = $this->getListener();
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($token))
+ ;
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo($token))
+ ;
+
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->returnValue($token))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue(new Request()))
+ ;
+
+ $listener->handle($event);
+ }
+
+ public function testSessionStrategy()
+ {
+ list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true);
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($token))
+ ;
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo($token))
+ ;
+
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->returnValue($token))
+ ;
+
+ $session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface');
+ $session
+ ->expects($this->once())
+ ->method('isStarted')
+ ->will($this->returnValue(true))
+ ;
+
+ $request = $this->getMock('\Symfony\Component\HttpFoundation\Request');
+ $request
+ ->expects($this->once())
+ ->method('hasSession')
+ ->will($this->returnValue(true))
+ ;
+
+ $request
+ ->expects($this->once())
+ ->method('getSession')
+ ->will($this->returnValue($session))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue($request))
+ ;
+
+ $sessionStrategy
+ ->expects($this->once())
+ ->method('onAuthentication')
+ ->will($this->returnValue(null))
+ ;
+
+ $listener->handle($event);
+ }
+
+ public function testSessionIsMigratedByDefault()
+ {
+ list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false);
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($token))
+ ;
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo($token))
+ ;
+
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->returnValue($token))
+ ;
+
+ $session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface');
+ $session
+ ->expects($this->once())
+ ->method('isStarted')
+ ->will($this->returnValue(true))
+ ;
+ $session
+ ->expects($this->once())
+ ->method('migrate')
+ ;
+
+ $request = $this->getMock('\Symfony\Component\HttpFoundation\Request');
+ $request
+ ->expects($this->any())
+ ->method('hasSession')
+ ->will($this->returnValue(true))
+ ;
+
+ $request
+ ->expects($this->any())
+ ->method('getSession')
+ ->will($this->returnValue($session))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue($request))
+ ;
+
+ $listener->handle($event);
+ }
+
+ public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent()
+ {
+ list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true);
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $service
+ ->expects($this->once())
+ ->method('autoLogin')
+ ->will($this->returnValue($token))
+ ;
+
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo($token))
+ ;
+
+ $manager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->returnValue($token))
+ ;
+
+ $event = $this->getGetResponseEvent();
+ $request = new Request();
+ $event
+ ->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue($request))
+ ;
+
+ $dispatcher
+ ->expects($this->once())
+ ->method('dispatch')
+ ->with(
+ SecurityEvents::INTERACTIVE_LOGIN,
+ $this->isInstanceOf('Symfony\Component\Security\Http\Event\InteractiveLoginEvent')
+ )
+ ;
+
+ $listener->handle($event);
+ }
+
+ protected function getGetResponseEvent()
+ {
+ return $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
+ }
+
+ protected function getFilterResponseEvent()
+ {
+ return $this->getMock('Symfony\Component\HttpKernel\Event\FilterResponseEvent', array(), array(), '', false);
+ }
+
+ protected function getListener($withDispatcher = false, $catchExceptions = true, $withSessionStrategy = false)
+ {
+ $listener = new RememberMeListener(
+ $tokenStorage = $this->getTokenStorage(),
+ $service = $this->getService(),
+ $manager = $this->getManager(),
+ $logger = $this->getLogger(),
+ $dispatcher = ($withDispatcher ? $this->getDispatcher() : null),
+ $catchExceptions,
+ $sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null)
+ );
+
+ return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy);
+ }
+
+ protected function getLogger()
+ {
+ return $this->getMock('Psr\Log\LoggerInterface');
+ }
+
+ protected function getManager()
+ {
+ return $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+ }
+
+ protected function getService()
+ {
+ return $this->getMock('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface');
+ }
+
+ protected function getTokenStorage()
+ {
+ return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ }
+
+ protected function getDispatcher()
+ {
+ return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ }
+
+ private function getSessionStrategy()
+ {
+ return $this->getMock('\Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface');
+ }
+}
diff --git a/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php b/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php
new file mode 100644
index 0000000..dad7aad
--- /dev/null
+++ b/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Tests\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\Firewall\RemoteUserAuthenticationListener;
+
+class RemoteUserAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetPreAuthenticatedData()
+ {
+ $serverVars = array(
+ 'REMOTE_USER' => 'TheUser',
+ );
+
+ $request = new Request(array(), array(), array(), array(), array(), $serverVars);
+
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+
+ $listener = new RemoteUserAuthenticationListener(
+ $tokenStorage,
+ $authenticationManager,
+ 'TheProviderKey'
+ );
+
+ $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
+ $method->setAccessible(true);
+
+ $result = $method->invokeArgs($listener, array($request));
+ $this->assertSame($result, array('TheUser', null));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testGetPreAuthenticatedDataNoUser()
+ {
+ $request = new Request(array(), array(), array(), array(), array(), array());
+
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+
+ $listener = new RemoteUserAuthenticationListener(
+ $tokenStorage,
+ $authenticationManager,
+ 'TheProviderKey'
+ );
+
+ $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
+ $method->setAccessible(true);
+
+ $result = $method->invokeArgs($listener, array($request));
+ }
+
+ public function testGetPreAuthenticatedDataWithDifferentKeys()
+ {
+ $userCredentials = array('TheUser', null);
+
+ $request = new Request(array(), array(), array(), array(), array(), array(
+ 'TheUserKey' => 'TheUser',
+ ));
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+
+ $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
+
+ $listener = new RemoteUserAuthenticationListener(
+ $tokenStorage,
+ $authenticationManager,
+ 'TheProviderKey',
+ 'TheUserKey'
+ );
+
+ $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
+ $method->setAccessible(true);
+
+ $result = $method->invokeArgs($listener, array($request));
+ $this->assertSame($result, $userCredentials);
+ }
+}
diff --git a/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php
new file mode 100644
index 0000000..0a1286c
--- /dev/null
+++ b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Http\Tests\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
+use Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener;
+use Symfony\Component\Security\Http\SecurityEvents;
+
+class SimplePreAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ private $authenticationManager;
+ private $dispatcher;
+ private $event;
+ private $logger;
+ private $request;
+ private $tokenStorage;
+ private $token;
+
+ public function testHandle()
+ {
+ $this->tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo($this->token))
+ ;
+
+ $this->authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->with($this->equalTo($this->token))
+ ->will($this->returnValue($this->token))
+ ;
+
+ $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface');
+ $simpleAuthenticator
+ ->expects($this->once())
+ ->method('createToken')
+ ->with($this->equalTo($this->request), $this->equalTo('secured_area'))
+ ->will($this->returnValue($this->token))
+ ;
+
+ $loginEvent = new InteractiveLoginEvent($this->request, $this->token);
+
+ $this->dispatcher
+ ->expects($this->once())
+ ->method('dispatch')
+ ->with($this->equalTo(SecurityEvents::INTERACTIVE_LOGIN), $this->equalTo($loginEvent))
+ ;
+
+ $listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher);
+
+ $listener->handle($this->event);
+ }
+
+ public function testHandlecatchAuthenticationException()
+ {
+ $exception = new AuthenticationException('Authentication failed.');
+
+ $this->authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->with($this->equalTo($this->token))
+ ->will($this->throwException($exception))
+ ;
+
+ $this->tokenStorage->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo(null))
+ ;
+
+ $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface');
+ $simpleAuthenticator
+ ->expects($this->once())
+ ->method('createToken')
+ ->with($this->equalTo($this->request), $this->equalTo('secured_area'))
+ ->will($this->returnValue($this->token))
+ ;
+
+ $listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher);
+
+ $listener->handle($this->event);
+ }
+
+ protected function setUp()
+ {
+ $this->authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+
+ $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
+ $this->request = new Request(array(), array(), array(), array(), array(), array());
+
+ $this->event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
+ $this->event
+ ->expects($this->any())
+ ->method('getRequest')
+ ->will($this->returnValue($this->request))
+ ;
+
+ $this->logger = $this->getMock('Psr\Log\LoggerInterface');
+ $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ }
+
+ protected function tearDown()
+ {
+ $this->authenticationManager = null;
+ $this->dispatcher = null;
+ $this->event = null;
+ $this->logger = null;
+ $this->request = null;
+ $this->tokenStorage = null;
+ $this->token = null;
+ }
+}
diff --git a/Tests/Http/Firewall/SwitchUserListenerTest.php b/Http/Tests/Firewall/SwitchUserListenerTest.php
index 4e795c8..28d73e0 100644
--- a/Tests/Http/Firewall/SwitchUserListenerTest.php
+++ b/Http/Tests/Firewall/SwitchUserListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
@@ -17,7 +17,7 @@ use Symfony\Component\Security\Http\SecurityEvents;
class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
{
- private $securityContext;
+ private $tokenStorage;
private $userProvider;
@@ -31,11 +31,12 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
- $this->securityContext = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
$this->userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
$this->accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
$this->request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ $this->request->query = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag');
$this->request->server = $this->getMock('Symfony\Component\HttpFoundation\ServerBag');
$this->event = $this->getEvent($this->request);
}
@@ -46,7 +47,7 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
*/
public function testProviderKeyIsRequired()
{
- new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, '', $this->accessDecisionManager);
+ new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, '', $this->accessDecisionManager);
}
public function testEventIsIgnoredIfUsernameIsNotPassedWithTheRequest()
@@ -54,9 +55,9 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue(null));
$this->event->expects($this->never())->method('setResponse');
- $this->securityContext->expects($this->never())->method('setToken');
+ $this->tokenStorage->expects($this->never())->method('setToken');
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
@@ -67,10 +68,10 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
{
$token = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface')));
- $this->securityContext->expects($this->any())->method('getToken')->will($this->returnValue($token));
+ $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit'));
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
@@ -82,20 +83,22 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
$role->expects($this->any())->method('getSource')->will($this->returnValue($originalToken));
- $this->securityContext->expects($this->any())
+ $this->tokenStorage->expects($this->any())
->method('getToken')
->will($this->returnValue($this->getToken(array($role))));
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit'));
$this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
+ $this->request->query->expects($this->once())->method('remove', '_switch_user');
+ $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array()));
$this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', '');
- $this->securityContext->expects($this->once())
+ $this->tokenStorage->expects($this->once())
->method('setToken')->with($originalToken);
$this->event->expects($this->once())
->method('setResponse')->with($this->isInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse'));
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
@@ -120,7 +123,7 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
$role->expects($this->any())->method('getSource')->willReturn($originalToken);
$this
- ->securityContext
+ ->tokenStorage
->expects($this->any())
->method('getToken')
->willReturn($this->getToken(array($role)));
@@ -135,6 +138,12 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->expects($this->any())
->method('getUri')
->willReturn('/');
+ $this
+ ->request
+ ->query
+ ->expects($this->any())
+ ->method('all')
+ ->will($this->returnValue(array()));
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$dispatcher
@@ -145,7 +154,7 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
}))
;
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
$listener->handle($this->event);
}
@@ -170,7 +179,7 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->method('getSource')
->willReturn($originalToken);
$this
- ->securityContext
+ ->tokenStorage
->expects($this->any())
->method('getToken')
->willReturn($this->getToken(array($role)));
@@ -182,6 +191,12 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->willReturn('_exit');
$this
->request
+ ->query
+ ->expects($this->any())
+ ->method('all')
+ ->will($this->returnValue(array()));
+ $this
+ ->request
->expects($this->any())
->method('getUri')
->willReturn('/');
@@ -192,25 +207,25 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->method('dispatch')
;
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
$listener->handle($this->event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
- public function testSwitchUserIsDissallowed()
+ public function testSwitchUserIsDisallowed()
{
$token = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface')));
- $this->securityContext->expects($this->any())->method('getToken')->will($this->returnValue($token));
+ $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(false));
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
@@ -220,8 +235,11 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user->expects($this->any())->method('getRoles')->will($this->returnValue(array()));
- $this->securityContext->expects($this->any())->method('getToken')->will($this->returnValue($token));
+ $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
$this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
+ $this->request->query->expects($this->once())->method('remove', '_switch_user');
+ $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array()));
+
$this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
$this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', '');
@@ -234,10 +252,39 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($user));
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
- $this->securityContext->expects($this->once())
+ $this->tokenStorage->expects($this->once())
+ ->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'));
+
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener->handle($this->event);
+ }
+
+ public function testSwitchUserKeepsOtherQueryStringParameters()
+ {
+ $token = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface')));
+ $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $user->expects($this->any())->method('getRoles')->will($this->returnValue(array()));
+
+ $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token));
+ $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba'));
+ $this->request->query->expects($this->once())->method('remove', '_switch_user');
+ $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array('page' => 3, 'section' => 2)));
+ $this->request->expects($this->any())->method('getUri')->will($this->returnValue('/'));
+ $this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', 'page=3&section=2');
+
+ $this->accessDecisionManager->expects($this->once())
+ ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
+ ->will($this->returnValue(true));
+
+ $this->userProvider->expects($this->once())
+ ->method('loadUserByUsername')->with('kuba')
+ ->will($this->returnValue($user));
+ $this->userChecker->expects($this->once())
+ ->method('checkPostAuth')->with($user);
+ $this->tokenStorage->expects($this->once())
->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'));
- $listener = new SwitchUserListener($this->securityContext, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
diff --git a/Tests/Http/Firewall/X509AuthenticationListenerTest.php b/Http/Tests/Firewall/X509AuthenticationListenerTest.php
index b28c0ac..66690d9 100644
--- a/Tests/Http/Firewall/X509AuthenticationListenerTest.php
+++ b/Http/Tests/Firewall/X509AuthenticationListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Firewall;
+namespace Symfony\Component\Security\Http\Tests\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener;
@@ -31,11 +31,11 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$request = new Request(array(), array(), array(), array(), array(), $serverVars);
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey');
+ $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
@@ -60,11 +60,11 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$credentials = 'CN=Sample certificate DN/emailAddress='.$emailAddress;
$request = new Request(array(), array(), array(), array(), array(), array('SSL_CLIENT_S_DN' => $credentials));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey');
+ $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
@@ -88,11 +88,11 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
{
$request = new Request(array(), array(), array(), array(), array(), array());
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey');
+ $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
@@ -108,11 +108,11 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
'TheUserKey' => 'TheUser',
'TheCredentialsKey' => 'TheCredentials',
));
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey');
+ $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
diff --git a/Tests/Http/FirewallMapTest.php b/Http/Tests/FirewallMapTest.php
index 5d3a72a..85a57ab 100644
--- a/Tests/Http/FirewallMapTest.php
+++ b/Http/Tests/FirewallMapTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http;
+namespace Symfony\Component\Security\Http\Tests;
use Symfony\Component\Security\Http\FirewallMap;
use Symfony\Component\HttpFoundation\Request;
diff --git a/Tests/Http/FirewallTest.php b/Http/Tests/FirewallTest.php
index 7fd2cda..9994737 100644
--- a/Tests/Http/FirewallTest.php
+++ b/Http/Tests/FirewallTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http;
+namespace Symfony\Component\Security\Http\Tests;
use Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
diff --git a/Tests/Http/HttpUtilsTest.php b/Http/Tests/HttpUtilsTest.php
index 4a69242..45a0281 100644
--- a/Tests/Http/HttpUtilsTest.php
+++ b/Http/Tests/HttpUtilsTest.php
@@ -9,13 +9,13 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http;
+namespace Symfony\Component\Security\Http\Tests;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
-use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\HttpUtils;
class HttpUtilsTest extends \PHPUnit_Framework_TestCase
@@ -127,9 +127,9 @@ class HttpUtilsTest extends \PHPUnit_Framework_TestCase
public function provideSecurityContextAttributes()
{
return array(
- array(SecurityContextInterface::AUTHENTICATION_ERROR),
- array(SecurityContextInterface::ACCESS_DENIED_ERROR),
- array(SecurityContextInterface::LAST_USERNAME),
+ array(Security::AUTHENTICATION_ERROR),
+ array(Security::ACCESS_DENIED_ERROR),
+ array(Security::LAST_USERNAME),
);
}
diff --git a/Tests/Http/Logout/CookieClearingLogoutHandlerTest.php b/Http/Tests/Logout/CookieClearingLogoutHandlerTest.php
index c443d8d..8474504 100644
--- a/Tests/Http/Logout/CookieClearingLogoutHandlerTest.php
+++ b/Http/Tests/Logout/CookieClearingLogoutHandlerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Logout;
+namespace Symfony\Component\Security\Http\Tests\Logout;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
diff --git a/Tests/Http/Logout/DefaultLogoutSuccessHandlerTest.php b/Http/Tests/Logout/DefaultLogoutSuccessHandlerTest.php
index f18604d..381a48e 100644
--- a/Tests/Http/Logout/DefaultLogoutSuccessHandlerTest.php
+++ b/Http/Tests/Logout/DefaultLogoutSuccessHandlerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Logout;
+namespace Symfony\Component\Security\Http\Tests\Logout;
use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
diff --git a/Tests/Http/Logout/SessionLogoutHandlerTest.php b/Http/Tests/Logout/SessionLogoutHandlerTest.php
index f89a423..c342995 100644
--- a/Tests/Http/Logout/SessionLogoutHandlerTest.php
+++ b/Http/Tests/Logout/SessionLogoutHandlerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Logout;
+namespace Symfony\Component\Security\Http\Tests\Logout;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Logout\SessionLogoutHandler;
diff --git a/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
index c98b6b4..ddfaaeb 100644
--- a/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\RememberMe;
+namespace Symfony\Component\Security\Http\Tests\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -266,7 +266,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException InvalidArgumentException
+ * @expectedException \InvalidArgumentException
* @expectedExceptionMessage cookie delimiter
*/
public function testThereShouldBeNoCookieDelimiterInCookieParts()
diff --git a/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
index 3ba8f99..f43963e 100644
--- a/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\RememberMe;
+namespace Symfony\Component\Security\Http\Tests\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
diff --git a/Tests/Http/RememberMe/ResponseListenerTest.php b/Http/Tests/RememberMe/ResponseListenerTest.php
index bca2c43..78de8e4 100644
--- a/Tests/Http/RememberMe/ResponseListenerTest.php
+++ b/Http/Tests/RememberMe/ResponseListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\RememberMe;
+namespace Symfony\Component\Security\Http\Tests\RememberMe;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\RememberMe\ResponseListener;
@@ -94,7 +94,7 @@ class ResponseListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
- $event->expects($this->any())->method('getRequestType')->will($this->returnValue($type));
+ $event->expects($this->any())->method('isMasterRequest')->will($this->returnValue($type === HttpKernelInterface::MASTER_REQUEST));
$event->expects($this->any())->method('getResponse')->will($this->returnValue($response));
return $event;
diff --git a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
index d1ec9b2..e3b58e9 100644
--- a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\RememberMe;
+namespace Symfony\Component\Security\Http\Tests\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
diff --git a/Tests/Http/Session/SessionAuthenticationStrategyTest.php b/Http/Tests/Session/SessionAuthenticationStrategyTest.php
index 7296afd..4aef4b2 100644
--- a/Tests/Http/Session/SessionAuthenticationStrategyTest.php
+++ b/Http/Tests/Session/SessionAuthenticationStrategyTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Tests\Http\Session;
+namespace Symfony\Component\Security\Http\Tests\Session;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
diff --git a/Http/composer.json b/Http/composer.json
new file mode 100644
index 0000000..1b36428
--- /dev/null
+++ b/Http/composer.json
@@ -0,0 +1,46 @@
+{
+ "name": "symfony/security-http",
+ "type": "library",
+ "description": "Symfony Security Component - HTTP Integration",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/security-core": "~2.6",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/http-foundation": "~2.4",
+ "symfony/http-kernel": "~2.4"
+ },
+ "require-dev": {
+ "symfony/routing": "~2.2",
+ "symfony/security-csrf": "~2.4",
+ "psr/log": "~1.0"
+ },
+ "suggest": {
+ "symfony/security-csrf": "For using tokens to protect authentication/logout attempts",
+ "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Security\\Http\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ }
+}
diff --git a/Http/phpunit.xml.dist b/Http/phpunit.xml.dist
new file mode 100644
index 0000000..8d636e9
--- /dev/null
+++ b/Http/phpunit.xml.dist
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Security Component HTTP Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/Tests/Core/SecurityContextTest.php b/Tests/Core/SecurityContextTest.php
deleted file mode 100644
index 3fba8d9..0000000
--- a/Tests/Core/SecurityContextTest.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Security\Tests\Core;
-
-use Symfony\Component\Security\Core\SecurityContext;
-
-class SecurityContextTest extends \PHPUnit_Framework_TestCase
-{
- public function testVoteAuthenticatesTokenIfNecessary()
- {
- $authManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $decisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
-
- $context = new SecurityContext($authManager, $decisionManager);
- $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
-
- $authManager
- ->expects($this->once())
- ->method('authenticate')
- ->with($this->equalTo($token))
- ->will($this->returnValue($newToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
- ;
-
- $decisionManager
- ->expects($this->once())
- ->method('decide')
- ->will($this->returnValue(true))
- ;
-
- $this->assertTrue($context->isGranted('foo'));
- $this->assertSame($newToken, $context->getToken());
- }
-
- /**
- * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
- */
- public function testVoteWithoutAuthenticationToken()
- {
- $context = new SecurityContext(
- $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'),
- $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')
- );
-
- $context->isGranted('ROLE_FOO');
- }
-
- public function testIsGranted()
- {
- $manager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
- $manager->expects($this->once())->method('decide')->will($this->returnValue(false));
- $context = new SecurityContext($this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), $manager);
- $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
- $token
- ->expects($this->once())
- ->method('isAuthenticated')
- ->will($this->returnValue(true))
- ;
- $this->assertFalse($context->isGranted('ROLE_FOO'));
-
- $manager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface');
- $manager->expects($this->once())->method('decide')->will($this->returnValue(true));
- $context = new SecurityContext($this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), $manager);
- $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
- $token
- ->expects($this->once())
- ->method('isAuthenticated')
- ->will($this->returnValue(true))
- ;
- $this->assertTrue($context->isGranted('ROLE_FOO'));
- }
-
- public function testGetSetToken()
- {
- $context = new SecurityContext(
- $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'),
- $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')
- );
- $this->assertNull($context->getToken());
-
- $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
- $this->assertSame($token, $context->getToken());
- }
-
- public function testTranslationsAreNotInCore()
- {
- $this->assertFileNotExists(__DIR__.'/../../Core/Resources/translations/');
- }
-}
diff --git a/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php b/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php
deleted file mode 100644
index 4c420c7..0000000
--- a/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Security\Tests\Core\Validator\Constraints;
-
-use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
-use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator;
-
-class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase
-{
- const PASSWORD_VALID = true;
- const PASSWORD_INVALID = false;
-
- protected $context;
-
- protected function setUp()
- {
- $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
- }
-
- protected function tearDown()
- {
- $this->context = null;
- }
-
- public function testPasswordIsValid()
- {
- $user = $this->createUser();
- $securityContext = $this->createSecurityContext($user);
-
- $encoder = $this->createPasswordEncoder(static::PASSWORD_VALID);
- $encoderFactory = $this->createEncoderFactory($encoder);
-
- $validator = new UserPasswordValidator($securityContext, $encoderFactory);
- $validator->initialize($this->context);
-
- $this
- ->context
- ->expects($this->never())
- ->method('addViolation')
- ;
-
- $validator->validate('secret', new UserPassword());
- }
-
- public function testPasswordIsNotValid()
- {
- $user = $this->createUser();
- $securityContext = $this->createSecurityContext($user);
-
- $encoder = $this->createPasswordEncoder(static::PASSWORD_INVALID);
- $encoderFactory = $this->createEncoderFactory($encoder);
-
- $validator = new UserPasswordValidator($securityContext, $encoderFactory);
- $validator->initialize($this->context);
-
- $this
- ->context
- ->expects($this->once())
- ->method('addViolation')
- ;
-
- $validator->validate('secret', new UserPassword());
- }
-
- public function testUserIsNotValid()
- {
- $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
-
- $user = $this->getMock('Foo\Bar\User');
- $encoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
- $securityContext = $this->createSecurityContext($user);
-
- $validator = new UserPasswordValidator($securityContext, $encoderFactory);
- $validator->initialize($this->context);
- $validator->validate('secret', new UserPassword());
- }
-
- protected function createUser()
- {
- $mock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
-
- $mock
- ->expects($this->once())
- ->method('getPassword')
- ->will($this->returnValue('s3Cr3t'))
- ;
-
- $mock
- ->expects($this->once())
- ->method('getSalt')
- ->will($this->returnValue('^S4lt$'))
- ;
-
- return $mock;
- }
-
- protected function createPasswordEncoder($isPasswordValid = true)
- {
- $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
-
- $mock
- ->expects($this->once())
- ->method('isPasswordValid')
- ->will($this->returnValue($isPasswordValid))
- ;
-
- return $mock;
- }
-
- protected function createEncoderFactory($encoder = null)
- {
- $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
-
- $mock
- ->expects($this->once())
- ->method('getEncoder')
- ->will($this->returnValue($encoder))
- ;
-
- return $mock;
- }
-
- protected function createSecurityContext($user = null)
- {
- $token = $this->createAuthenticationToken($user);
-
- $mock = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $mock
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue($token))
- ;
-
- return $mock;
- }
-
- protected function createAuthenticationToken($user = null)
- {
- $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $mock
- ->expects($this->once())
- ->method('getUser')
- ->will($this->returnValue($user))
- ;
-
- return $mock;
- }
-}
diff --git a/Tests/Http/Firewall/AnonymousAuthenticationListenerTest.php b/Tests/Http/Firewall/AnonymousAuthenticationListenerTest.php
deleted file mode 100644
index 0666ef3..0000000
--- a/Tests/Http/Firewall/AnonymousAuthenticationListenerTest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Security\Tests\Http\Firewall;
-
-use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener;
-
-class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
-{
- public function testHandleWithContextHavingAToken()
- {
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
- ->expects($this->any())
- ->method('getToken')
- ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
- ;
- $context
- ->expects($this->never())
- ->method('setToken')
- ;
-
- $listener = new AnonymousAuthenticationListener($context, 'TheKey');
- $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
- }
-
- public function testHandleWithContextHavingNoToken()
- {
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $context
- ->expects($this->any())
- ->method('getToken')
- ->will($this->returnValue(null))
- ;
- $context
- ->expects($this->once())
- ->method('setToken')
- ->with(self::logicalAnd(
- $this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken'),
- $this->attributeEqualTo('key', 'TheKey')
- ))
- ;
-
- $listener = new AnonymousAuthenticationListener($context, 'TheKey');
- $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
- }
-
- public function testHandledEventIsLogged()
- {
- $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
- $logger = $this->getMock('Psr\Log\LoggerInterface');
- $logger->expects($this->once())
- ->method('info')
- ->with('Populated SecurityContext with an anonymous Token')
- ;
-
- $listener = new AnonymousAuthenticationListener($context, 'TheKey', $logger);
- $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
- }
-}
diff --git a/Tests/Http/Firewall/RememberMeListenerTest.php b/Tests/Http/Firewall/RememberMeListenerTest.php
deleted file mode 100644
index 8316a8c..0000000
--- a/Tests/Http/Firewall/RememberMeListenerTest.php
+++ /dev/null
@@ -1,247 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Security\Tests\Http\Firewall;
-
-use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Http\Firewall\RememberMeListener;
-use Symfony\Component\HttpFoundation\Request;
-
-class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
-{
- public function testOnCoreSecurityDoesNotTryToPopulateNonEmptySecurityContext()
- {
- list($listener, $context, $service) = $this->getListener();
-
- $context
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
- ;
-
- $context
- ->expects($this->never())
- ->method('setToken')
- ;
-
- $this->assertNull($listener->handle($this->getGetResponseEvent()));
- }
-
- public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet()
- {
- list($listener, $context, $service) = $this->getListener();
-
- $context
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue(null))
- ;
-
- $service
- ->expects($this->once())
- ->method('autoLogin')
- ->will($this->returnValue(null))
- ;
-
- $event = $this->getGetResponseEvent();
- $event
- ->expects($this->once())
- ->method('getRequest')
- ->will($this->returnValue(new Request()))
- ;
-
- $this->assertNull($listener->handle($event));
- }
-
- public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
- {
- list($listener, $context, $service, $manager) = $this->getListener();
-
- $context
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue(null))
- ;
-
- $service
- ->expects($this->once())
- ->method('autoLogin')
- ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
- ;
-
- $service
- ->expects($this->once())
- ->method('loginFail')
- ;
-
- $exception = new AuthenticationException('Authentication failed.');
- $manager
- ->expects($this->once())
- ->method('authenticate')
- ->will($this->throwException($exception))
- ;
-
- $event = $this->getGetResponseEvent();
- $event
- ->expects($this->once())
- ->method('getRequest')
- ->will($this->returnValue(new Request()))
- ;
-
- $listener->handle($event);
- }
-
- public function testOnCoreSecurity()
- {
- list($listener, $context, $service, $manager) = $this->getListener();
-
- $context
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue(null))
- ;
-
- $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $service
- ->expects($this->once())
- ->method('autoLogin')
- ->will($this->returnValue($token))
- ;
-
- $context
- ->expects($this->once())
- ->method('setToken')
- ->with($this->equalTo($token))
- ;
-
- $manager
- ->expects($this->once())
- ->method('authenticate')
- ->will($this->returnValue($token))
- ;
-
- $event = $this->getGetResponseEvent();
- $event
- ->expects($this->once())
- ->method('getRequest')
- ->will($this->returnValue(new Request()))
- ;
-
- $listener->handle($event);
- }
-
- public function testSessionStrategy()
- {
- list($listener, $tokenStorage, $service, $manager) = $this->getListener();
-
- $tokenStorage
- ->expects($this->once())
- ->method('getToken')
- ->will($this->returnValue(null))
- ;
-
- $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $service
- ->expects($this->once())
- ->method('autoLogin')
- ->will($this->returnValue($token))
- ;
-
- $tokenStorage
- ->expects($this->once())
- ->method('setToken')
- ->with($this->equalTo($token))
- ;
-
- $manager
- ->expects($this->once())
- ->method('authenticate')
- ->will($this->returnValue($token))
- ;
-
- $session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface');
- $session
- ->expects($this->once())
- ->method('isStarted')
- ->will($this->returnValue(true))
- ;
- $session
- ->expects($this->once())
- ->method('migrate')
- ;
-
- $request = $this->getMock('\Symfony\Component\HttpFoundation\Request');
- $request
- ->expects($this->any())
- ->method('hasSession')
- ->will($this->returnValue(true))
- ;
-
- $request
- ->expects($this->any())
- ->method('getSession')
- ->will($this->returnValue($session))
- ;
-
- $event = $this->getGetResponseEvent();
- $event
- ->expects($this->once())
- ->method('getRequest')
- ->will($this->returnValue($request))
- ;
-
- $listener->handle($event);
- }
-
- protected function getGetResponseEvent()
- {
- return $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
- }
-
- protected function getFilterResponseEvent()
- {
- return $this->getMock('Symfony\Component\HttpKernel\Event\FilterResponseEvent', array(), array(), '', false);
- }
-
- protected function getListener()
- {
- $listener = new RememberMeListener(
- $context = $this->getContext(),
- $service = $this->getService(),
- $manager = $this->getManager(),
- $logger = $this->getLogger()
- );
-
- return array($listener, $context, $service, $manager, $logger);
- }
-
- protected function getLogger()
- {
- return $this->getMock('Psr\Log\LoggerInterface');
- }
-
- protected function getManager()
- {
- return $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- }
-
- protected function getService()
- {
- return $this->getMock('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface');
- }
-
- protected function getContext()
- {
- return $this->getMockBuilder('Symfony\Component\Security\Core\SecurityContext')
- ->disableOriginalConstructor()
- ->getMock();
- }
-}
diff --git a/Tests/TranslationSyncStatusTest.php b/Tests/TranslationSyncStatusTest.php
new file mode 100644
index 0000000..4b72d41
--- /dev/null
+++ b/Tests/TranslationSyncStatusTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Tests;
+
+use Symfony\Component\Finder\Finder;
+
+class TranslationSyncStatusTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTranslationDirectoriesData
+ */
+ public function testTranslationFileIsNotMissingInCore($dir1, $dir2)
+ {
+ $finder = new Finder();
+ $files = $finder->in($dir1)->files();
+
+ foreach ($files as $file) {
+ $this->assertFileExists($dir2.'/'.$file->getFilename(), 'Missing file '.$file->getFilename().' in directory '.$dir2);
+ }
+ }
+
+ public function getTranslationDirectoriesData()
+ {
+ $legacyTranslationsDir = $this->getLegacyTranslationsDirectory();
+ $coreTranslationsDir = $this->getCoreTranslationsDirectory();
+
+ return array(
+ 'file-not-missing-in-core' => array($legacyTranslationsDir, $coreTranslationsDir),
+ 'file-not-added-in-core' => array($coreTranslationsDir, $legacyTranslationsDir),
+ );
+ }
+
+ public function testFileContentsAreEqual()
+ {
+ $finder = new Finder();
+ $files = $finder->in($this->getLegacyTranslationsDirectory())->files();
+
+ foreach ($files as $file) {
+ $coreFile = $this->getCoreTranslationsDirectory().'/'.$file->getFilename();
+
+ $this->assertFileEquals($file->getRealPath(), $coreFile, $file.' and '.$coreFile.' have equal content.');
+ }
+ }
+
+ private function getLegacyTranslationsDirectory()
+ {
+ return __DIR__.'/../Resources/translations';
+ }
+
+ private function getCoreTranslationsDirectory()
+ {
+ return __DIR__.'/../Core/Resources/translations';
+ }
+}
diff --git a/composer.json b/composer.json
index 4f265fe..b64e1b8 100644
--- a/composer.json
+++ b/composer.json
@@ -16,47 +16,49 @@
}
],
"require": {
- "php": ">=5.3.3",
+ "php": ">=5.3.9",
"paragonie/random_compat": "~1.0",
"symfony/event-dispatcher": "~2.2",
"symfony/http-foundation": "~2.1",
- "symfony/http-kernel": "~2.1"
+ "symfony/http-kernel": "~2.4"
+ },
+ "replace": {
+ "symfony/security-acl": "self.version",
+ "symfony/security-core": "self.version",
+ "symfony/security-csrf": "self.version",
+ "symfony/security-http": "self.version"
},
"require-dev": {
- "symfony/form": "~2.0,>=2.0.5",
+ "symfony/finder": "~2.3",
"symfony/intl": "~2.3",
"symfony/routing": "~2.2",
- "symfony/validator": "~2.2",
+ "symfony/validator": "~2.5,>=2.5.9",
"doctrine/common": "~2.2",
"doctrine/dbal": "~2.2",
"psr/log": "~1.0",
- "ircmaxell/password-compat": "~1.0"
- },
- "replace": {
- "symfony/security-acl": "self.version",
- "symfony/security-core": "self.version",
- "symfony/security-http": "self.version"
+ "ircmaxell/password-compat": "~1.0",
+ "symfony/expression-language": "~2.6"
},
"suggest": {
- "symfony/class-loader": "",
- "symfony/finder": "",
+ "symfony/class-loader": "For using the ACL generateSql script",
+ "symfony/finder": "For using the ACL generateSql script",
"symfony/form": "",
- "symfony/validator": "",
- "symfony/routing": "",
- "doctrine/dbal": "to use the built-in ACL implementation",
- "ircmaxell/password-compat": ""
+ "symfony/validator": "For using the user password constraint",
+ "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs",
+ "doctrine/dbal": "For using the built-in ACL implementation",
+ "symfony/expression-language": "For using the expression voter",
+ "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5"
},
"autoload": {
- "psr-0": { "Symfony\\Component\\Security\\": "" },
+ "psr-4": { "Symfony\\Component\\Security\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
},
- "target-dir": "Symfony/Component/Security",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.7-dev"
}
}
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 9d3cf4a..6b56bf2 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -13,6 +13,7 @@
<testsuites>
<testsuite name="Symfony Security Component Test Suite">
<directory>./Tests/</directory>
+ <directory>./*/Tests/</directory>
</testsuite>
</testsuites>
@@ -20,10 +21,12 @@
<whitelist>
<directory>./</directory>
<exclude>
- <directory>./Acl/Resources</directory>
<directory>./Resources</directory>
<directory>./Tests</directory>
<directory>./vendor</directory>
+ <directory>./*/Resources</directory>
+ <directory>./*/Tests</directory>
+ <directory>./*/vendor</directory>
</exclude>
</whitelist>
</filter>