From ab12817b7a7104dd204aab36f92918bbddac20be Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Tue, 23 May 2006 13:38:33 +0000 Subject: [PATCH] SEC-97: Format Acegi Security source code in accordance with latest Jalopy configuration. --- .../adapters/cas/CasPasswordHandler.java | 58 +- .../adapters/cas/CasPasswordHandlerProxy.java | 81 +- .../cas3/CasAuthenticationHandler.java | 106 ++- .../cas/CasPasswordHandlerProxyTests.java | 31 +- .../adapters/cas/CasPasswordHandlerTests.java | 32 +- .../cas3/CasAuthenticationHandlerTests.java | 138 ++-- .../catalina/CatalinaAcegiUserRealm.java | 135 ++-- .../catalina/CatalinaAcegiUserRealmTests.java | 114 ++- .../adapters/jboss/JbossAcegiLoginModule.java | 77 +- .../jboss/JbossIntegrationFilter.java | 77 +- .../jboss/JbossAcegiLoginModuleTests.java | 75 +- .../jboss/JbossIntegrationFilterTests.java | 85 +- .../adapters/jboss/MockInitialContext.java | 44 +- .../jboss/MockJbossIntegrationFilter.java | 12 +- .../adapters/jetty/JettyAcegiUserRealm.java | 72 +- .../adapters/jetty/JettyAcegiUserToken.java | 15 +- .../jetty/JettyAcegiUserRealmTests.java | 60 +- .../jetty/JettyAcegiUserTokenTests.java | 20 +- .../resin/ResinAcegiAuthenticator.java | 85 +- .../resin/ResinAcegiAuthenticatorTests.java | 89 +-- .../org/acegisecurity/annotation/Secured.java | 6 +- .../SecurityAnnotationAttributes.java | 182 +++-- .../test/java/org/acegisecurity/Entity.java | 8 +- .../java/org/acegisecurity/Organisation.java | 16 +- .../acegisecurity/OrganisationService.java | 25 +- .../OrganisationServiceImpl.java | 29 +- .../test/java/org/acegisecurity/Person.java | 16 +- .../java/org/acegisecurity/PersonService.java | 25 +- .../org/acegisecurity/PersonServiceImpl.java | 29 +- .../test/java/org/acegisecurity/Service.java | 4 +- .../java/org/acegisecurity/ServiceImpl.java | 50 +- .../annotation/BusinessService.java | 47 +- .../SecurityAnnotationAttributesTests.java | 129 ++- ...ethodDefinitionSourceEditorTigerTests.java | 80 +- .../AbstractAuthenticationManager.java | 50 +- .../acegisecurity/AccessDecisionManager.java | 48 +- .../acegisecurity/AccessDeniedException.java | 11 +- .../AccountExpiredException.java | 13 +- .../org/acegisecurity/AcegiMessageSource.java | 17 +- .../acegisecurity/AcegiSecurityException.java | 17 +- .../acegisecurity/AfterInvocationManager.java | 58 +- .../org/acegisecurity/Authentication.java | 124 ++- ...nticationCredentialsNotFoundException.java | 15 +- .../AuthenticationException.java | 21 +- .../acegisecurity/AuthenticationManager.java | 48 +- .../AuthenticationServiceException.java | 16 +- .../AuthenticationTrustResolver.java | 50 +- .../AuthenticationTrustResolverImpl.java | 48 +- .../AuthorizationServiceException.java | 17 +- .../BadCredentialsException.java | 20 +- .../org/acegisecurity/ConfigAttribute.java | 31 +- .../ConfigAttributeDefinition.java | 61 +- .../acegisecurity/ConfigAttributeEditor.java | 17 +- .../CredentialsExpiredException.java | 13 +- .../org/acegisecurity/DisabledException.java | 13 +- .../org/acegisecurity/GrantedAuthority.java | 30 +- .../acegisecurity/GrantedAuthorityImpl.java | 14 +- .../InsufficientAuthenticationException.java | 25 +- .../org/acegisecurity/LockedException.java | 12 +- .../MockAuthenticationManager.java | 14 +- .../java/org/acegisecurity/RunAsManager.java | 44 +- .../org/acegisecurity/SecurityConfig.java | 16 +- .../java/org/acegisecurity/acl/AclEntry.java | 3 +- .../org/acegisecurity/acl/AclManager.java | 29 +- .../org/acegisecurity/acl/AclProvider.java | 53 +- .../acegisecurity/acl/AclProviderManager.java | 67 +- .../acl/basic/AbstractBasicAclEntry.java | 258 +++--- .../acl/basic/AclObjectIdentity.java | 13 +- .../acl/basic/AclObjectIdentityAware.java | 7 +- .../acegisecurity/acl/basic/BasicAclDao.java | 24 +- .../acl/basic/BasicAclEntry.java | 149 ++-- .../acl/basic/BasicAclEntryCache.java | 26 +- .../acl/basic/BasicAclExtendedDao.java | 70 +- .../acl/basic/BasicAclProvider.java | 412 ++++------ .../acl/basic/EffectiveAclsResolver.java | 20 +- ...GrantedAuthorityEffectiveAclsResolver.java | 75 +- .../acl/basic/NamedEntityObjectIdentity.java | 38 +- .../acl/basic/SimpleAclEntry.java | 21 +- .../acl/basic/cache/BasicAclEntryHolder.java | 30 +- .../cache/EhCacheBasedAclEntryCache.java | 21 +- .../acl/basic/cache/NullAclEntryCache.java | 16 +- .../acl/basic/jdbc/JdbcDaoImpl.java | 202 ++--- .../acl/basic/jdbc/JdbcExtendedDaoImpl.java | 147 ++-- .../AbstractAdapterAuthenticationToken.java | 108 ++- .../acegisecurity/adapters/AuthByAdapter.java | 11 +- .../adapters/AuthByAdapterProvider.java | 33 +- .../HttpRequestIntegrationFilter.java | 47 +- .../adapters/PrincipalAcegiUserToken.java | 18 +- .../AfterInvocationProvider.java | 36 +- .../AfterInvocationProviderManager.java | 118 ++- ...InvocationCollectionFilteringProvider.java | 226 +++--- .../BasicAclEntryAfterInvocationProvider.java | 135 ++-- ...terMaxRequestsCaptchaChannelProcessor.java | 20 +- ...erTimeInMillisCaptchaChannelProcessor.java | 29 +- ...MillisBetweenRequestsChannelProcessor.java | 30 +- .../CaptchaChannelProcessorTemplate.java | 123 ++- .../captcha/CaptchaEntryPoint.java | 420 +++++----- .../captcha/CaptchaSecurityContext.java | 42 +- .../captcha/CaptchaSecurityContextImpl.java | 88 ++- .../captcha/CaptchaServiceProxy.java | 9 +- .../CaptchaValidationProcessingFilter.java | 90 +-- ...terMaxRequestsCaptchaChannelProcessor.java | 29 +- .../concurrent/ConcurrentLoginException.java | 10 +- .../ConcurrentSessionController.java | 34 +- .../ConcurrentSessionControllerImpl.java | 86 +- .../concurrent/ConcurrentSessionFilter.java | 68 +- .../NullConcurrentSessionController.java | 10 +- .../SessionAlreadyUsedException.java | 10 +- .../concurrent/SessionIdentifierAware.java | 2 +- .../concurrent/SessionInformation.java | 42 +- .../concurrent/SessionRegistry.java | 56 +- .../concurrent/SessionRegistryUtils.java | 12 +- .../GlobalSecurityContextHolderStrategy.java | 19 +- .../HttpSessionContextIntegrationFilter.java | 171 ++-- ...eadLocalSecurityContextHolderStrategy.java | 7 +- .../context/SecurityContext.java | 28 +- .../context/SecurityContextHolder.java | 65 +- .../SecurityContextHolderStrategy.java | 11 +- .../context/SecurityContextImpl.java | 62 +- ...eadLocalSecurityContextHolderStrategy.java | 7 +- ...ationSimpleHttpInvokerRequestExecutor.java | 51 +- .../ContextPropagatingRemoteInvocation.java | 68 +- ...extPropagatingRemoteInvocationFactory.java | 21 +- .../AbstractAuthenticationEvent.java | 18 +- .../AbstractAuthenticationFailureEvent.java | 17 +- ...henticationFailureBadCredentialsEvent.java | 13 +- ...enticationFailureConcurrentLoginEvent.java | 14 +- ...icationFailureCredentialsExpiredEvent.java | 13 +- .../AuthenticationFailureDisabledEvent.java | 13 +- .../AuthenticationFailureExpiredEvent.java | 13 +- .../AuthenticationFailureLockedEvent.java | 13 +- ...nticationFailureProviderNotFoundEvent.java | 15 +- ...henticationFailureProxyUntrustedEvent.java | 14 +- ...nticationFailureServiceExceptionEvent.java | 14 +- .../AuthenticationSuccessEvent.java | 4 +- .../AuthenticationSwitchUserEvent.java | 14 +- ...InteractiveAuthenticationSuccessEvent.java | 26 +- .../event/authentication/LoggerListener.java | 19 +- .../AbstractAuthorizationEvent.java | 6 +- ...uthenticationCredentialsNotFoundEvent.java | 24 +- .../AuthorizationFailureEvent.java | 24 +- .../event/authorization/AuthorizedEvent.java | 23 +- .../event/authorization/LoggerListener.java | 39 +- .../authorization/PublicInvocationEvent.java | 22 +- .../AbstractSecurityInterceptor.java | 370 ++++----- .../intercept/InterceptorStatusToken.java | 33 +- .../intercept/ObjectDefinitionSource.java | 40 +- .../AbstractMethodDefinitionSource.java | 48 +- .../method/MethodDefinitionAttributes.java | 158 ++-- .../intercept/method/MethodDefinitionMap.java | 185 ++--- .../method/MethodDefinitionSource.java | 2 +- .../method/MethodDefinitionSourceEditor.java | 17 +- .../MethodInvocationPrivilegeEvaluator.java | 47 +- .../MethodDefinitionSourceAdvisor.java | 53 +- .../MethodSecurityInterceptor.java | 38 +- .../method/aspectj/AspectJCallback.java | 4 +- .../aspectj/AspectJSecurityInterceptor.java | 53 +- ...tractFilterInvocationDefinitionSource.java | 37 +- .../intercept/web/FilterInvocation.java | 43 +- .../web/FilterInvocationDefinitionMap.java | 5 +- .../web/FilterInvocationDefinitionSource.java | 2 +- ...ilterInvocationDefinitionSourceEditor.java | 72 +- .../web/FilterSecurityInterceptor.java | 57 +- ...athBasedFilterInvocationDefinitionMap.java | 49 +- ...ExpBasedFilterInvocationDefinitionMap.java | 108 +-- .../web/WebInvocationPrivilegeEvaluator.java | 27 +- .../ldap/DefaultInitialDirContextFactory.java | 294 ++++--- .../ldap/InitialDirContextFactory.java | 24 +- .../org/acegisecurity/ldap/LdapCallback.java | 9 +- .../ldap/LdapDataAccessException.java | 8 +- .../acegisecurity/ldap/LdapEntryMapper.java | 53 +- .../org/acegisecurity/ldap/LdapTemplate.java | 296 ++++--- .../acegisecurity/ldap/LdapUserSearch.java | 9 +- .../org/acegisecurity/ldap/LdapUtils.java | 58 +- .../ldap/NamingExceptionTranslator.java | 55 +- .../search/FilterBasedLdapUserSearch.java | 146 ++-- .../AbstractAuthenticationToken.java | 34 +- .../providers/AuthenticationProvider.java | 46 +- .../providers/ProviderManager.java | 179 ++--- .../providers/ProviderNotFoundException.java | 13 +- .../TestingAuthenticationProvider.java | 20 +- .../providers/TestingAuthenticationToken.java | 18 +- .../UsernamePasswordAuthenticationToken.java | 32 +- .../AnonymousAuthenticationProvider.java | 32 +- .../AnonymousAuthenticationToken.java | 22 +- .../anonymous/AnonymousProcessingFilter.java | 88 +-- .../cas/CasAuthenticationProvider.java | 89 +-- .../providers/cas/CasAuthenticationToken.java | 39 +- .../cas/CasAuthoritiesPopulator.java | 16 +- .../providers/cas/CasProxyDecider.java | 16 +- .../cas/ProxyUntrustedException.java | 8 +- .../providers/cas/TicketResponse.java | 16 +- .../providers/cas/TicketValidator.java | 16 +- .../cas/cache/EhCacheBasedTicketCache.java | 43 +- .../populator/DaoCasAuthoritiesPopulator.java | 41 +- .../cas/proxy/AcceptAnyCasProxy.java | 15 +- .../cas/proxy/NamedCasProxyDecider.java | 35 +- .../cas/proxy/RejectProxyTickets.java | 34 +- .../AbstractTicketValidator.java | 98 ++- .../CasProxyTicketValidator.java | 78 +- ...ractUserDetailsAuthenticationProvider.java | 263 +++---- .../dao/DaoAuthenticationProvider.java | 42 +- .../providers/dao/SaltSource.java | 4 +- .../providers/dao/UserCache.java | 32 +- .../dao/cache/EhCacheBasedUserCache.java | 34 +- .../providers/dao/cache/NullUserCache.java | 5 +- .../dao/salt/ReflectionSaltSource.java | 50 +- .../dao/salt/SystemWideSaltSource.java | 42 +- .../encoding/BaseDigestPasswordEncoder.java | 23 +- .../encoding/BasePasswordEncoder.java | 67 +- .../encoding/Md5PasswordEncoder.java | 37 +- .../providers/encoding/PasswordEncoder.java | 100 +-- .../encoding/PlaintextPasswordEncoder.java | 61 +- .../encoding/ShaPasswordEncoder.java | 37 +- .../providers/jaas/AuthorityGranter.java | 23 +- .../jaas/DefaultLoginExceptionResolver.java | 7 +- .../JaasAuthenticationCallbackHandler.java | 11 +- .../jaas/JaasAuthenticationProvider.java | 632 +++++++-------- .../jaas/JaasAuthenticationToken.java | 30 +- .../providers/jaas/JaasGrantedAuthority.java | 12 +- .../jaas/JaasNameCallbackHandler.java | 28 +- .../jaas/JaasPasswordCallbackHandler.java | 22 +- .../jaas/LoginExceptionResolver.java | 7 +- .../jaas/SecurityContextLoginModule.java | 90 +-- .../jaas/event/JaasAuthenticationEvent.java | 11 +- .../event/JaasAuthenticationFailedEvent.java | 14 +- .../event/JaasAuthenticationSuccessEvent.java | 11 +- .../ldap/LdapAuthenticationProvider.java | 193 ++--- .../providers/ldap/LdapAuthenticator.java | 9 +- .../ldap/LdapAuthoritiesPopulator.java | 15 +- .../AbstractLdapAuthenticator.java | 159 ++-- .../ldap/authenticator/BindAuthenticator.java | 41 +- .../authenticator/LdapShaPasswordEncoder.java | 122 +-- .../PasswordComparisonAuthenticator.java | 118 ++- .../DefaultLdapAuthoritiesPopulator.java | 250 +++--- .../rcp/RemoteAuthenticationException.java | 17 +- .../rcp/RemoteAuthenticationManager.java | 35 +- .../rcp/RemoteAuthenticationManagerImpl.java | 45 +- .../rcp/RemoteAuthenticationProvider.java | 55 +- .../RememberMeAuthenticationProvider.java | 32 +- .../RememberMeAuthenticationToken.java | 32 +- .../x509/X509AuthenticationProvider.java | 56 +- .../x509/X509AuthenticationToken.java | 16 +- .../x509/X509AuthoritiesPopulator.java | 22 +- .../providers/x509/X509UserCache.java | 4 +- .../x509/cache/EhCacheBasedX509UserCache.java | 33 +- .../x509/cache/NullX509UserCache.java | 19 +- .../DaoX509AuthoritiesPopulator.java | 67 +- .../acegisecurity/runas/NullRunAsManager.java | 15 +- .../RunAsImplAuthenticationProvider.java | 37 +- .../acegisecurity/runas/RunAsManagerImpl.java | 111 ++- .../acegisecurity/runas/RunAsUserToken.java | 16 +- .../securechannel/ChannelDecisionManager.java | 38 +- .../ChannelDecisionManagerImpl.java | 91 +-- .../securechannel/ChannelEntryPoint.java | 17 +- .../ChannelProcessingFilter.java | 64 +- .../securechannel/ChannelProcessor.java | 38 +- .../InsecureChannelProcessor.java | 74 +- .../RetryWithHttpEntryPoint.java | 63 +- .../RetryWithHttpsEntryPoint.java | 63 +- .../securechannel/SecureChannelProcessor.java | 73 +- .../acegisecurity/taglibs/authz/AclTag.java | 83 +- .../taglibs/authz/AuthenticationTag.java | 67 +- .../taglibs/authz/AuthorizeTag.java | 254 +++--- .../acegisecurity/taglibs/velocity/Authz.java | 26 +- .../taglibs/velocity/AuthzImpl.java | 35 +- .../ui/AbstractProcessingFilter.java | 251 ++---- .../acegisecurity/ui/AccessDeniedHandler.java | 5 +- .../ui/AccessDeniedHandlerImpl.java | 42 +- .../ui/AuthenticationDetailsSource.java | 8 +- .../ui/AuthenticationDetailsSourceImpl.java | 17 +- .../ui/AuthenticationEntryPoint.java | 28 +- .../ui/ExceptionTranslationFilter.java | 144 ++-- .../ui/WebAuthenticationDetails.java | 17 +- .../ui/basicauth/BasicProcessingFilter.java | 139 ++-- .../BasicProcessingFilterEntryPoint.java | 51 +- .../ui/cas/CasProcessingFilter.java | 88 +-- .../ui/cas/CasProcessingFilterEntryPoint.java | 82 +- .../ui/cas/ServiceProperties.java | 79 +- .../ui/digestauth/DigestProcessingFilter.java | 233 ++---- .../DigestProcessingFilterEntryPoint.java | 101 ++- .../ui/digestauth/NonceExpiredException.java | 11 +- .../acegisecurity/ui/logout/LogoutFilter.java | 52 +- .../ui/logout/LogoutHandler.java | 37 +- .../logout/SecurityContextLogoutHandler.java | 8 +- .../ui/rememberme/NullRememberMeServices.java | 21 +- .../RememberMeProcessingFilter.java | 96 +-- .../ui/rememberme/RememberMeServices.java | 69 +- .../TokenBasedRememberMeServices.java | 202 ++--- .../ui/savedrequest/Enumerator.java | 45 +- .../ui/savedrequest/FastHttpDateFormat.java | 55 +- .../ui/savedrequest/SavedRequest.java | 75 +- .../session/HttpSessionApplicationEvent.java | 8 +- .../ui/session/HttpSessionCreatedEvent.java | 7 +- .../ui/session/HttpSessionDestroyedEvent.java | 7 +- .../ui/session/HttpSessionEventPublisher.java | 109 ++- .../SwitchUserGrantedAuthority.java | 20 +- .../SwitchUserProcessingFilter.java | 181 ++--- .../AuthenticationProcessingFilter.java | 63 +- ...henticationProcessingFilterEntryPoint.java | 58 +- ...eminderAuthenticationProcessingFilter.java | 196 ++--- .../ui/x509/X509ProcessingFilter.java | 121 +-- .../x509/X509ProcessingFilterEntryPoint.java | 59 +- .../org/acegisecurity/userdetails/User.java | 52 +- .../userdetails/UserDetails.java | 86 +- .../userdetails/UserDetailsService.java | 23 +- .../UsernameNotFoundException.java | 11 +- .../userdetails/jdbc/JdbcDaoImpl.java | 195 ++--- .../userdetails/ldap/LdapUserDetails.java | 78 +- .../userdetails/ldap/LdapUserDetailsImpl.java | 406 +++++----- .../ldap/LdapUserDetailsMapper.java | 220 +++--- .../userdetails/memory/InMemoryDaoImpl.java | 53 +- .../userdetails/memory/UserAttribute.java | 41 +- .../memory/UserAttributeEditor.java | 15 +- .../userdetails/memory/UserMap.java | 77 +- .../userdetails/memory/UserMapEditor.java | 110 +-- .../acegisecurity/util/FilterChainProxy.java | 198 ++--- .../util/FilterInvocationUtils.java | 45 +- .../acegisecurity/util/FilterToBeanProxy.java | 172 ++-- .../acegisecurity/util/InMemoryResource.java | 32 +- .../util/MethodInvocationUtils.java | 60 +- .../org/acegisecurity/util/PortMapper.java | 16 +- .../acegisecurity/util/PortMapperImpl.java | 113 ++- .../org/acegisecurity/util/PortResolver.java | 4 +- .../acegisecurity/util/PortResolverImpl.java | 33 +- .../util/SimpleMethodInvocation.java | 8 +- .../acegisecurity/util/StringSplitUtils.java | 54 +- .../java/org/acegisecurity/util/UrlUtils.java | 57 +- .../vote/AbstractAccessDecisionManager.java | 62 +- .../acegisecurity/vote/AbstractAclVoter.java | 139 ++-- .../vote/AccessDecisionVoter.java | 82 +- .../acegisecurity/vote/AffirmativeBased.java | 35 +- .../vote/AuthenticatedVoter.java | 73 +- .../vote/BasicAclEntryVoter.java | 192 ++--- .../acegisecurity/vote/ConsensusBased.java | 50 +- .../org/acegisecurity/vote/RoleVoter.java | 79 +- .../acegisecurity/vote/UnanimousBased.java | 39 +- .../wrapper/SavedRequestAwareWrapper.java | 93 +-- ...curityContextHolderAwareRequestFilter.java | 37 +- ...urityContextHolderAwareRequestWrapper.java | 98 ++- .../AbstractAuthenticationManagerTests.java | 57 +- .../AcegiMessageSourceTests.java | 13 +- .../AuthenticationTrustResolverImplTests.java | 12 +- .../ConfigAttributeEditorTests.java | 32 +- .../GrantedAuthorityImplTests.java | 9 +- .../java/org/acegisecurity/ITargetObject.java | 4 +- .../MockAccessDecisionManager.java | 18 +- .../org/acegisecurity/MockAclManager.java | 19 +- .../MockAfterInvocationManager.java | 12 +- .../acegisecurity/MockApplicationContext.java | 10 +- .../MockAuthenticationEntryPoint.java | 11 +- .../org/acegisecurity/MockFilterChain.java | 4 +- .../org/acegisecurity/MockFilterConfig.java | 14 +- .../java/org/acegisecurity/MockJoinPoint.java | 10 +- .../org/acegisecurity/MockPortResolver.java | 11 +- .../MockRunAsAuthenticationToken.java | 8 +- .../org/acegisecurity/MockRunAsManager.java | 11 +- .../org/acegisecurity/OtherTargetObject.java | 25 +- .../org/acegisecurity/PopulatedDatabase.java | 44 +- .../acegisecurity/SecurityConfigTests.java | 20 +- .../java/org/acegisecurity/TargetObject.java | 33 +- .../acl/AclProviderManagerTests.java | 58 +- .../acl/basic/BasicAclProviderTests.java | 29 +- ...edAuthorityEffectiveAclsResolverTests.java | 81 +- .../acl/basic/MockAclObjectIdentity.java | 7 +- .../basic/NamedEntityObjectIdentityTests.java | 39 +- .../acl/basic/SimpleAclEntryTests.java | 53 +- .../acegisecurity/acl/basic/SomeDomain.java | 14 +- .../basic/cache/BasicAclEntryHolderTests.java | 14 +- .../cache/EhCacheBasedAclEntryCacheTests.java | 42 +- .../basic/cache/NullAclEntryCacheTests.java | 10 +- .../acl/basic/jdbc/JdbcDaoImplTests.java | 53 +- .../basic/jdbc/JdbcExtendedDaoImplTests.java | 112 ++- ...stractAdapterAuthenticationTokenTests.java | 81 +- .../adapters/AuthByAdapterTests.java | 31 +- .../HttpRequestIntegrationFilterTests.java | 35 +- .../acegisecurity/adapters/MockPrincipal.java | 4 +- .../PrincipalAcegiUserTokenTests.java | 25 +- .../AfterInvocationProviderManagerTests.java | 83 +- ...ationCollectionFilteringProviderTests.java | 188 ++--- ...cAclEntryAfterInvocationProviderTests.java | 130 ++- ...xRequestsCaptchaChannelProcessorTests.java | 40 +- ...eInMillisCaptchaChannelProcessorTests.java | 60 +- ...sBetweenRequestsChannelProcessorTests.java | 66 +- .../CaptchaChannelProcessorTemplateTests.java | 48 +- .../captcha/CaptchaEntryPointTests.java | 107 +-- .../CaptchaSecurityContextImplTests.java | 38 +- ...aptchaValidationProcessingFilterTests.java | 5 +- .../captcha/MockCaptchaServiceProxy.java | 6 +- ...xRequestsCaptchaChannelProcessorTests.java | 47 +- .../ConcurrentSessionControllerImplTests.java | 11 +- .../ConcurrentSessionFilterTests.java | 36 +- .../concurrent/SessionInformationTests.java | 7 +- .../concurrent/SessionRegistryImplTests.java | 38 +- ...pSessionContextIntegrationFilterTests.java | 99 +-- .../context/SecurityContextHolderTests.java | 363 +++++---- .../context/SecurityContextImplTests.java | 18 +- ...SimpleHttpInvokerRequestExecutorTests.java | 41 +- ...ntextPropagatingRemoteInvocationTests.java | 34 +- .../AuthenticationEventTests.java | 31 +- .../authentication/LoggerListenerTests.java | 25 +- ...ticationCredentialsNotFoundEventTests.java | 18 +- .../AuthorizationFailureEventTests.java | 36 +- .../authorization/AuthorizedEventTests.java | 11 +- .../AbstractSecurityInterceptorTests.java | 42 +- .../InterceptorStatusTokenTests.java | 14 +- .../AbstractMethodDefinitionSourceTests.java | 32 +- .../MethodDefinitionAttributesTests.java | 286 ++++--- .../MethodDefinitionSourceEditorTests.java | 95 +-- ...thodInvocationPrivilegeEvaluatorTests.java | 36 +- .../intercept/method/MockAttributes.java | 50 +- .../method/MockMethodDefinitionSource.java | 11 +- .../MethodDefinitionSourceAdvisorTests.java | 48 +- .../MethodSecurityInterceptorTests.java | 195 +++-- .../AspectJSecurityInterceptorTests.java | 52 +- ...FilterInvocationDefinitionSourceTests.java | 45 +- ...InvocationDefinitionSourceEditorTests.java | 100 +-- ...nDefinitionSourceEditorWithPathsTests.java | 117 ++- .../intercept/web/FilterInvocationTests.java | 22 +- .../web/FilterSecurityInterceptorTests.java | 47 +- .../MockFilterInvocationDefinitionSource.java | 14 +- .../PathBasedFilterDefinitionMapTests.java | 32 +- .../RegExpBasedFilterDefinitionMapTests.java | 41 +- .../WebInvocationPrivilegeEvaluatorTests.java | 19 +- .../ldap/AbstractLdapServerTestCase.java | 36 +- .../DefaultInitialDirContextFactoryTests.java | 192 ++--- .../acegisecurity/ldap/LdapTemplateTests.java | 67 +- .../acegisecurity/ldap/LdapTestServer.java | 268 +++---- .../acegisecurity/ldap/LdapUtilsTests.java | 146 ++-- .../ldap/MockInitialDirContextFactory.java | 83 +- .../FilterBasedLdapUserSearchTests.java | 100 ++- .../AbstractAuthenticationTokenTests.java | 160 ++-- .../providers/ProviderManagerTests.java | 131 ++-- .../TestingAuthenticationProviderTests.java | 20 +- .../TestingAuthenticationTokenTests.java | 13 +- ...rnamePasswordAuthenticationTokenTests.java | 25 +- .../AnonymousAuthenticationProviderTests.java | 30 +- .../AnonymousAuthenticationTokenTests.java | 76 +- .../AnonymousProcessingFilterTests.java | 36 +- .../cas/CasAuthenticationProviderTests.java | 93 +-- .../cas/CasAuthenticationTokenTests.java | 201 ++--- .../providers/cas/TicketResponseTests.java | 22 +- .../cache/EhCacheBasedTicketCacheTests.java | 60 +- .../DaoCasAuthoritiesPopulatorTests.java | 40 +- .../cas/proxy/AcceptAnyCasProxyTests.java | 14 +- .../cas/proxy/NamedCasProxyDeciderTests.java | 27 +- .../cas/proxy/RejectProxyTicketsTests.java | 20 +- .../AbstractTicketValidatorTests.java | 30 +- .../CasProxyTicketValidatorTests.java | 30 +- .../dao/DaoAuthenticationProviderTests.java | 169 ++-- .../dao/cache/EhCacheBasedUserCacheTests.java | 41 +- .../dao/cache/NullUserCacheTests.java | 22 +- .../dao/salt/ReflectionSaltSourceTests.java | 18 +- .../dao/salt/SystemWideSaltSourceTests.java | 14 +- .../encoding/BasePasswordEncoderTests.java | 39 +- .../encoding/Md5PasswordEncoderTests.java | 8 +- .../PlaintextPasswordEncoderTests.java | 8 +- .../encoding/ShaPasswordEncoderTests.java | 8 +- .../jaas/JaasAuthenticationProviderTests.java | 128 ++- .../providers/jaas/JaasEventCheck.java | 6 +- .../jaas/SecurityContextLoginModuleTests.java | 25 +- .../providers/jaas/TestAuthorityGranter.java | 4 +- .../providers/jaas/TestCallbackHandler.java | 4 +- .../providers/jaas/TestLoginModule.java | 12 +- .../ldap/LdapAuthenticationProviderTests.java | 151 ++-- .../authenticator/BindAuthenticatorTests.java | 67 +- .../LdapShaPasswordEncoderTests.java | 36 +- .../ldap/authenticator/MockUserSearch.java | 26 + ...swordComparisonAuthenticatorMockTests.java | 46 +- .../PasswordComparisonAuthenticatorTests.java | 183 +++-- .../DefaultLdapAuthoritiesPopulatorTests.java | 57 +- .../RemoteAuthenticationManagerImplTests.java | 15 +- .../RemoteAuthenticationProviderTests.java | 40 +- ...RememberMeAuthenticationProviderTests.java | 30 +- .../RememberMeAuthenticationTokenTests.java | 89 +-- .../x509/X509AuthenticationProviderTests.java | 23 +- .../x509/X509AuthenticationTokenTests.java | 6 +- .../providers/x509/X509TestUtils.java | 139 ++-- .../cache/EhCacheBasedX509UserCacheTests.java | 39 +- .../DaoX509AuthoritiesPopulatorTests.java | 27 +- .../runas/NullRunAsManagerTests.java | 14 +- .../RunAsImplAuthenticationProviderTests.java | 21 +- .../runas/RunAsManagerImplTests.java | 51 +- .../runas/RunAsUserTokenTests.java | 42 +- .../ChannelDecisionManagerImplTests.java | 36 +- .../ChannelProcessingFilterTests.java | 89 +-- .../InsecureChannelProcessorTests.java | 18 +- .../RetryWithHttpEntryPointTests.java | 29 +- .../RetryWithHttpsEntryPointTests.java | 29 +- .../SecureChannelProcessorTests.java | 18 +- .../taglibs/authz/AclTagTests.java | 61 +- .../taglibs/authz/AuthenticationTagTests.java | 41 +- .../authz/AuthorizeTagAttributeTests.java | 36 +- ...thorizeTagCustomGrantedAuthorityTests.java | 15 +- .../AuthorizeTagExpressionLanguageTests.java | 15 +- .../taglibs/authz/AuthorizeTagTests.java | 39 +- .../velocity/AuthzImplAttributeTest.java | 16 +- .../velocity/AuthzImplAuthorizeTagTest.java | 10 +- .../taglibs/velocity/AuthzImplTest.java | 60 +- .../ui/AbstractProcessingFilterTests.java | 107 +-- .../ui/ExceptionTranslationFilterTests.java | 57 +- .../BasicProcessingFilterEntryPointTests.java | 20 +- .../basicauth/BasicProcessingFilterTests.java | 76 +- .../CasProcessingFilterEntryPointTests.java | 36 +- .../ui/cas/CasProcessingFilterTests.java | 17 +- .../ui/cas/ServicePropertiesTests.java | 14 +- ...DigestProcessingFilterEntryPointTests.java | 53 +- .../DigestProcessingFilterTests.java | 215 ++--- .../NullRememberMeServicesTests.java | 16 +- .../RememberMeProcessingFilterTests.java | 59 +- .../TokenBasedRememberMeServicesTests.java | 133 ++-- .../HttpSessionEventPublisherTests.java | 57 +- .../ui/session/TestListener.java | 22 +- .../SwitchUserProcessingFilterTests.java | 129 ++- ...cationProcessingFilterEntryPointTests.java | 26 +- .../AuthenticationProcessingFilterTests.java | 33 +- ...erAuthenticationProcessingFilterTests.java | 353 +++++---- .../X509ProcessingFilterEntryPointTests.java | 21 +- .../ui/x509/X509ProcessingFilterTests.java | 48 +- .../acegisecurity/userdetails/UserTests.java | 81 +- .../userdetails/jdbc/JdbcDaoTests.java | 65 +- .../userdetails/memory/InMemoryDaoTests.java | 29 +- .../memory/UserAttributeEditorTests.java | 36 +- .../memory/UserMapEditorTests.java | 27 +- .../userdetails/memory/UserMapTests.java | 33 +- .../util/FilterChainProxyTests.java | 36 +- .../util/FilterToBeanProxyTests.java | 97 +-- .../org/acegisecurity/util/MockFilter.java | 34 +- .../acegisecurity/util/MockFilterChain.java | 13 +- .../acegisecurity/util/MockNotAFilter.java | 2 +- .../util/PortMapperImplTests.java | 32 +- .../util/PortResolverImplTests.java | 16 +- .../util/StringSplitUtilsTests.java | 30 +- .../AbstractAccessDecisionManagerTests.java | 29 +- .../vote/AffirmativeBasedTests.java | 60 +- .../vote/AuthenticatedVoterTests.java | 88 +-- .../vote/BasicAclEntryVoterTests.java | 178 ++--- .../acegisecurity/vote/DenyAgainVoter.java | 21 +- .../org/acegisecurity/vote/DenyVoter.java | 20 +- .../acegisecurity/vote/SomeDomainObject.java | 8 +- .../vote/SomeDomainObjectManager.java | 8 +- .../vote/UnanimousBasedTests.java | 103 ++- ...yContextHolderAwareRequestFilterTests.java | 9 +- ...ContextHolderAwareRequestWrapperTests.java | 32 +- .../acegisecurity/domain/DomainException.java | 11 +- .../domain/PersistableEntity.java | 27 +- .../org/acegisecurity/domain/dao/Dao.java | 130 ++- .../domain/dao/DetachmentContextHolder.java | 44 +- .../domain/dao/EvictionCapable.java | 18 +- .../domain/dao/EvictionUtils.java | 108 ++- .../domain/dao/InitializationCapable.java | 29 +- .../domain/dao/InitializationUtils.java | 69 +- .../domain/dao/PaginatedList.java | 314 ++++---- .../domain/hibernate/DaoHibernate.java | 213 ++--- .../domain/hibernate/EnumUserType.java | 200 ++--- .../IntrospectionManagerHibernate.java | 110 ++- .../impl/AbstractPersistableEntity.java | 48 +- .../domain/impl/BusinessObject.java | 33 +- .../domain/impl/PersistableEntityInteger.java | 25 +- .../domain/impl/PersistableEntityLong.java | 18 +- .../domain/impl/PersistableValue.java | 23 +- .../domain/service/ImmutableManager.java | 108 ++- .../service/ImmutableManagerEditor.java | 101 ++- .../domain/service/ImmutableManagerImpl.java | 88 ++- .../domain/util/CollectionUtils.java | 56 +- .../acegisecurity/domain/util/EnumEditor.java | 123 +-- .../domain/util/GenericsUtils.java | 20 +- .../util/ReflectionToStringBuilder.java | 117 +-- .../validation/BindBeforeValidation.java | 24 +- .../validation/BindBeforeValidationUtils.java | 11 +- .../validation/IntrospectionManager.java | 27 +- .../domain/validation/ValidationAdvisor.java | 58 +- .../validation/ValidationInterceptor.java | 46 +- .../domain/validation/ValidationManager.java | 23 +- .../validation/ValidationManagerImpl.java | 222 +++--- .../validation/ValidationRegistryManager.java | 10 +- .../ValidationRegistryManagerImpl.java | 219 +++--- .../ValidatorNotFoundException.java | 11 +- jalopy.xml | 34 +- .../main/java/acegifier/WebXmlConverter.java | 1 + .../acegifier/web/AcegifierController.java | 131 +++- .../java/acegifier/web/AcegifierForm.java | 19 + .../java/acegifier/WebXmlConverterTests.java | 27 +- .../java/sample/annotations/BankService.java | 14 +- .../sample/annotations/BankServiceImpl.java | 6 +- .../main/java/sample/annotations/Main.java | 55 +- .../java/samples/annotations/BankTests.java | 117 +-- .../java/sample/attributes/BankService.java | 3 +- .../sample/attributes/BankServiceImpl.java | 4 +- .../src/main/java/sample/attributes/Main.java | 42 +- .../java/sample/attributes/BankTests.java | 44 +- .../annotation/ContactManagerBackend.java | 184 +++-- .../java/sample/contact/AddPermission.java | 30 +- .../contact/AddPermissionController.java | 117 ++- .../contact/AddPermissionValidator.java | 19 +- .../contact/AdminPermissionController.java | 33 +- .../sample/contact/ClientApplication.java | 68 +- .../src/main/java/sample/contact/Contact.java | 46 +- .../main/java/sample/contact/ContactDao.java | 8 +- .../java/sample/contact/ContactDaoSpring.java | 65 +- .../java/sample/contact/ContactManager.java | 21 +- .../sample/contact/ContactManagerBackend.java | 154 ++-- .../sample/contact/DataSourcePopulator.java | 166 ++-- .../java/sample/contact/DeleteController.java | 23 +- .../contact/DeletePermissionController.java | 39 +- .../sample/contact/PublicIndexController.java | 25 +- .../sample/contact/SecureIndexController.java | 25 +- .../main/java/sample/contact/WebContact.java | 22 +- .../contact/WebContactAddController.java | 20 +- .../sample/contact/WebContactValidator.java | 16 +- .../acls/AccessControlEntry.java | 33 +- .../main/java/org/acegisecurity/acls/Acl.java | 184 ++--- .../acls/AclFormattingUtils.java | 30 +- .../org/acegisecurity/acls/AclService.java | 49 +- .../acls/AlreadyExistsException.java | 6 +- .../acls/AuditableAccessControlEntry.java | 22 +- .../org/acegisecurity/acls/AuditableAcl.java | 19 +- .../acls/ChildrenExistException.java | 9 +- .../acls/IdentityUnavailableException.java | 6 +- .../org/acegisecurity/acls/MutableAcl.java | 21 +- .../acegisecurity/acls/MutableAclService.java | 25 +- .../acegisecurity/acls/NotFoundException.java | 6 +- .../org/acegisecurity/acls/OwnershipAcl.java | 3 +- .../org/acegisecurity/acls/Permission.java | 37 +- .../acls/UnloadedSidException.java | 11 +- .../acls/domain/AccessControlEntryImpl.java | 227 +++--- .../acegisecurity/acls/domain/AclImpl.java | 414 +++++----- .../acls/domain/AuditLogger.java | 20 +- .../acls/domain/BasePermission.java | 146 ++-- .../acls/domain/ConsoleAuditLogger.java | 49 +- .../acls/domain/CumulativePermission.java | 37 +- .../org/acegisecurity/acls/jdbc/AclCache.java | 29 +- .../acls/jdbc/BasicLookupStrategy.java | 739 +++++++++--------- .../acls/jdbc/EhCacheBasedAclCache.java | 117 ++- .../acls/jdbc/JdbcAclService.java | 89 ++- .../acls/jdbc/LookupStrategy.java | 13 +- .../acls/objectidentity/ObjectIdentity.java | 25 +- .../objectidentity/ObjectIdentityImpl.java | 53 +- .../acls/sid/GrantedAuthoritySid.java | 26 +- .../acegisecurity/acls/sid/PrincipalSid.java | 30 +- .../java/org/acegisecurity/acls/sid/Sid.java | 11 +- .../controls/PasswordPolicyControl.java | 54 +- .../PasswordPolicyControlFactory.java | 16 +- .../PasswordPolicyResponseControl.java | 220 +++--- .../PasswordPolicyResponseControlTests.java | 2 +- .../AbstractSmbAuthenticationProvider.java | 69 +- .../smb/ChallengeExpiredException.java | 4 +- .../smb/NtlmAuthenticationToken.java | 10 +- .../smb/SmbBasicAuthenticationProvider.java | 40 +- .../smb/SmbNtlmAuthenticationProvider.java | 27 +- .../ntlm/NtlmProcessingFilterEntryPoint.java | 11 +- .../acls/domain/PermissionTests.java | 89 ++- .../acls/jdbc/DatabaseSeeder.java | 51 +- .../acls/jdbc/JdbcAclServiceTests.java | 79 +- 654 files changed, 17379 insertions(+), 21566 deletions(-) diff --git a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandler.java b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandler.java index ac2af4e4c1..6f82451b7b 100644 --- a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandler.java +++ b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.adapters.cas; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationManager; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.apache.commons.logging.Log; @@ -29,51 +30,32 @@ import javax.servlet.ServletRequest; /** - * Provides actual CAS authentication by delegation to an - * AuthenticationManager. - * - *

- * Do not use this class directly. Instead configure CAS to use the {@link - * CasPasswordHandlerProxy}. - *

+ * Provides actual CAS authentication by delegation to an AuthenticationManager.

Do not use this + * class directly. Instead configure CAS to use the {@link CasPasswordHandlerProxy}.

* * @author Ben Alex * @version $Id$ */ public final class CasPasswordHandler implements InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CasPasswordHandler.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationManager authenticationManager; - //~ Methods ================================================================ - - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - public AuthenticationManager getAuthenticationManager() { - return authenticationManager; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { if (this.authenticationManager == null) { - throw new IllegalArgumentException( - "An AuthenticationManager is required"); + throw new IllegalArgumentException("An AuthenticationManager is required"); } } /** - * Called by CasPasswordHandlerProxy for individual - * authentication requests. - * - *

- * Delegates to the configured AuthenticationManager. - *

+ * Called by CasPasswordHandlerProxy for individual authentication requests.

Delegates to + * the configured AuthenticationManager.

* * @param servletRequest as provided by CAS * @param username provided to CAS @@ -81,8 +63,7 @@ public final class CasPasswordHandler implements InitializingBean { * * @return whether authentication was successful or not */ - public boolean authenticate(ServletRequest servletRequest, String username, - String password) { + public boolean authenticate(ServletRequest servletRequest, String username, String password) { if ((username == null) || "".equals(username)) { return false; } @@ -91,26 +72,31 @@ public final class CasPasswordHandler implements InitializingBean { password = ""; } - Authentication request = new UsernamePasswordAuthenticationToken(username - .toString(), password.toString()); + Authentication request = new UsernamePasswordAuthenticationToken(username.toString(), password.toString()); Authentication response = null; try { response = authenticationManager.authenticate(request); } catch (AuthenticationException failed) { if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " failed: " + failed.toString()); + logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); } return false; } if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " successful"); + logger.debug("Authentication request for user: " + username + " successful"); } return true; } + + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } } diff --git a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxy.java b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxy.java index b1cb782c4b..a3c24a9a9e 100644 --- a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxy.java +++ b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxy.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,62 +31,39 @@ import javax.servlet.http.HttpServletRequest; /** - * Enables CAS to use the Acegi Security System for authentication. - * - *

- * This class works along with {@link CasPasswordHandler} to enable users to - * easily migrate from stand-alone Acegi Security System deployments to - * enterprise-wide CAS deployments. - *

- * - *

- * It should be noted that the Acegi Security System will operate as a CAS - * client irrespective of the PasswordHandler used on the CAS - * server. In other words, this class need not be used on the CAS - * server if not desired. It exists solely for the convenience of users - * wishing have CAS delegate to an Acegi Security System-based - * AuthenticationManager. - *

- * - *

- * This class works requires a properly configured - * CasPasswordHandler. On the first authentication request, the - * class will use Spring's {@link - * WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)} - * method to obtain an ApplicationContext instance, inside which - * must be a configured CasPasswordHandler instance. The - * CasPasswordHandlerProxy will then delegate authentication - * requests to that instance. - *

- * - *

- * To configure CAS to use this class, edit CAS' web.xml and - * define the edu.yale.its.tp.cas.authHandler context parameter - * with the value - * org.acegisecurity.adapters.cas.CasPasswordHandlerProxy. - *

+ * Enables CAS to use the Acegi Security System for authentication.

This class works along with {@link + * CasPasswordHandler} to enable users to easily migrate from stand-alone Acegi Security System deployments to + * enterprise-wide CAS deployments.

+ *

It should be noted that the Acegi Security System will operate as a CAS client irrespective of the + * PasswordHandler used on the CAS server. In other words, this class need not be used on the CAS + * server if not desired. It exists solely for the convenience of users wishing have CAS delegate to an Acegi Security + * System-based AuthenticationManager.

+ *

This class works requires a properly configured CasPasswordHandler. On the first authentication + * request, the class will use Spring's {@link WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)} + * method to obtain an ApplicationContext instance, inside which must be a configured + * CasPasswordHandler instance. The CasPasswordHandlerProxy will then delegate + * authentication requests to that instance.

+ *

To configure CAS to use this class, edit CAS' web.xml and define the + * edu.yale.its.tp.cas.authHandler context parameter with the value + * org.acegisecurity.adapters.cas.CasPasswordHandlerProxy.

* * @author Ben Alex * @version $Id$ */ public class CasPasswordHandlerProxy implements PasswordHandler { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CasPasswordHandlerProxy.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext ctx; private CasPasswordHandler handler; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Called by CAS when authentication is required. - * - *

- * Delegates to the CasPasswordHandler. - *

+ * Called by CAS when authentication is required.

Delegates to the CasPasswordHandler.

* * @param request as provided by CAS * @param username provided to CAS @@ -94,17 +71,13 @@ public class CasPasswordHandlerProxy implements PasswordHandler { * * @return whether authentication was successful or not * - * @throws IllegalArgumentException if the application context does not - * contain a CasPasswordHandler or the - * ServletRequest was not of type - * HttpServletRequest + * @throws IllegalArgumentException if the application context does not contain a CasPasswordHandler + * or the ServletRequest was not of type HttpServletRequest */ - public boolean authenticate(ServletRequest request, String username, - String password) { + public boolean authenticate(ServletRequest request, String username, String password) { if (ctx == null) { if (!(request instanceof HttpServletRequest)) { - throw new IllegalArgumentException( - "Can only process HttpServletRequest"); + throw new IllegalArgumentException("Can only process HttpServletRequest"); } HttpServletRequest httpRequest = (HttpServletRequest) request; @@ -130,13 +103,11 @@ public class CasPasswordHandlerProxy implements PasswordHandler { /** * Allows test cases to override where application context obtained from. * - * @param httpRequest which can be used to find the - * ServletContext + * @param httpRequest which can be used to find the ServletContext * * @return the Spring application context */ protected ApplicationContext getContext(HttpServletRequest httpRequest) { - return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession() - .getServletContext()); + return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext()); } } diff --git a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandler.java b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandler.java index 6a51e3e022..7f19250c30 100644 --- a/adapters/cas/src/main/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandler.java +++ b/adapters/cas/src/main/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,90 +12,80 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.adapters.cas3; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationManager; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.jasig.cas.authentication.handler.AuthenticationException; import org.jasig.cas.authentication.handler.AuthenticationHandler; import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; + import org.springframework.util.Assert; + /** - *

- * Provides JA-SIG CAS 3 authentication by delegating to the Acegi - * AuthenticationManager. - *

- *

- * This class would be configured in the - * webapp/WEB-INF/deployerConfigContext.xml file in the CAS - * distribution. - *

- * + *

Provides JA-SIG CAS 3 authentication by delegating to the Acegi AuthenticationManager.

+ *

This class would be configured in the webapp/WEB-INF/deployerConfigContext.xml file in the CAS + * distribution.

+ * * @author Scott Battaglia * @version $Id$ - * + * * @see AuthenticationHandler * @see AuthenticationManager */ -public final class CasAuthenticationHandler extends - AbstractUsernamePasswordAuthenticationHandler { +public final class CasAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler { + //~ Instance fields ================================================================================================ - private Log log = LogFactory.getLog(this.getClass()); + private AuthenticationManager authenticationManager; + private Log log = LogFactory.getLog(this.getClass()); - private AuthenticationManager authenticationManager; + //~ Methods ======================================================================================================== - protected boolean authenticateUsernamePasswordInternal( - final UsernamePasswordCredentials credentials) - throws AuthenticationException { + protected void afterPropertiesSetInternal() throws Exception { + Assert.notNull(this.authenticationManager, "authenticationManager cannot be null."); + } - final Authentication authenticationRequest = new UsernamePasswordAuthenticationToken( - credentials.getUsername(), credentials.getPassword()); + protected boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) + throws AuthenticationException { + final Authentication authenticationRequest = new UsernamePasswordAuthenticationToken(credentials.getUsername(), + credentials.getPassword()); - if (log.isDebugEnabled()) { - log.debug("Attempting to authenticate for user: " - + credentials.getUsername()); - } + if (log.isDebugEnabled()) { + log.debug("Attempting to authenticate for user: " + credentials.getUsername()); + } - try { - this.authenticationManager.authenticate(authenticationRequest); - } catch (final org.acegisecurity.AuthenticationException e) { - if (log.isDebugEnabled()) { - log - .debug("Authentication request for " - + credentials.getUsername() + "failed: " - + e.toString()); - } - return false; - } + try { + this.authenticationManager.authenticate(authenticationRequest); + } catch (final org.acegisecurity.AuthenticationException e) { + if (log.isDebugEnabled()) { + log.debug("Authentication request for " + credentials.getUsername() + "failed: " + e.toString()); + } - if (log.isDebugEnabled()) { - log.debug("Authentication request for " + credentials.getUsername() - + " successful."); - } + return false; + } - return true; - } + if (log.isDebugEnabled()) { + log.debug("Authentication request for " + credentials.getUsername() + " successful."); + } - protected void afterPropertiesSetInternal() throws Exception { - Assert.notNull(this.authenticationManager, - "authenticationManager cannot be null."); - } + return true; + } - /** - * Method to set the Acegi AuthenticationManager to delegate - * to. - * - * @param authenticationManager - * the Acegi AuthenticationManager that knows how to authenticate - * users. - */ - public void setAuthenticationManager( - final AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } + /** + * Method to set the Acegi AuthenticationManager to delegate to. + * + * @param authenticationManager the Acegi AuthenticationManager that knows how to authenticate users. + */ + public void setAuthenticationManager(final AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } } diff --git a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxyTests.java b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxyTests.java index aa6323d9a6..626d738a47 100644 --- a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxyTests.java +++ b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerProxyTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import javax.servlet.http.HttpServletRequest; * @version $Id$ */ public class CasPasswordHandlerProxyTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasPasswordHandlerProxyTests() { super(); @@ -42,16 +42,16 @@ public class CasPasswordHandlerProxyTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasPasswordHandlerProxyTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsIfHttpServletRequestNotPassed() { CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy( "org/acegisecurity/adapters/cas/applicationContext-valid.xml"); @@ -60,8 +60,7 @@ public class CasPasswordHandlerProxyTests extends TestCase { proxy.authenticate(null, "x", "y"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -73,23 +72,19 @@ public class CasPasswordHandlerProxyTests extends TestCase { proxy.authenticate(new MockHttpServletRequest(), "x", "y"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Bean context must contain at least one bean of type CasPasswordHandler", - expected.getMessage()); + assertEquals("Bean context must contain at least one bean of type CasPasswordHandler", expected.getMessage()); } } public void testNormalOperation() { CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy( "org/acegisecurity/adapters/cas/applicationContext-valid.xml"); - assertTrue(proxy.authenticate(new MockHttpServletRequest(), "marissa", - "koala")); - assertFalse(proxy.authenticate(new MockHttpServletRequest(), "marissa", - "WRONG_PASSWORD")); - assertFalse(proxy.authenticate(new MockHttpServletRequest(), - "INVALID_USER_NAME", "WRONG_PASSWORD")); + assertTrue(proxy.authenticate(new MockHttpServletRequest(), "marissa", "koala")); + assertFalse(proxy.authenticate(new MockHttpServletRequest(), "marissa", "WRONG_PASSWORD")); + assertFalse(proxy.authenticate(new MockHttpServletRequest(), "INVALID_USER_NAME", "WRONG_PASSWORD")); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** * Mock object so that application context source can be specified. diff --git a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerTests.java b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerTests.java index 3272028d22..3d09d5e67e 100644 --- a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerTests.java +++ b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/CasPasswordHandlerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class CasPasswordHandlerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasPasswordHandlerTests() { super(); @@ -39,24 +39,23 @@ public class CasPasswordHandlerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasPasswordHandlerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDeniesAccessWhenAuthenticationManagerThrowsException() throws Exception { CasPasswordHandler handler = new CasPasswordHandler(); handler.setAuthenticationManager(new MockAuthenticationManager(false)); handler.afterPropertiesSet(); - assertFalse(handler.authenticate(new MockHttpServletRequest(), - "username", "password")); + assertFalse(handler.authenticate(new MockHttpServletRequest(), "username", "password")); } public void testDetectsEmptyAuthenticationManager() @@ -67,8 +66,7 @@ public class CasPasswordHandlerTests extends TestCase { handler.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An AuthenticationManager is required", - expected.getMessage()); + assertEquals("An AuthenticationManager is required", expected.getMessage()); } } @@ -85,14 +83,11 @@ public class CasPasswordHandlerTests extends TestCase { handler.afterPropertiesSet(); // If empty or null username we return false - assertFalse(handler.authenticate(new MockHttpServletRequest(), "", - "password")); - assertFalse(handler.authenticate(new MockHttpServletRequest(), null, - "password")); + assertFalse(handler.authenticate(new MockHttpServletRequest(), "", "password")); + assertFalse(handler.authenticate(new MockHttpServletRequest(), null, "password")); // We authenticate with null passwords (they might not have one) - assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", - null)); + assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", null)); assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", "")); } @@ -101,7 +96,6 @@ public class CasPasswordHandlerTests extends TestCase { handler.setAuthenticationManager(new MockAuthenticationManager(true)); handler.afterPropertiesSet(); - assertTrue(handler.authenticate(new MockHttpServletRequest(), - "username", "password")); + assertTrue(handler.authenticate(new MockHttpServletRequest(), "username", "password")); } } diff --git a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandlerTests.java b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandlerTests.java index b58c4867ba..c4093160c2 100644 --- a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandlerTests.java +++ b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas3/CasAuthenticationHandlerTests.java @@ -1,77 +1,97 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.adapters.cas3; import org.acegisecurity.AuthenticationManager; + import org.jasig.cas.authentication.handler.AuthenticationException; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; + import org.springframework.test.AbstractDependencyInjectionSpringContextTests; + /** * Tests {@link CasAuthenticationHandler} + * * @author Scott Battaglia * @version $Id$ - * */ public class CasAuthenticationHandlerTests extends AbstractDependencyInjectionSpringContextTests { + //~ Instance fields ================================================================================================ - private AuthenticationManager authenticationManager; - - private CasAuthenticationHandler casAuthenticationHandler; - - public void setAuthenticationManager(final AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } + private AuthenticationManager authenticationManager; + private CasAuthenticationHandler casAuthenticationHandler; - protected String[] getConfigLocations() { - return new String[] {"/org/acegisecurity/adapters/cas/applicationContext-valid.xml"}; - } + //~ Methods ======================================================================================================== - protected void onSetUp() throws Exception { - this.casAuthenticationHandler = new CasAuthenticationHandler(); - this.casAuthenticationHandler.setAuthenticationManager(authenticationManager); - this.casAuthenticationHandler.afterPropertiesSet(); - } - - public void testAfterPropertiesSet() throws Exception { - this.casAuthenticationHandler.setAuthenticationManager(null); - try { - this.casAuthenticationHandler.afterPropertiesSet(); - fail("IllegalArgumenException expected when no AuthenticationManager is set."); - } catch (final IllegalArgumentException e) { - // this is okay - } - } - - public void testValidUsernamePasswordCombination() { - try { - assertTrue(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "wombat"))); - } catch (final AuthenticationException e) { - fail("AuthenticationException not expected."); - } - } - - public void testInvalidUsernamePasswordCombination() { - try { - assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "scott"))); - } catch (final AuthenticationException e) { - fail("AuthenticationException not expected."); - } - } - - public void testGracefullyHandlesInvalidInput() { + protected String[] getConfigLocations() { + return new String[] {"/org/acegisecurity/adapters/cas/applicationContext-valid.xml"}; + } - try { - assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("", ""))); - assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor(null, null))); - } catch (final AuthenticationException e) { - fail("AuthenticationException not expected."); - } - } - - private UsernamePasswordCredentials getCredentialsFor(final String username, final String password) { - final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(); - credentials.setUsername(username); - credentials.setPassword(password); - - return credentials; - } + private UsernamePasswordCredentials getCredentialsFor(final String username, final String password) { + final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(); + credentials.setUsername(username); + credentials.setPassword(password); + + return credentials; + } + + protected void onSetUp() throws Exception { + this.casAuthenticationHandler = new CasAuthenticationHandler(); + this.casAuthenticationHandler.setAuthenticationManager(authenticationManager); + this.casAuthenticationHandler.afterPropertiesSet(); + } + + public void setAuthenticationManager(final AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + public void testAfterPropertiesSet() throws Exception { + this.casAuthenticationHandler.setAuthenticationManager(null); + + try { + this.casAuthenticationHandler.afterPropertiesSet(); + fail("IllegalArgumenException expected when no AuthenticationManager is set."); + } catch (final IllegalArgumentException e) { + // this is okay + } + } + + public void testGracefullyHandlesInvalidInput() { + try { + assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("", ""))); + assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor(null, null))); + } catch (final AuthenticationException e) { + fail("AuthenticationException not expected."); + } + } + + public void testInvalidUsernamePasswordCombination() { + try { + assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "scott"))); + } catch (final AuthenticationException e) { + fail("AuthenticationException not expected."); + } + } + + public void testValidUsernamePasswordCombination() { + try { + assertTrue(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "wombat"))); + } catch (final AuthenticationException e) { + fail("AuthenticationException not expected."); + } + } } diff --git a/adapters/catalina/src/main/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealm.java b/adapters/catalina/src/main/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealm.java index efc5953016..f1658cd951 100644 --- a/adapters/catalina/src/main/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealm.java +++ b/adapters/catalina/src/main/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealm.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,48 +41,27 @@ import java.util.Map; /** - * Adapter to enable Catalina (Tomcat) to authenticate via the Acegi Security - * System for Spring. - * - *

- * Returns a {@link PrincipalAcegiUserToken} to Catalina's authentication - * system, which is subsequently available via - * HttpServletRequest.getUserPrincipal(). - *

+ * Adapter to enable Catalina (Tomcat) to authenticate via the Acegi Security System for Spring.

Returns a {@link + * PrincipalAcegiUserToken} to Catalina's authentication system, which is subsequently available via + * HttpServletRequest.getUserPrincipal().

* * @author Ben Alex * @version $Id$ */ public class CatalinaAcegiUserRealm extends RealmBase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CatalinaAcegiUserRealm.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - protected final String name = "CatalinaSpringUserRealm / $Id$"; private AuthenticationManager authenticationManager; private Container container; private String appContextLocation; private String key; + protected final String name = "CatalinaSpringUserRealm / $Id$"; - //~ Methods ================================================================ - - public void setAppContextLocation(String appContextLocation) { - this.appContextLocation = appContextLocation; - } - - public String getAppContextLocation() { - return appContextLocation; - } - - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; - } + //~ Methods ======================================================================================================== public Principal authenticate(String username, String credentials) { if (username == null) { @@ -93,25 +72,21 @@ public class CatalinaAcegiUserRealm extends RealmBase { credentials = ""; } - Authentication request = new UsernamePasswordAuthenticationToken(username, - credentials); + Authentication request = new UsernamePasswordAuthenticationToken(username, credentials); Authentication response = null; try { response = authenticationManager.authenticate(request); } catch (AuthenticationException failed) { if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " failed: " + failed.toString()); + logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); } return null; } - return new PrincipalAcegiUserToken(this.key, - response.getPrincipal().toString(), - response.getCredentials().toString(), response.getAuthorities(), - response.getPrincipal()); + return new PrincipalAcegiUserToken(this.key, response.getPrincipal().toString(), + response.getCredentials().toString(), response.getAuthorities(), response.getPrincipal()); } public Principal authenticate(String username, byte[] credentials) { @@ -132,10 +107,9 @@ public class CatalinaAcegiUserRealm extends RealmBase { * * @return DOCUMENT ME! */ - public java.security.Principal authenticate(java.lang.String username, - java.lang.String digest, java.lang.String nonce, java.lang.String nc, - java.lang.String cnonce, java.lang.String qop, java.lang.String realm, - java.lang.String md5a2) { + public java.security.Principal authenticate(java.lang.String username, java.lang.String digest, + java.lang.String nonce, java.lang.String nc, java.lang.String cnonce, java.lang.String qop, + java.lang.String realm, java.lang.String md5a2) { return null; } @@ -150,31 +124,12 @@ public class CatalinaAcegiUserRealm extends RealmBase { return null; } - public boolean hasRole(Principal principal, String role) { - if ((principal == null) || (role == null)) { - return false; - } - - if (!(principal instanceof PrincipalAcegiUserToken)) { - logger.warn( - "Expected passed principal to be of type PrincipalAcegiUserToken but was " - + principal.getClass().getName()); - - return false; - } - - PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal; - - return test.isUserInRole(role); + public String getAppContextLocation() { + return appContextLocation; } - /** - * Provides the method that Catalina will use to start the container. - * - * @throws LifecycleException if a problem is detected - */ - public void start() throws LifecycleException { - this.start(true); + public String getKey() { + return key; } protected String getName() { @@ -203,14 +158,38 @@ public class CatalinaAcegiUserRealm extends RealmBase { return null; } + public boolean hasRole(Principal principal, String role) { + if ((principal == null) || (role == null)) { + return false; + } + + if (!(principal instanceof PrincipalAcegiUserToken)) { + logger.warn("Expected passed principal to be of type PrincipalAcegiUserToken but was " + + principal.getClass().getName()); + + return false; + } + + PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal; + + return test.isUserInRole(role); + } + + public void setAppContextLocation(String appContextLocation) { + this.appContextLocation = appContextLocation; + } + + public void setKey(String key) { + this.key = key; + } + /** - * Provides a method to load the container adapter without delegating to - * the superclass, which cannot operate outside the Catalina container. + * Provides the method that Catalina will use to start the container. * * @throws LifecycleException if a problem is detected */ - protected void startForTest() throws LifecycleException { - this.start(false); + public void start() throws LifecycleException { + this.start(true); } private void start(boolean startParent) throws LifecycleException { @@ -226,17 +205,13 @@ public class CatalinaAcegiUserRealm extends RealmBase { throw new LifecycleException("key must be defined"); } - File xml = new File(System.getProperty("catalina.base"), - appContextLocation); + File xml = new File(System.getProperty("catalina.base"), appContextLocation); if (!xml.exists()) { - throw new LifecycleException( - "appContextLocation does not seem to exist in " - + xml.toString()); + throw new LifecycleException("appContextLocation does not seem to exist in " + xml.toString()); } - FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext( - "file:" + xml.getAbsolutePath()); + FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("file:" + xml.getAbsolutePath()); Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true); if (beans.size() == 0) { @@ -248,4 +223,14 @@ public class CatalinaAcegiUserRealm extends RealmBase { authenticationManager = (AuthenticationManager) beans.get(beanName); logger.info("CatalinaAcegiUserRealm Started"); } + + /** + * Provides a method to load the container adapter without delegating to the superclass, which cannot + * operate outside the Catalina container. + * + * @throws LifecycleException if a problem is detected + */ + protected void startForTest() throws LifecycleException { + this.start(false); + } } diff --git a/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java b/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java index 9a43d09803..bdf5f32dd4 100644 --- a/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java +++ b/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,11 +38,11 @@ import java.security.Principal; * @version $Id$ */ public class CatalinaAcegiUserRealmTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final String ADAPTER_KEY = "my_key"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CatalinaAcegiUserRealmTests() { super(); @@ -52,21 +52,41 @@ public class CatalinaAcegiUserRealmTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CatalinaAcegiUserRealmTests.class); } + private CatalinaAcegiUserRealm makeAdapter(String fileName) + throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + + URL url = Thread.currentThread().getContextClassLoader().getResource("org/acegisecurity/adapters/" + fileName); + + if (url == null) { + throw new Exception("Could not find " + fileName + " - cannot continue"); + } + + File file = new File(url.getFile()); + + System.setProperty("catalina.base", file.getParentFile().getAbsolutePath()); + System.out.println("catalina.base set to: " + System.getProperty("catalina.base")); + adapter.setAppContextLocation(fileName); + adapter.setKey(ADAPTER_KEY); + adapter.startForTest(); + + return adapter; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() throws Exception { try { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-invalid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-invalid.xml"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -83,8 +103,7 @@ public class CatalinaAcegiUserRealmTests extends TestCase { adapter.startForTest(); fail("Should have thrown LifecycleException"); } catch (LifecycleException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } adapter.setAppContextLocation(""); @@ -93,8 +112,7 @@ public class CatalinaAcegiUserRealmTests extends TestCase { adapter.startForTest(); fail("Should have thrown LifecycleException"); } catch (LifecycleException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } } @@ -140,15 +158,13 @@ public class CatalinaAcegiUserRealmTests extends TestCase { } public void testAdapterStartsUpSuccess() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); assertTrue(true); } public void testAuthenticateManyParamsReturnsNull() { CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); - assertEquals(null, - adapter.authenticate(null, null, null, null, null, null, null, null)); + assertEquals(null, adapter.authenticate(null, null, null, null, null, null, null, null)); } public void testAuthenticateX509ReturnsNull() { @@ -158,22 +174,19 @@ public class CatalinaAcegiUserRealmTests extends TestCase { public void testAuthenticationFailsForIncorrectPassword() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); assertEquals(null, adapter.authenticate("marissa", "kangaroo")); } public void testAuthenticationFailsForIncorrectUserName() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); assertEquals(null, adapter.authenticate("melissa", "koala")); } public void testAuthenticationUsingByteArrayForCredentials() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); byte[] credentials = {'k', 'o', 'a', 'l', 'a'}; Principal result = adapter.authenticate("marissa", credentials); @@ -184,17 +197,14 @@ public class CatalinaAcegiUserRealmTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } public void testAuthenticationUsingStringForCredentials() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); Principal result = adapter.authenticate("marissa", "koala"); if (!(result instanceof PrincipalAcegiUserToken)) { @@ -204,24 +214,20 @@ public class CatalinaAcegiUserRealmTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } public void testAuthenticationWithNullPasswordHandledGracefully() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); assertEquals(null, adapter.authenticate("marissa", (String) null)); } public void testAuthenticationWithNullUserNameHandledGracefully() throws Exception { - CatalinaAcegiUserRealm adapter = makeAdapter( - "catalinaAdapterTest-valid.xml"); + CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml"); assertEquals(null, adapter.authenticate(null, "koala")); } @@ -258,38 +264,12 @@ public class CatalinaAcegiUserRealmTests extends TestCase { } public void testHasRoleWithPrincipalAcegiUserToken() { - PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, null); + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + null); CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); assertTrue(adapter.hasRole(token, "ROLE_ONE")); assertTrue(adapter.hasRole(token, "ROLE_TWO")); assertTrue(!adapter.hasRole(token, "ROLE_WE_DO_NOT_HAVE")); } - - private CatalinaAcegiUserRealm makeAdapter(String fileName) - throws Exception { - CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); - - URL url = Thread.currentThread().getContextClassLoader().getResource("org/acegisecurity/adapters/" - + fileName); - - if (url == null) { - throw new Exception("Could not find " + fileName - + " - cannot continue"); - } - - File file = new File(url.getFile()); - - System.setProperty("catalina.base", - file.getParentFile().getAbsolutePath()); - System.out.println("catalina.base set to: " - + System.getProperty("catalina.base")); - adapter.setAppContextLocation(fileName); - adapter.setKey(ADAPTER_KEY); - adapter.startForTest(); - - return adapter; - } } diff --git a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModule.java b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModule.java index 6689315767..7cafa95f95 100644 --- a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModule.java +++ b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModule.java @@ -52,28 +52,23 @@ import javax.security.auth.login.LoginException; /** - * Adapter to enable JBoss to authenticate via the Acegi Security System for - * Spring. - * - *

- * Returns a {@link PrincipalAcegiUserToken} to JBoss' authentication system, - * which is subsequently available from - * java:comp/env/security/subject. - *

+ * Adapter to enable JBoss to authenticate via the Acegi Security System for Spring.

Returns a {@link + * PrincipalAcegiUserToken} to JBoss' authentication system, which is subsequently available from + * java:comp/env/security/subject.

* * @author Ben Alex * @author Sergio Bern� * @version $Id$ */ public class JbossAcegiLoginModule extends AbstractServerLoginModule { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationManager authenticationManager; private Principal identity; private String key; private char[] credential; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected Principal getIdentity() { return this.identity; @@ -87,8 +82,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { Authentication user = (Authentication) this.identity; for (int i = 0; i < user.getAuthorities().length; i++) { - roles.addMember(new SimplePrincipal( - user.getAuthorities()[i].getAuthority())); + roles.addMember(new SimplePrincipal(user.getAuthorities()[i].getAuthority())); } } @@ -100,8 +94,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { // prompt for a username and password if (callbackHandler == null) { - throw new LoginException("Error: no CallbackHandler available " - + "to collect authentication information"); + throw new LoginException("Error: no CallbackHandler available " + "to collect authentication information"); } NameCallback nc = new NameCallback("User name: ", "guest"); @@ -118,16 +111,14 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { if (tmpPassword != null) { credential = new char[tmpPassword.length]; - System.arraycopy(tmpPassword, 0, credential, 0, - tmpPassword.length); + System.arraycopy(tmpPassword, 0, credential, 0, tmpPassword.length); pc.clearPassword(); password = new String(credential); } } catch (java.io.IOException ioe) { throw new LoginException(ioe.toString()); } catch (UnsupportedCallbackException uce) { - throw new LoginException("CallbackHandler does not support: " - + uce.getCallback()); + throw new LoginException("CallbackHandler does not support: " + uce.getCallback()); } info[0] = username; @@ -136,8 +127,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { return info; } - public void initialize(Subject subject, CallbackHandler callbackHandler, - Map sharedState, Map options) { + public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { super.initialize(subject, callbackHandler, sharedState, options); if (super.log.isInfoEnabled()) { @@ -154,24 +144,21 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { String appContextLocation = (String) options.get("appContextLocation"); - if ((((singletonId == null) || "".equals(singletonId)) - && (appContextLocation == null)) || "".equals(appContextLocation)) { - throw new IllegalArgumentException( - "appContextLocation must be defined"); + if ((((singletonId == null) || "".equals(singletonId)) && (appContextLocation == null)) + || "".equals(appContextLocation)) { + throw new IllegalArgumentException("appContextLocation must be defined"); } String beanName = (String) options.get("authenticationManager"); // Attempt to find the appContextLocation only if no singletonId was defined if ((singletonId == null) || "".equals(singletonId)) { - if (Thread.currentThread().getContextClassLoader() - .getResource(appContextLocation) == null) { + if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) { if (super.log.isInfoEnabled()) { super.log.info("cannot locate " + appContextLocation); } - throw new IllegalArgumentException("Cannot locate " - + appContextLocation); + throw new IllegalArgumentException("Cannot locate " + appContextLocation); } } @@ -182,13 +169,10 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { ctx = new ClassPathXmlApplicationContext(appContextLocation); } catch (Exception e) { if (super.log.isInfoEnabled()) { - super.log.info("error loading spring context " - + appContextLocation + " " + e); + super.log.info("error loading spring context " + appContextLocation + " " + e); } - throw new IllegalArgumentException( - "error loading spring context " + appContextLocation + " " - + e); + throw new IllegalArgumentException("error loading spring context " + appContextLocation + " " + e); } } else { if (super.log.isInfoEnabled()) { @@ -204,8 +188,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { super.log.info("singleton " + beanName + " does not exists"); } - throw new IllegalArgumentException("singleton " + singletonId - + " does not exists"); + throw new IllegalArgumentException("singleton " + singletonId + " does not exists"); } } @@ -213,15 +196,13 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { Map beans = null; try { - beans = ctx.getBeansOfType(AuthenticationManager.class, true, - true); + beans = ctx.getBeansOfType(AuthenticationManager.class, true, true); } catch (Exception e) { if (super.log.isInfoEnabled()) { super.log.info("exception in getBeansOfType " + e); } - throw new IllegalStateException( - "spring error in get beans by class"); + throw new IllegalStateException("spring error in get beans by class"); } if (beans.size() == 0) { @@ -248,8 +229,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { if ((username == null) && (password == null)) { identity = null; - super.log.trace("Authenticating as unauthenticatedIdentity=" - + identity); + super.log.trace("Authenticating as unauthenticatedIdentity=" + identity); } if (username == null) { @@ -267,8 +247,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { if (identity == null) { super.log.debug("creating usernamepassword token"); - Authentication request = new UsernamePasswordAuthenticationToken(username, - password); + Authentication request = new UsernamePasswordAuthenticationToken(username, password); Authentication response = null; try { @@ -290,8 +269,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { "The credential used to identify the user has expired"); } catch (AccountExpiredException cee) { if (super.log.isDebugEnabled()) { - super.log.debug( - "Account has expired, throwing jaas exception"); + super.log.debug("Account has expired, throwing jaas exception"); } throw new javax.security.auth.login.AccountExpiredException( @@ -301,14 +279,12 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { super.log.debug("Bad password for username=" + username); } - throw new FailedLoginException( - "Password Incorrect/Password Required"); + throw new FailedLoginException("Password Incorrect/Password Required"); } super.log.debug("user is logged. redirecting to jaas classes"); - identity = new PrincipalAcegiUserToken(this.key, - response.getName(), response.getCredentials().toString(), + identity = new PrincipalAcegiUserToken(this.key, response.getName(), response.getCredentials().toString(), response.getAuthorities(), response.getPrincipal()); } @@ -319,8 +295,7 @@ public class JbossAcegiLoginModule extends AbstractServerLoginModule { } super.loginOk = true; - super.log.trace("User '" + identity + "' authenticated, loginOk=" - + loginOk); + super.log.trace("User '" + identity + "' authenticated, loginOk=" + loginOk); return true; } diff --git a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java index de85938443..c2d21d6eea 100644 --- a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java +++ b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.adapters.jboss; import org.acegisecurity.Authentication; + import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.logging.Log; @@ -42,76 +43,45 @@ import javax.servlet.ServletResponse; /** - * Populates a {@link org.acegisecurity.context.security.SecureContext} from - * JBoss' java:comp/env/security/subject. - * - *

- * This filter never preserves the Authentication on the - * ContextHolder - it is replaced every request. - *

- * - *

- * See {@link HttpSessionContextIntegrationFilter} for further information. - *

+ * Populates a {@link org.acegisecurity.context.security.SecureContext} from JBoss' + * java:comp/env/security/subject.

This filter never preserves the + * Authentication on the ContextHolder - it is replaced every request.

+ *

See {@link HttpSessionContextIntegrationFilter} for further information.

* * @author Ben Alex * @version $Id$ */ public class JbossIntegrationFilter implements Filter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(JbossIntegrationFilter.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Does nothing. We use IoC container lifecycle services instead. */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { Object principal = extractFromContainer(request); if ((principal != null) && principal instanceof Authentication) { SecurityContextHolder.getContext().setAuthentication((Authentication) principal); if (logger.isDebugEnabled()) { - logger.debug( - "ContextHolder updated with Authentication from container: '" - + principal + "'"); + logger.debug("ContextHolder updated with Authentication from container: '" + principal + "'"); } } else { if (logger.isDebugEnabled()) { - logger.debug( - "ContextHolder not set with new Authentication as Principal was: '" - + principal + "'"); + logger.debug("ContextHolder not set with new Authentication as Principal was: '" + principal + "'"); } } chain.doFilter(request, response); } - /** - * Does nothing. We use IoC container lifecycle services instead. - * - * @param arg0 ignored - * - * @throws ServletException ignored - */ - public void init(FilterConfig arg0) throws ServletException {} - - /** - * Provided so that unit tests can override. - * - * @return a Context that can be used for lookup - * - * @throws NamingException DOCUMENT ME! - */ - protected Context getLookupContext() throws NamingException { - return new InitialContext(); - } - private Object extractFromContainer(ServletRequest request) { Subject subject = null; @@ -133,8 +103,7 @@ public class JbossIntegrationFilter implements Filter { } } catch (NamingException ne) { if (logger.isWarnEnabled()) { - logger.warn("Lookup on Subject failed " - + ne.getLocalizedMessage()); + logger.warn("Lookup on Subject failed " + ne.getLocalizedMessage()); } } @@ -152,4 +121,24 @@ public class JbossIntegrationFilter implements Filter { return null; } + + /** + * Provided so that unit tests can override. + * + * @return a Context that can be used for lookup + * + * @throws NamingException DOCUMENT ME! + */ + protected Context getLookupContext() throws NamingException { + return new InitialContext(); + } + + /** + * Does nothing. We use IoC container lifecycle services instead. + * + * @param arg0 ignored + * + * @throws ServletException ignored + */ + public void init(FilterConfig arg0) throws ServletException {} } diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java index 0d07ab4b56..b6f3bd98d3 100644 --- a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,11 +45,11 @@ import javax.security.auth.login.LoginException; * @version $Id$ */ public class JbossAcegiLoginModuleTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final String ADAPTER_KEY = "my_key"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JbossAcegiLoginModuleTests() { super(); @@ -59,23 +59,22 @@ public class JbossAcegiLoginModuleTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JbossAcegiLoginModuleTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() throws Exception { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-invalid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-invalid.xml"); try { adapter.initialize(null, null, null, props); @@ -96,8 +95,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { adapter.initialize(null, null, null, props); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } props = new Properties(); @@ -108,8 +106,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { adapter.initialize(null, null, null, props); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } } @@ -117,8 +114,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); try { adapter.initialize(null, null, null, props); @@ -129,8 +125,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { props = new Properties(); props.put("key", ""); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); try { adapter.initialize(null, null, null, props); @@ -152,8 +147,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { adapter.initialize(null, null, null, props); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertTrue("Cannot locate INVALID_PATH".equals( - expected.getMessage())); + assertTrue("Cannot locate INVALID_PATH".equals(expected.getMessage())); } } @@ -162,8 +156,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); @@ -181,8 +174,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.initialize(null, null, null, props); assertTrue(true); } @@ -192,8 +184,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler("marissa", "kangaroo"); @@ -213,8 +204,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler("melissa", "koala"); @@ -233,8 +223,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler("marissa", "koala"); @@ -251,10 +240,8 @@ public class JbossAcegiLoginModuleTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } @@ -263,8 +250,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler("marissa", null); @@ -284,8 +270,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler(null, null); @@ -305,8 +290,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler(null, "kangaroo"); @@ -325,8 +309,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); Properties props = new Properties(); props.put("key", ADAPTER_KEY); - props.put("appContextLocation", - "org/acegisecurity/adapters/adaptertest-valid.xml"); + props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml"); Subject subject = new Subject(); CallbackHandler callback = new MockCallbackHandler("marissa", "koala"); @@ -342,7 +325,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { assertTrue(roles.isMember(new SimplePrincipal("ROLE_SUPERVISOR"))); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockCallbackHandler implements CallbackHandler { private String password; @@ -357,8 +340,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { super(); } - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { ((NameCallback) callbacks[i]).setName(username); @@ -366,8 +348,7 @@ public class JbossAcegiLoginModuleTests extends TestCase { if (this.password == null) { ((PasswordCallback) callbacks[i]).setPassword(null); } else { - ((PasswordCallback) callbacks[i]).setPassword(password - .toCharArray()); + ((PasswordCallback) callbacks[i]).setPassword(password.toCharArray()); } } else { throw new UnsupportedCallbackException(callbacks[i]); diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java index 469948b360..9ab16c8013 100644 --- a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class JbossIntegrationFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JbossIntegrationFilterTests() { super(); @@ -63,35 +63,55 @@ public class JbossIntegrationFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + filter.init(filterConfig); + filter.doFilter(request, response, filterChain); + filter.destroy(); + } public static void main(String[] args) { junit.textui.TestRunner.run(JbossIntegrationFilterTests.class); } - public void testCorrectOperation() throws Exception { - PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, - null); + private Subject makeIntoSubject(Principal principal) { + Set principals = new HashSet(); + principals.add(principal); - JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext( - makeIntoSubject(principal))); + return new Subject(false, principals, new HashSet(), new HashSet()); + } + + protected void setUp() throws Exception { + super.setUp(); + SecurityContextHolder.setContext(new SecurityContextImpl()); + } + + protected void tearDown() throws Exception { + super.tearDown(); + SecurityContextHolder.setContext(new SecurityContextImpl()); + } + + public void testCorrectOperation() throws Exception { + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); + + JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject(principal))); MockHttpServletRequest request = new MockHttpServletRequest(); MockFilterChain chain = new MockFilterChain(); filter.doFilter(request, null, chain); - assertEquals(principal, - SecurityContextHolder.getContext().getAuthentication()); + assertEquals(principal, SecurityContextHolder.getContext().getAuthentication()); SecurityContextHolder.setContext(new SecurityContextImpl()); } public void testReturnsNullIfContextReturnsSomethingOtherThanASubject() throws Exception { - JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext( - "THIS_IS_NOT_A_SUBJECT")); + JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext("THIS_IS_NOT_A_SUBJECT")); MockHttpServletRequest request = new MockHttpServletRequest(); MockFilterChain chain = new MockFilterChain(); @@ -102,8 +122,7 @@ public class JbossIntegrationFilterTests extends TestCase { public void testReturnsNullIfInitialContextHasNullPrincipal() throws Exception { - JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext( - makeIntoSubject(null))); + JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject(null))); MockHttpServletRequest request = new MockHttpServletRequest(); MockFilterChain chain = new MockFilterChain(); @@ -114,8 +133,7 @@ public class JbossIntegrationFilterTests extends TestCase { public void testReturnsNullIfInitialContextHasNullSubject() throws Exception { - JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext( - null)); + JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(null)); MockHttpServletRequest request = new MockHttpServletRequest(); MockFilterChain chain = new MockFilterChain(); @@ -137,8 +155,8 @@ public class JbossIntegrationFilterTests extends TestCase { public void testReturnsNullIfPrincipalNotAnAuthenticationImplementation() throws Exception { - JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext( - makeIntoSubject(new Principal() { + JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject( + new Principal() { public String getName() { return "MockPrincipal"; } @@ -157,32 +175,7 @@ public class JbossIntegrationFilterTests extends TestCase { assertTrue(filter.getLookupContext() instanceof Context); } - protected void setUp() throws Exception { - super.setUp(); - SecurityContextHolder.setContext(new SecurityContextImpl()); - } - - protected void tearDown() throws Exception { - super.tearDown(); - SecurityContextHolder.setContext(new SecurityContextImpl()); - } - - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - filter.init(filterConfig); - filter.doFilter(request, response, filterChain); - filter.destroy(); - } - - private Subject makeIntoSubject(Principal principal) { - Set principals = new HashSet(); - principals.add(principal); - - return new Subject(false, principals, new HashSet(), new HashSet()); - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { public void doFilter(ServletRequest arg0, ServletResponse arg1) diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockInitialContext.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockInitialContext.java index 05da9b8532..b60dfa5466 100644 --- a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockInitialContext.java +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockInitialContext.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,18 +25,18 @@ import javax.naming.NamingException; /** - * Mocks a javax.naming.Context and returns an Object - * when queried for address java:comp/env/security/subject. + * Mocks a javax.naming.Context and returns an Object when queried for address + * java:comp/env/security/subject. * * @author Ben Alex * @version $Id$ */ public class MockInitialContext implements Context { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object object; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockInitialContext(Object object) { this.object = object; @@ -46,23 +46,7 @@ public class MockInitialContext implements Context { super(); } - //~ Methods ================================================================ - - public Hashtable getEnvironment() throws NamingException { - throw new UnsupportedOperationException("mock method not implemented"); - } - - public String getNameInNamespace() throws NamingException { - throw new UnsupportedOperationException("mock method not implemented"); - } - - public NameParser getNameParser(String name) throws NamingException { - throw new UnsupportedOperationException("mock method not implemented"); - } - - public NameParser getNameParser(Name name) throws NamingException { - throw new UnsupportedOperationException("mock method not implemented"); - } + //~ Methods ======================================================================================================== public Object addToEnvironment(String propName, Object propVal) throws NamingException { @@ -106,6 +90,22 @@ public class MockInitialContext implements Context { throw new UnsupportedOperationException("mock method not implemented"); } + public Hashtable getEnvironment() throws NamingException { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public String getNameInNamespace() throws NamingException { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public NameParser getNameParser(String name) throws NamingException { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public NameParser getNameParser(Name name) throws NamingException { + throw new UnsupportedOperationException("mock method not implemented"); + } + public NamingEnumeration list(String name) throws NamingException { throw new UnsupportedOperationException("mock method not implemented"); } diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockJbossIntegrationFilter.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockJbossIntegrationFilter.java index 47565a6d22..731b219788 100644 --- a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockJbossIntegrationFilter.java +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/MockJbossIntegrationFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,18 @@ import javax.naming.NamingException; /** - * Provides mock of JbossIntegrationFilter, using a lookup - * Context provided in the constructor. + * Provides mock of JbossIntegrationFilter, using a lookup Context provided in the + * constructor. * * @author Ben Alex * @version $Id$ */ public class MockJbossIntegrationFilter extends JbossIntegrationFilter { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Context context; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockJbossIntegrationFilter(Context context) { this.context = context; @@ -41,7 +41,7 @@ public class MockJbossIntegrationFilter extends JbossIntegrationFilter { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected Context getLookupContext() throws NamingException { return this.context; diff --git a/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealm.java b/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealm.java index 3b872bdbc8..b0c3997983 100644 --- a/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealm.java +++ b/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealm.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.adapters.jetty; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationManager; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.apache.commons.logging.Log; @@ -33,32 +34,27 @@ import java.util.Map; /** - * Adapter to enable Jetty to authenticate via the Acegi Security System for - * Spring. - * - *

- * Returns a {@link JettyAcegiUserToken} to Jetty's authentication system, - * which is subsequently available via - * HttpServletRequest.getUserPrincipal(). - *

+ * Adapter to enable Jetty to authenticate via the Acegi Security System for Spring.

Returns a {@link + * JettyAcegiUserToken} to Jetty's authentication system, which is subsequently available via + * HttpServletRequest.getUserPrincipal().

* * @author Ben Alex * @version $Id$ */ public final class JettyAcegiUserRealm implements UserRealm { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(JettyAcegiUserRealm.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationManager authenticationManager; private String key; private String realm; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct a SpringUserRealm. * * @param realm the name of the authentication realm (within Jetty) @@ -68,8 +64,7 @@ public final class JettyAcegiUserRealm implements UserRealm { * * @throws IllegalArgumentException DOCUMENT ME! */ - public JettyAcegiUserRealm(String realm, String providerKey, - String appContextLocation) { + public JettyAcegiUserRealm(String realm, String providerKey, String appContextLocation) { this.realm = realm; this.key = providerKey; @@ -82,13 +77,11 @@ public final class JettyAcegiUserRealm implements UserRealm { } if ((appContextLocation == null) || "".equals(appContextLocation)) { - throw new IllegalArgumentException( - "appContextLocation must be specified"); + throw new IllegalArgumentException("appContextLocation must be specified"); } if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) { - throw new IllegalArgumentException("Cannot locate " - + appContextLocation); + throw new IllegalArgumentException("Cannot locate " + appContextLocation); } ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(appContextLocation); @@ -107,24 +100,9 @@ public final class JettyAcegiUserRealm implements UserRealm { throw new IllegalArgumentException("Cannot use default constructor"); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public AuthenticationManager getAuthenticationManager() { - return authenticationManager; - } - - /** - * Accesses the realm name. - * - * @return the name of the realm as defined when - * SpringUserRealm was created - */ - public String getName() { - return this.realm; - } - - public UserPrincipal authenticate(String username, Object password, - HttpRequest httpRequest) { + public UserPrincipal authenticate(String username, Object password, HttpRequest httpRequest) { if (username == null) { return null; } @@ -133,23 +111,20 @@ public final class JettyAcegiUserRealm implements UserRealm { password = ""; } - Authentication request = new UsernamePasswordAuthenticationToken(username - .toString(), password.toString()); + Authentication request = new UsernamePasswordAuthenticationToken(username.toString(), password.toString()); Authentication response = null; try { response = authenticationManager.authenticate(request); } catch (AuthenticationException failed) { if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " failed: " + failed.toString()); + logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); } return null; } - return new JettyAcegiUserToken(this.key, - response.getPrincipal().toString(), + return new JettyAcegiUserToken(this.key, response.getPrincipal().toString(), response.getCredentials().toString(), response.getAuthorities()); } @@ -157,6 +132,19 @@ public final class JettyAcegiUserRealm implements UserRealm { // No action required } + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + /** + * Accesses the realm name. + * + * @return the name of the realm as defined when SpringUserRealm was created + */ + public String getName() { + return this.realm; + } + public void logout(UserPrincipal arg0) { // Not supported } diff --git a/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserToken.java b/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserToken.java index d8e70c0ac0..43ea5b0d3c 100644 --- a/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserToken.java +++ b/adapters/jetty/src/main/java/org/acegisecurity/adapters/jetty/JettyAcegiUserToken.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.adapters.jetty; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.adapters.AbstractAdapterAuthenticationToken; import org.mortbay.http.UserPrincipal; @@ -27,17 +28,15 @@ import org.mortbay.http.UserPrincipal; * @author Ben Alex * @version $Id$ */ -public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken - implements UserPrincipal { - //~ Instance fields ======================================================== +public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken implements UserPrincipal { + //~ Instance fields ================================================================================================ private String password; private String username; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public JettyAcegiUserToken(String key, String username, String password, - GrantedAuthority[] authorities) { + public JettyAcegiUserToken(String key, String username, String password, GrantedAuthority[] authorities) { super(key, authorities); this.username = username; this.password = password; @@ -47,7 +46,7 @@ public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken throw new IllegalArgumentException("Cannot use default constructor"); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return this.password; diff --git a/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java index c6590b9711..4994a6c25f 100644 --- a/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java +++ b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,12 +27,12 @@ import org.mortbay.http.UserPrincipal; * @version $Id$ */ public class JettyAcegiUserRealmTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final String ADAPTER_KEY = "my_key"; private final String REALM_NAME = "Acegi Powered Realm"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JettyAcegiUserRealmTests() { super(); @@ -42,16 +42,23 @@ public class JettyAcegiUserRealmTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JettyAcegiUserRealmTests.class); } + private JettyAcegiUserRealm makeAdapter(String fileName) + throws Exception { + String useFile = "org/acegisecurity/adapters/" + fileName; + + return new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, useFile); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() throws Exception { try { @@ -69,16 +76,14 @@ public class JettyAcegiUserRealmTests extends TestCase { new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("appContextLocation must be specified", - expected.getMessage()); + assertEquals("appContextLocation must be specified", expected.getMessage()); } try { new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, ""); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("appContextLocation must be specified", - expected.getMessage()); + assertEquals("appContextLocation must be specified", expected.getMessage()); } } @@ -118,8 +123,7 @@ public class JettyAcegiUserRealmTests extends TestCase { public void testAdapterAbortsWithIncorrectApplicationContextLocation() throws Exception { try { - new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, - "SOME_INVALID_LOCATION"); + new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, "SOME_INVALID_LOCATION"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(expected.getMessage().startsWith("Cannot locate")); @@ -160,10 +164,8 @@ public class JettyAcegiUserRealmTests extends TestCase { JettyAcegiUserToken castResult = (JettyAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } @@ -217,29 +219,19 @@ public class JettyAcegiUserRealmTests extends TestCase { assertEquals(user, adapter.pushRole(user, "SOME_ROLE")); } - private JettyAcegiUserRealm makeAdapter(String fileName) - throws Exception { - String useFile = "org/acegisecurity/adapters/" + fileName; - - return new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, useFile); - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockUserPrincipal implements UserPrincipal { - public boolean isAuthenticated() { - throw new UnsupportedOperationException( - "mock method not implemented"); + public String getName() { + throw new UnsupportedOperationException("mock method not implemented"); } - public String getName() { - throw new UnsupportedOperationException( - "mock method not implemented"); + public boolean isAuthenticated() { + throw new UnsupportedOperationException("mock method not implemented"); } public boolean isUserInRole(String arg0) { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } } } diff --git a/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserTokenTests.java b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserTokenTests.java index bfa611c0f3..bf47c4b1c0 100644 --- a/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserTokenTests.java +++ b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class JettyAcegiUserTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JettyAcegiUserTokenTests() { super(); @@ -38,21 +38,19 @@ public class JettyAcegiUserTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JettyAcegiUserTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() throws Exception { - JettyAcegiUserToken token = new JettyAcegiUserToken("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + JettyAcegiUserToken token = new JettyAcegiUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("my_password".hashCode(), token.getKeyHash()); diff --git a/adapters/resin/src/main/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticator.java b/adapters/resin/src/main/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticator.java index db9ece67a7..ecb901e95f 100644 --- a/adapters/resin/src/main/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticator.java +++ b/adapters/resin/src/main/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,64 +41,34 @@ import javax.servlet.http.HttpServletResponse; /** - * Adapter to enable Resin to authenticate via the Acegi Security System for - * Spring. - * - *

- * Returns a {@link PrincipalAcegiUserToken} to Resin's authentication system, - * which is subsequently available via - * HttpServletRequest.getUserPrincipal(). - *

+ * Adapter to enable Resin to authenticate via the Acegi Security System for Spring.

Returns a {@link + * PrincipalAcegiUserToken} to Resin's authentication system, which is subsequently available via + * HttpServletRequest.getUserPrincipal().

* * @author Ben Alex * @version $Id$ */ public class ResinAcegiAuthenticator extends AbstractAuthenticator { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(ResinAcegiAuthenticator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationManager authenticationManager; private String appContextLocation; private String key; - //~ Methods ================================================================ - - public void setAppContextLocation(String appContextLocation) { - this.appContextLocation = appContextLocation; - } + //~ Methods ======================================================================================================== public String getAppContextLocation() { return appContextLocation; } - public void setKey(String key) { - this.key = key; - } - public String getKey() { return key; } - public boolean isUserInRole(HttpServletRequest request, - HttpServletResponse response, ServletContext application, - Principal principal, String role) { - if (!(principal instanceof PrincipalAcegiUserToken)) { - if (logger.isWarnEnabled()) { - logger.warn( - "Expected passed principal to be of type PrincipalAcegiUserToken"); - } - - return false; - } - - PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal; - - return test.isUserInRole(role); - } - public void init() throws ServletException { super.init(); @@ -118,8 +88,7 @@ public class ResinAcegiAuthenticator extends AbstractAuthenticator { Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true); if (beans.size() == 0) { - throw new ServletException( - "Bean context must contain at least one bean of type AuthenticationManager"); + throw new ServletException("Bean context must contain at least one bean of type AuthenticationManager"); } String beanName = (String) beans.keySet().iterator().next(); @@ -127,6 +96,21 @@ public class ResinAcegiAuthenticator extends AbstractAuthenticator { logger.info("ResinAcegiAuthenticator Started"); } + public boolean isUserInRole(HttpServletRequest request, HttpServletResponse response, ServletContext application, + Principal principal, String role) { + if (!(principal instanceof PrincipalAcegiUserToken)) { + if (logger.isWarnEnabled()) { + logger.warn("Expected passed principal to be of type PrincipalAcegiUserToken"); + } + + return false; + } + + PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal; + + return test.isUserInRole(role); + } + protected Principal loginImpl(String username, String credentials) { if (username == null) { return null; @@ -136,30 +120,33 @@ public class ResinAcegiAuthenticator extends AbstractAuthenticator { credentials = ""; } - Authentication request = new UsernamePasswordAuthenticationToken(username, - credentials); + Authentication request = new UsernamePasswordAuthenticationToken(username, credentials); Authentication response = null; try { response = authenticationManager.authenticate(request); } catch (AuthenticationException failed) { if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " failed: " + failed.toString()); + logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); } return null; } - return new PrincipalAcegiUserToken(this.key, - response.getPrincipal().toString(), - response.getCredentials().toString(), response.getAuthorities(), - response.getPrincipal()); + return new PrincipalAcegiUserToken(this.key, response.getPrincipal().toString(), + response.getCredentials().toString(), response.getAuthorities(), response.getPrincipal()); } - protected Principal loginImpl(HttpServletRequest request, - HttpServletResponse response, ServletContext application, + protected Principal loginImpl(HttpServletRequest request, HttpServletResponse response, ServletContext application, String userName, String password) throws ServletException { return loginImpl(userName, password); } + + public void setAppContextLocation(String appContextLocation) { + this.appContextLocation = appContextLocation; + } + + public void setKey(String key) { + this.key = key; + } } diff --git a/adapters/resin/src/test/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticatorTests.java b/adapters/resin/src/test/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticatorTests.java index 3e68deb1e4..8f2b4d792c 100644 --- a/adapters/resin/src/test/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticatorTests.java +++ b/adapters/resin/src/test/java/org/acegisecurity/adapters/resin/ResinAcegiAuthenticatorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,11 +34,11 @@ import javax.servlet.ServletException; * @version $Id$ */ public class ResinAcegiAuthenticatorTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final String ADAPTER_KEY = "my_key"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ResinAcegiAuthenticatorTests() { super(); @@ -48,21 +48,20 @@ public class ResinAcegiAuthenticatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ResinAcegiAuthenticatorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-invalid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-invalid.xml"); adapter.setKey(ADAPTER_KEY); try { @@ -83,8 +82,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { adapter.init(); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } adapter.setAppContextLocation(""); @@ -93,15 +91,13 @@ public class ResinAcegiAuthenticatorTests extends TestCase { adapter.init(); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("appContextLocation must be defined", - expected.getMessage()); + assertEquals("appContextLocation must be defined", expected.getMessage()); } } public void testAdapterAbortsIfNoKeySpecified() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); try { adapter.init(); @@ -136,8 +132,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testAdapterStartsUpSuccess() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertTrue(true); @@ -146,8 +141,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testAuthenticationFailsForIncorrectPassword() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertEquals(null, adapter.loginImpl("marissa", "kangaroo")); @@ -156,8 +150,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testAuthenticationFailsForIncorrectUserName() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertEquals(null, adapter.loginImpl("melissa", "koala")); @@ -165,8 +158,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testAuthenticationSuccess() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); @@ -179,23 +171,19 @@ public class ResinAcegiAuthenticatorTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } public void testAuthenticationSuccessUsingAlternateMethod() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); - Principal result = adapter.loginImpl(null, null, null, "marissa", - "koala"); + Principal result = adapter.loginImpl(null, null, null, "marissa", "koala"); if (!(result instanceof PrincipalAcegiUserToken)) { fail("Should have returned PrincipalAcegiUserToken"); @@ -204,18 +192,15 @@ public class ResinAcegiAuthenticatorTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); - assertEquals("ROLE_TELLER", - castResult.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_SUPERVISOR", - castResult.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority()); assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); } public void testAuthenticationWithNullPasswordHandledGracefully() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertEquals(null, adapter.loginImpl("marissa", null)); @@ -224,8 +209,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testAuthenticationWithNullUserNameHandledGracefully() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertEquals(null, adapter.loginImpl(null, "koala")); @@ -233,18 +217,15 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testGetters() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); assertEquals(ADAPTER_KEY, adapter.getKey()); - assertEquals("org/acegisecurity/adapters/adaptertest-valid.xml", - adapter.getAppContextLocation()); + assertEquals("org/acegisecurity/adapters/adaptertest-valid.xml", adapter.getAppContextLocation()); } public void testHasRoleWithANullPrincipalFails() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertTrue(!adapter.isUserInRole(null, null, null, null, "ROLE_ONE")); @@ -253,8 +234,7 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testHasRoleWithAPrincipalTheAdapterDidNotCreateFails() throws Exception { ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertTrue(!adapter.isUserInRole(null, null, null, @@ -267,18 +247,15 @@ public class ResinAcegiAuthenticatorTests extends TestCase { public void testHasRoleWithPrincipalAcegiUserToken() throws Exception { - PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, null); + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + null); ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator(); - adapter.setAppContextLocation( - "org/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml"); adapter.setKey(ADAPTER_KEY); adapter.init(); assertTrue(adapter.isUserInRole(null, null, null, token, "ROLE_ONE")); assertTrue(adapter.isUserInRole(null, null, null, token, "ROLE_ONE")); - assertTrue(!adapter.isUserInRole(null, null, null, token, - "ROLE_WE_DO_NOT_HAVE")); + assertTrue(!adapter.isUserInRole(null, null, null, token, "ROLE_WE_DO_NOT_HAVE")); } } diff --git a/core-tiger/src/main/java/org/acegisecurity/annotation/Secured.java b/core-tiger/src/main/java/org/acegisecurity/annotation/Secured.java index b7212bd65e..abfd05e72a 100644 --- a/core-tiger/src/main/java/org/acegisecurity/annotation/Secured.java +++ b/core-tiger/src/main/java/org/acegisecurity/annotation/Secured.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,9 +47,7 @@ import java.lang.annotation.Target; @Inherited @Documented public @interface Secured { - //~ Methods ================================================================ - - /** +/** * Returns the list of security configuration attributes. * (i.e. ROLE_USER, ROLE_ADMIN etc.) * @return String[] The secure method attributes diff --git a/core-tiger/src/main/java/org/acegisecurity/annotation/SecurityAnnotationAttributes.java b/core-tiger/src/main/java/org/acegisecurity/annotation/SecurityAnnotationAttributes.java index b619a13936..5afea13e08 100644 --- a/core-tiger/src/main/java/org/acegisecurity/annotation/SecurityAnnotationAttributes.java +++ b/core-tiger/src/main/java/org/acegisecurity/annotation/SecurityAnnotationAttributes.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,54 +12,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.acegisecurity.annotation; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +package org.acegisecurity.annotation; import org.acegisecurity.SecurityConfig; import org.springframework.metadata.Attributes; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + + /** - * Java 5 Annotation Attributes metadata implementation used for - * secure method interception. - * - *

This Attributes implementation will return security - * configuration for classes described using the Secured Java 5 - * annotation. - * - *

The SecurityAnnotationAttributes implementation can be used - * to configure a MethodDefinitionAttributes and - * MethodSecurityInterceptor bean definition (see below). - * - *

For example: - *

- * <bean id="attributes" 
- *     class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/>
- * 
- * <bean id="objectDefinitionSource" 
- *     class="org.acegisecurity.intercept.method.MethodDefinitionAttributes">
- *     <property name="attributes">
- *         <ref local="attributes"/>
- *     </property>
- * </bean>
- * 
- * <bean id="securityInterceptor" 
- *     class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
- *      . . .
- *      <property name="objectDefinitionSource">
- *          <ref local="objectDefinitionSource"/>
- *      </property>
- * </bean>
- * 
- * - *

These security annotations are similiar to the Commons Attributes - * approach, however they are using Java 5 language-level metadata support. + * Java 5 Annotation Attributes metadata implementation used for secure method interception.

This + * Attributes implementation will return security configuration for classes described using the + * Secured Java 5 annotation.

+ *

The SecurityAnnotationAttributes implementation can be used to configure a + * MethodDefinitionAttributes and MethodSecurityInterceptor bean definition (see below).

+ *

For example:

<bean id="attributes" 
+ *     class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/><bean id="objectDefinitionSource" 
+ *     class="org.acegisecurity.intercept.method.MethodDefinitionAttributes">    <property name="attributes">
+ *         <ref local="attributes"/>    </property></bean><bean id="securityInterceptor" 
+ *     class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">     . . .
+ *      <property name="objectDefinitionSource">         <ref local="objectDefinitionSource"/>     </property>
+ * </bean>

+ *

These security annotations are similiar to the Commons Attributes approach, however they are using Java 5 + * language-level metadata support.

* * @author Mark St.Godard * @version $Id$ @@ -67,66 +50,77 @@ import org.springframework.metadata.Attributes; * @see org.acegisecurity.annotation.Secured */ public class SecurityAnnotationAttributes implements Attributes { + //~ Methods ======================================================================================================== - /** - * Get the Secured attributes for a given target class. - * @param method The target method - * @return Collection of SecurityConfig - * @see Attributes#getAttributes - */ - public Collection getAttributes(Class target) { + /** + * Get the Secured attributes for a given target class. + * + * @param target The target method + * + * @return Collection of SecurityConfig + * + * @see Attributes#getAttributes + */ + public Collection getAttributes(Class target) { + Set attributes = new HashSet(); - Set attributes = new HashSet(); + for (Annotation annotation : target.getAnnotations()) { + // check for Secured annotations + if (annotation instanceof Secured) { + Secured attr = (Secured) annotation; - for (Annotation annotation : target.getAnnotations()) { - // check for Secured annotations - if (annotation instanceof Secured) { - Secured attr = (Secured) annotation; - for (String auth : attr.value()) { - attributes.add(new SecurityConfig(auth)); - } - break; - } - } - return attributes; - } + for (String auth : attr.value()) { + attributes.add(new SecurityConfig(auth)); + } - public Collection getAttributes(Class clazz, Class filter) { - throw new UnsupportedOperationException("Unsupported operation"); - } + break; + } + } - /** - * Get the Secured attributes for a given target method. - * @param method The target method - * @return Collection of SecurityConfig - * @see Attributes#getAttributes - */ - public Collection getAttributes(Method method) { - Set attributes = new HashSet(); + return attributes; + } - for (Annotation annotation : method.getAnnotations()) { - // check for Secured annotations - if (annotation instanceof Secured) { - Secured attr = (Secured) annotation; - for (String auth : attr.value()) { - attributes.add(new SecurityConfig(auth)); - } - break; - } - } - return attributes; - } + public Collection getAttributes(Class clazz, Class filter) { + throw new UnsupportedOperationException("Unsupported operation"); + } - public Collection getAttributes(Method method, Class clazz) { - throw new UnsupportedOperationException("Unsupported operation"); - } + /** + * Get the Secured attributes for a given target method. + * + * @param method The target method + * + * @return Collection of SecurityConfig + * + * @see Attributes#getAttributes + */ + public Collection getAttributes(Method method) { + Set attributes = new HashSet(); - public Collection getAttributes(Field field) { - throw new UnsupportedOperationException("Unsupported operation"); - } + for (Annotation annotation : method.getAnnotations()) { + // check for Secured annotations + if (annotation instanceof Secured) { + Secured attr = (Secured) annotation; - public Collection getAttributes(Field field, Class clazz) { - throw new UnsupportedOperationException("Unsupported operation"); - } + for (String auth : attr.value()) { + attributes.add(new SecurityConfig(auth)); + } + break; + } + } + + return attributes; + } + + public Collection getAttributes(Method method, Class clazz) { + throw new UnsupportedOperationException("Unsupported operation"); + } + + public Collection getAttributes(Field field) { + throw new UnsupportedOperationException("Unsupported operation"); + } + + public Collection getAttributes(Field field, Class clazz) { + throw new UnsupportedOperationException("Unsupported operation"); + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/Entity.java b/core-tiger/src/test/java/org/acegisecurity/Entity.java index 89b8b039a9..d3ae9c482d 100644 --- a/core-tiger/src/test/java/org/acegisecurity/Entity.java +++ b/core-tiger/src/test/java/org/acegisecurity/Entity.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,18 +25,18 @@ import org.springframework.util.Assert; * @version $Id$ */ public class Entity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ String info; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public Entity(String info) { Assert.hasText(info, "Some information must be given!"); this.info = info; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public String getInfo() { return info; diff --git a/core-tiger/src/test/java/org/acegisecurity/Organisation.java b/core-tiger/src/test/java/org/acegisecurity/Organisation.java index 03dbf7bd42..0e9d363d86 100644 --- a/core-tiger/src/test/java/org/acegisecurity/Organisation.java +++ b/core-tiger/src/test/java/org/acegisecurity/Organisation.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,23 +22,23 @@ package org.acegisecurity; * @version $Id$ */ public class Organisation extends Entity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean active = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public Organisation(String name) { super(name); } - //~ Methods ================================================================ - - public boolean isActive() { - return this.active; - } + //~ Methods ======================================================================================================== void deactive() { this.active = true; } + + public boolean isActive() { + return this.active; + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/OrganisationService.java b/core-tiger/src/test/java/org/acegisecurity/OrganisationService.java index 0c40630eb7..a2743069bf 100644 --- a/core-tiger/src/test/java/org/acegisecurity/OrganisationService.java +++ b/core-tiger/src/test/java/org/acegisecurity/OrganisationService.java @@ -1,5 +1,28 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public interface OrganisationService extends Service { - public void deactive(Organisation org); + //~ Methods ======================================================================================================== + + public void deactive(Organisation org); } diff --git a/core-tiger/src/test/java/org/acegisecurity/OrganisationServiceImpl.java b/core-tiger/src/test/java/org/acegisecurity/OrganisationServiceImpl.java index d4b6f84889..f9c2ceceb6 100644 --- a/core-tiger/src/test/java/org/acegisecurity/OrganisationServiceImpl.java +++ b/core-tiger/src/test/java/org/acegisecurity/OrganisationServiceImpl.java @@ -1,9 +1,30 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class OrganisationServiceImpl extends ServiceImpl implements OrganisationService { + //~ Methods ======================================================================================================== - public void deactive(Organisation org) { - org.deactive(); - } - + public void deactive(Organisation org) { + org.deactive(); + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/Person.java b/core-tiger/src/test/java/org/acegisecurity/Person.java index 5fad5927d7..0381d07667 100644 --- a/core-tiger/src/test/java/org/acegisecurity/Person.java +++ b/core-tiger/src/test/java/org/acegisecurity/Person.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,23 +22,23 @@ package org.acegisecurity; * @version $Id$ */ public class Person extends Entity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean active = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public Person(String name) { super(name); } - //~ Methods ================================================================ - - public boolean isActive() { - return this.active; - } + //~ Methods ======================================================================================================== void deactive() { this.active = true; } + + public boolean isActive() { + return this.active; + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/PersonService.java b/core-tiger/src/test/java/org/acegisecurity/PersonService.java index c184602bd4..eeed02333c 100644 --- a/core-tiger/src/test/java/org/acegisecurity/PersonService.java +++ b/core-tiger/src/test/java/org/acegisecurity/PersonService.java @@ -1,5 +1,28 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public interface PersonService extends Service { - public void deactive(Person person); + //~ Methods ======================================================================================================== + + public void deactive(Person person); } diff --git a/core-tiger/src/test/java/org/acegisecurity/PersonServiceImpl.java b/core-tiger/src/test/java/org/acegisecurity/PersonServiceImpl.java index bf4f11eb9b..3d9a7790ab 100644 --- a/core-tiger/src/test/java/org/acegisecurity/PersonServiceImpl.java +++ b/core-tiger/src/test/java/org/acegisecurity/PersonServiceImpl.java @@ -1,9 +1,30 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class PersonServiceImpl extends ServiceImpl implements PersonService { + //~ Methods ======================================================================================================== - public void deactive(Person person) { - person.deactive(); - } - + public void deactive(Person person) { + person.deactive(); + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/Service.java b/core-tiger/src/test/java/org/acegisecurity/Service.java index f98c604058..a294f97f29 100644 --- a/core-tiger/src/test/java/org/acegisecurity/Service.java +++ b/core-tiger/src/test/java/org/acegisecurity/Service.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import java.util.Collection; * @version $Id$ */ public interface Service { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public int countElements(Collection ids); diff --git a/core-tiger/src/test/java/org/acegisecurity/ServiceImpl.java b/core-tiger/src/test/java/org/acegisecurity/ServiceImpl.java index 03b0be57a9..1be2d98283 100644 --- a/core-tiger/src/test/java/org/acegisecurity/ServiceImpl.java +++ b/core-tiger/src/test/java/org/acegisecurity/ServiceImpl.java @@ -1,23 +1,47 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity; import java.util.Collection; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + * + * @param DOCUMENT ME! + */ public class ServiceImpl implements Service { + //~ Methods ======================================================================================================== - public int countElements(Collection ids) { - return 0; - } + public int countElements(Collection ids) { + return 0; + } - public void makeLowerCase(E input) { - input.makeLowercase(); - } + public void makeLowerCase(E input) { + input.makeLowercase(); + } - public void makeUpperCase(E input) { - input.makeUppercase(); - } - - public void publicMakeLowerCase(E input) { - input.makeUppercase(); - } + public void makeUpperCase(E input) { + input.makeUppercase(); + } + public void publicMakeLowerCase(E input) { + input.makeUppercase(); + } } diff --git a/core-tiger/src/test/java/org/acegisecurity/annotation/BusinessService.java b/core-tiger/src/test/java/org/acegisecurity/annotation/BusinessService.java index 61de4cc4e6..09df1da354 100644 --- a/core-tiger/src/test/java/org/acegisecurity/annotation/BusinessService.java +++ b/core-tiger/src/test/java/org/acegisecurity/annotation/BusinessService.java @@ -1,18 +1,39 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.annotation; -@Secured ({"ROLE_USER"}) +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +@Secured({"ROLE_USER"}) public interface BusinessService { - - @Secured ({"ROLE_USER"}) - public void someUserMethod1(); + //~ Methods ======================================================================================================== - @Secured ({"ROLE_USER"}) - public void someUserMethod2(); - - @Secured ({"ROLE_USER","ROLE_ADMIN"}) - public void someUserAndAdminMethod(); - - @Secured ({"ROLE_ADMIN"}) - public void someAdminMethod(); - + @Secured({"ROLE_ADMIN"}) + public void someAdminMethod(); + + @Secured({"ROLE_USER", "ROLE_ADMIN"}) + public void someUserAndAdminMethod(); + + @Secured({"ROLE_USER"}) + public void someUserMethod1(); + + @Secured({"ROLE_USER"}) + public void someUserMethod2(); } diff --git a/core-tiger/src/test/java/org/acegisecurity/annotation/SecurityAnnotationAttributesTests.java b/core-tiger/src/test/java/org/acegisecurity/annotation/SecurityAnnotationAttributesTests.java index fab499c60f..0a87ae1b27 100644 --- a/core-tiger/src/test/java/org/acegisecurity/annotation/SecurityAnnotationAttributesTests.java +++ b/core-tiger/src/test/java/org/acegisecurity/annotation/SecurityAnnotationAttributesTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,17 @@ package org.acegisecurity.annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Collection; - import junit.framework.TestCase; + import org.acegisecurity.SecurityConfig; import org.springframework.metadata.Attributes; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import java.util.Collection; + /** * Tests for {@link org.acegisecurity.annotation.SecurityAnnotationAttributes} @@ -32,17 +34,22 @@ import org.springframework.metadata.Attributes; * @version $Revision$ */ public class SecurityAnnotationAttributesTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Attributes attributes; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + // create the Annotations impl + this.attributes = new SecurityAnnotationAttributes(); + } public void testGetAttributesClass() { Collection attrs = this.attributes.getAttributes(BusinessService.class); assertNotNull(attrs); - + // expect 1 annotation assertTrue(attrs.size() == 1); @@ -53,90 +60,76 @@ public class SecurityAnnotationAttributesTests extends TestCase { } public void testGetAttributesClassClass() { - try{ - this.attributes.getAttributes(BusinessService.class, null); - fail("Unsupported method should have thrown an exception!"); - - }catch(UnsupportedOperationException expected){ - } + try { + this.attributes.getAttributes(BusinessService.class, null); + fail("Unsupported method should have thrown an exception!"); + } catch (UnsupportedOperationException expected) {} } public void testGetAttributesField() { - try{ - Field field = null; - this.attributes.getAttributes(field); - fail("Unsupported method should have thrown an exception!"); - - }catch(UnsupportedOperationException expected){ - - } - + try { + Field field = null; + this.attributes.getAttributes(field); + fail("Unsupported method should have thrown an exception!"); + } catch (UnsupportedOperationException expected) {} } public void testGetAttributesFieldClass() { - try{ - Field field = null; - this.attributes.getAttributes(field, null); - fail("Unsupported method should have thrown an exception!"); - - }catch(UnsupportedOperationException expected){ - - } - + try { + Field field = null; + this.attributes.getAttributes(field, null); + fail("Unsupported method should have thrown an exception!"); + } catch (UnsupportedOperationException expected) {} } public void testGetAttributesMethod() { - - Method method = null; - try{ - method = BusinessService.class.getMethod("someUserAndAdminMethod",new Class[] {}); - }catch(NoSuchMethodException unexpected){ - fail("Should be a method called 'someUserAndAdminMethod' on class!"); - } + Method method = null; + + try { + method = BusinessService.class.getMethod("someUserAndAdminMethod", new Class[] {}); + } catch (NoSuchMethodException unexpected) { + fail("Should be a method called 'someUserAndAdminMethod' on class!"); + } + Collection attrs = this.attributes.getAttributes(method); assertNotNull(attrs); - + // expect 2 attributes assertTrue(attrs.size() == 2); boolean user = false; boolean admin = false; + // should have 2 SecurityConfigs - for(Object obj: attrs){ - assertTrue(obj instanceof SecurityConfig); - SecurityConfig sc = (SecurityConfig)obj; - if(sc.getAttribute().equals("ROLE_USER")){ - user = true; - }else if(sc.getAttribute().equals("ROLE_ADMIN")){ - admin = true; - } + for (Object obj : attrs) { + assertTrue(obj instanceof SecurityConfig); + + SecurityConfig sc = (SecurityConfig) obj; + + if (sc.getAttribute().equals("ROLE_USER")) { + user = true; + } else if (sc.getAttribute().equals("ROLE_ADMIN")) { + admin = true; + } } + // expect to have ROLE_USER and ROLE_ADMIN assertTrue(user && admin); } public void testGetAttributesMethodClass() { - - Method method = null; - try{ - method = BusinessService.class.getMethod("someUserAndAdminMethod",new Class[] {}); - }catch(NoSuchMethodException unexpected){ - fail("Should be a method called 'someUserAndAdminMethod' on class!"); - } - - try{ - this.attributes.getAttributes(method,null); - fail("Unsupported method should have thrown an exception!"); - - }catch(UnsupportedOperationException expected){ - - } - - } + Method method = null; - protected void setUp() throws Exception { - // create the Annotations impl - this.attributes = new SecurityAnnotationAttributes(); + try { + method = BusinessService.class.getMethod("someUserAndAdminMethod", new Class[] {}); + } catch (NoSuchMethodException unexpected) { + fail("Should be a method called 'someUserAndAdminMethod' on class!"); + } + + try { + this.attributes.getAttributes(method, null); + fail("Unsupported method should have thrown an exception!"); + } catch (UnsupportedOperationException expected) {} } } diff --git a/core-tiger/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTigerTests.java b/core-tiger/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTigerTests.java index 7229b7c022..0d4b4de96f 100644 --- a/core-tiger/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTigerTests.java +++ b/core-tiger/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTigerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.intercept.method; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Method; - import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; @@ -28,18 +25,21 @@ import org.acegisecurity.PersonServiceImpl; import org.acegisecurity.SecurityConfig; import org.acegisecurity.Service; import org.acegisecurity.ServiceImpl; + import org.aopalliance.intercept.MethodInvocation; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Method; + /** - * Extra tests to demonstrate generics behaviour with - * MethodDefinitionMap. + * Extra tests to demonstrate generics behaviour with MethodDefinitionMap. * * @author Ben Alex * @version $Id$ */ public class MethodDefinitionSourceEditorTigerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodDefinitionSourceEditorTigerTests() { super(); @@ -49,16 +49,16 @@ public class MethodDefinitionSourceEditorTigerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(MethodDefinitionSourceEditorTigerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConcreteClassInvocationsAlsoReturnDefinitionsAgainstInterface() throws Exception { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); @@ -68,21 +68,17 @@ public class MethodDefinitionSourceEditorTigerTests extends TestCase { MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); assertEquals(3, map.getMethodMapSize()); - ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( - Service.class, "makeLowerCase", new Class[] {Entity.class})); + ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(Service.class, + "makeLowerCase", new Class[] {Entity.class})); ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition(); - expectedMakeLower.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeLower, returnedMakeLower); - ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation( - ServiceImpl.class, "makeUpperCase", - new Class[] {Entity.class})); + ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(ServiceImpl.class, + "makeUpperCase", new Class[] {Entity.class})); ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_IMPLEMENTATION")); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_IMPLEMENTATION")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeUpper, returnedMakeUpper); } @@ -95,49 +91,41 @@ public class MethodDefinitionSourceEditorTigerTests extends TestCase { MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); assertEquals(3, map.getMethodMapSize()); - ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( - PersonService.class, "makeLowerCase", - new Class[] {Entity.class})); + ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(PersonService.class, + "makeLowerCase", new Class[] {Entity.class})); ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition(); - expectedMakeLower.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeLower, returnedMakeLower); ConfigAttributeDefinition returnedMakeLower2 = map.getAttributes(new MockMethodInvocation( - OrganisationService.class, "makeLowerCase", - new Class[] {Entity.class})); + OrganisationService.class, "makeLowerCase", new Class[] {Entity.class})); ConfigAttributeDefinition expectedMakeLower2 = new ConfigAttributeDefinition(); - expectedMakeLower2.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeLower2.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeLower2, returnedMakeLower2); ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation( - PersonServiceImpl.class, "makeUpperCase", - new Class[] {Entity.class})); + PersonServiceImpl.class, "makeUpperCase", new Class[] {Entity.class})); ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_IMPLEMENTATION")); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_IMPLEMENTATION")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeUpper, returnedMakeUpper); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockMethodInvocation implements MethodInvocation { Method method; - public MockMethodInvocation(Class clazz, String methodName, - Class[] parameterTypes) throws NoSuchMethodException { - System.out.println(clazz + " " + methodName + " " - + parameterTypes[0]); - method = clazz.getMethod(methodName, parameterTypes); - } - private MockMethodInvocation() { super(); } + public MockMethodInvocation(Class clazz, String methodName, Class[] parameterTypes) + throws NoSuchMethodException { + System.out.println(clazz + " " + methodName + " " + parameterTypes[0]); + method = clazz.getMethod(methodName, parameterTypes); + } + public Object[] getArguments() { return null; } diff --git a/core/src/main/java/org/acegisecurity/AbstractAuthenticationManager.java b/core/src/main/java/org/acegisecurity/AbstractAuthenticationManager.java index 861b73443d..6f7b95faa9 100644 --- a/core/src/main/java/org/acegisecurity/AbstractAuthenticationManager.java +++ b/core/src/main/java/org/acegisecurity/AbstractAuthenticationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,27 +17,21 @@ package org.acegisecurity; import org.acegisecurity.providers.AbstractAuthenticationToken; + /** * An abstract implementation of the {@link AuthenticationManager}. * * @author Wesley Hall * @version $Id$ */ -public abstract class AbstractAuthenticationManager - implements AuthenticationManager { - //~ Methods ================================================================ +public abstract class AbstractAuthenticationManager implements AuthenticationManager { + //~ Methods ======================================================================================================== /** - *

- * An implementation of the authenticate method that calls the - * abstract method doAuthenticatation to do its work. - *

- * - *

- * If doAuthenticate throws an AuthenticationException then - * the exception is populated with the failed Authentication - * object that failed. - *

+ *

An implementation of the authenticate method that calls the abstract method + * doAuthenticatation to do its work.

+ *

If doAuthenticate throws an AuthenticationException then the exception is populated + * with the failed Authentication object that failed.

* * @param authRequest the authentication request object * @@ -59,32 +53,24 @@ public abstract class AbstractAuthenticationManager } /** - * Copies the authentication details from a source Authentication object - * to a destination one, provided the latter does not already have one - * set. + * Copies the authentication details from a source Authentication object to a destination one, provided the + * latter does not already have one set. * * @param source source authentication * @param dest the destination authentication object */ private void copyDetails(Authentication source, Authentication dest) { - if((dest instanceof AbstractAuthenticationToken) - && dest.getDetails() == null) { - AbstractAuthenticationToken token = (AbstractAuthenticationToken)dest; + if ((dest instanceof AbstractAuthenticationToken) && (dest.getDetails() == null)) { + AbstractAuthenticationToken token = (AbstractAuthenticationToken) dest; - token.setDetails(source.getDetails()); + token.setDetails(source.getDetails()); } } /** - *

- * Concrete implementations of this class override this method to provide - * the authentication service. - *

- * - *

- * The contract for this method is documented in the {@link - * AuthenticationManager#authenticate(org.acegisecurity.Authentication)}. - *

+ *

Concrete implementations of this class override this method to provide the authentication service.

+ *

The contract for this method is documented in the {@link + * AuthenticationManager#authenticate(org.acegisecurity.Authentication)}.

* * @param authentication the authentication request object * @@ -92,6 +78,6 @@ public abstract class AbstractAuthenticationManager * * @throws AuthenticationException if authentication fails */ - protected abstract Authentication doAuthentication( - Authentication authentication) throws AuthenticationException; + protected abstract Authentication doAuthentication(Authentication authentication) + throws AuthenticationException; } diff --git a/core/src/main/java/org/acegisecurity/AccessDecisionManager.java b/core/src/main/java/org/acegisecurity/AccessDecisionManager.java index 280014cba9..7c7734f019 100644 --- a/core/src/main/java/org/acegisecurity/AccessDecisionManager.java +++ b/core/src/main/java/org/acegisecurity/AccessDecisionManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,54 +22,44 @@ package org.acegisecurity; * @version $Id$ */ public interface AccessDecisionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Resolves an access control decision for the passed parameters. * * @param authentication the caller invoking the method * @param object the secured object being called - * @param config the configuration attributes associated with the secured - * object being invoked + * @param config the configuration attributes associated with the secured object being invoked * - * @throws AccessDeniedException if access is denied as the authentication - * does not hold a required authority or ACL privilege - * @throws InsufficientAuthenticationException if access is denied as the - * authentication does not provide a sufficient level of trust + * @throws AccessDeniedException if access is denied as the authentication does not hold a required authority or + * ACL privilege + * @throws InsufficientAuthenticationException if access is denied as the authentication does not provide a + * sufficient level of trust */ - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException, InsufficientAuthenticationException; /** - * Indicates whether this AccessDecisionManager is able to - * process authorization requests presented with the passed - * ConfigAttribute. - * - *

- * This allows the AbstractSecurityInterceptor to check every - * configuration attribute can be consumed by the configured - * AccessDecisionManager and/or RunAsManager - * and/or AfterInvocationManager. - *

+ * Indicates whether this AccessDecisionManager is able to process authorization requests + * presented with the passed ConfigAttribute.

This allows the + * AbstractSecurityInterceptor to check every configuration attribute can be consumed by the + * configured AccessDecisionManager and/or RunAsManager and/or + * AfterInvocationManager.

* - * @param attribute a configuration attribute that has been configured - * against the AbstractSecurityInterceptor + * @param attribute a configuration attribute that has been configured against the + * AbstractSecurityInterceptor * - * @return true if this AccessDecisionManager can support the - * passed configuration attribute + * @return true if this AccessDecisionManager can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); /** - * Indicates whether the AccessDecisionManager implementation - * is able to provide access control decisions for the indicated secured - * object type. + * Indicates whether the AccessDecisionManager implementation is able to provide access + * control decisions for the indicated secured object type. * * @param clazz the class that is being queried * - * @return true if the implementation can process the - * indicated class + * @return true if the implementation can process the indicated class */ public boolean supports(Class clazz); } diff --git a/core/src/main/java/org/acegisecurity/AccessDeniedException.java b/core/src/main/java/org/acegisecurity/AccessDeniedException.java index c3c688156d..5f5204e0c5 100644 --- a/core/src/main/java/org/acegisecurity/AccessDeniedException.java +++ b/core/src/main/java/org/acegisecurity/AccessDeniedException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,15 @@ package org.acegisecurity; /** - * Thrown if an {@link Authentication} object does not hold a required - * authority. + * Thrown if an {@link Authentication} object does not hold a required authority. * * @author Ben Alex * @version $Id$ */ public class AccessDeniedException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AccessDeniedException with the specified * message. * @@ -35,7 +34,7 @@ public class AccessDeniedException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an AccessDeniedException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/AccountExpiredException.java b/core/src/main/java/org/acegisecurity/AccountExpiredException.java index 69cf450097..ef4af2c13d 100644 --- a/core/src/main/java/org/acegisecurity/AccountExpiredException.java +++ b/core/src/main/java/org/acegisecurity/AccountExpiredException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the account has - * expired. Makes no assertion as to whether or not the credentials were - * valid. + * Thrown if an authentication request is rejected because the account has expired. Makes no assertion as to + * whether or not the credentials were valid. * * @author Ben Alex * @version $Id$ */ public class AccountExpiredException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a AccountExpiredException with the specified * message. * @@ -36,7 +35,7 @@ public class AccountExpiredException extends AuthenticationException { super(msg); } - /** +/** * Constructs a AccountExpiredException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/AcegiMessageSource.java b/core/src/main/java/org/acegisecurity/AcegiMessageSource.java index 17bff3103a..f709594588 100644 --- a/core/src/main/java/org/acegisecurity/AcegiMessageSource.java +++ b/core/src/main/java/org/acegisecurity/AcegiMessageSource.java @@ -20,27 +20,22 @@ import org.springframework.context.support.ResourceBundleMessageSource; /** - * The default MessageSource used by Acegi Security. - * - *

- * All Acegi Security classes requiring messge localization will by default use - * this class. However, all such classes will also implement - * MessageSourceAware so that the application context can inject - * an alternative message source. Therefore this class is only used when the - * deployment environment has not specified an alternative message source. - *

+ * The default MessageSource used by Acegi Security.

All Acegi Security classes requiring messge + * localization will by default use this class. However, all such classes will also implement + * MessageSourceAware so that the application context can inject an alternative message source. Therefore + * this class is only used when the deployment environment has not specified an alternative message source.

* * @author Ben Alex * @version $Id$ */ public class AcegiMessageSource extends ResourceBundleMessageSource { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AcegiMessageSource() { setBasename("org.acegisecurity.messages"); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static MessageSourceAccessor getAccessor() { return new MessageSourceAccessor(new AcegiMessageSource()); diff --git a/core/src/main/java/org/acegisecurity/AcegiSecurityException.java b/core/src/main/java/org/acegisecurity/AcegiSecurityException.java index ef1ad9da90..5cd656344e 100644 --- a/core/src/main/java/org/acegisecurity/AcegiSecurityException.java +++ b/core/src/main/java/org/acegisecurity/AcegiSecurityException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,21 +19,16 @@ import org.springframework.core.NestedRuntimeException; /** - * Abstract superclass for all exceptions thrown in the security package and - * subpackages. - * - *

- * Note that this is a runtime (unchecked) exception. Security exceptions are - * usually fatal; there is no reason for them to be checked. - *

+ * Abstract superclass for all exceptions thrown in the security package and subpackages.

Note that this is a + * runtime (unchecked) exception. Security exceptions are usually fatal; there is no reason for them to be checked.

* * @author Ben Alex * @version $Id$ */ public abstract class AcegiSecurityException extends NestedRuntimeException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AcegiSecurityException with the specified * message and root cause. * @@ -44,7 +39,7 @@ public abstract class AcegiSecurityException extends NestedRuntimeException { super(msg, t); } - /** +/** * Constructs an AcegiSecurityException with the specified * message and no root cause. * diff --git a/core/src/main/java/org/acegisecurity/AfterInvocationManager.java b/core/src/main/java/org/acegisecurity/AfterInvocationManager.java index 2937425409..ef232336aa 100644 --- a/core/src/main/java/org/acegisecurity/AfterInvocationManager.java +++ b/core/src/main/java/org/acegisecurity/AfterInvocationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,61 +43,47 @@ package org.acegisecurity; * @version $Id$ */ public interface AfterInvocationManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Given the details of a secure object invocation including its returned - * Object, make an access control decision or optionally - * modify the returned Object. + * Given the details of a secure object invocation including its returned Object, make an + * access control decision or optionally modify the returned Object. * * @param authentication the caller that invoked the method * @param object the secured object that was called - * @param config the configuration attributes associated with the secured - * object that was invoked - * @param returnedObject the Object that was returned from the - * secure object invocation + * @param config the configuration attributes associated with the secured object that was invoked + * @param returnedObject the Object that was returned from the secure object invocation * - * @return the Object that will ultimately be returned to the - * caller (if an implementation does not wish to modify the object - * to be returned to the caller, the implementation should simply - * return the same object it was passed by the - * returnedObject method argument) + * @return the Object that will ultimately be returned to the caller (if an implementation does not + * wish to modify the object to be returned to the caller, the implementation should simply return the + * same object it was passed by the returnedObject method argument) * * @throws AccessDeniedException if access is denied */ - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException; + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException; /** - * Indicates whether this AfterInvocationManager is able to - * process "after invocation" requests presented with the passed - * ConfigAttribute. - * - *

- * This allows the AbstractSecurityInterceptor to check every - * configuration attribute can be consumed by the configured - * AccessDecisionManager and/or RunAsManager - * and/or AfterInvocationManager. - *

+ * Indicates whether this AfterInvocationManager is able to process "after invocation" + * requests presented with the passed ConfigAttribute.

This allows the + * AbstractSecurityInterceptor to check every configuration attribute can be consumed by the + * configured AccessDecisionManager and/or RunAsManager and/or + * AfterInvocationManager.

* - * @param attribute a configuration attribute that has been configured - * against the AbstractSecurityInterceptor + * @param attribute a configuration attribute that has been configured against the + * AbstractSecurityInterceptor * - * @return true if this AfterInvocationManager can support the - * passed configuration attribute + * @return true if this AfterInvocationManager can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); /** - * Indicates whether the AfterInvocationManager implementation - * is able to provide access control decisions for the indicated secured - * object type. + * Indicates whether the AfterInvocationManager implementation is able to provide access + * control decisions for the indicated secured object type. * * @param clazz the class that is being queried * - * @return true if the implementation can process the - * indicated class + * @return true if the implementation can process the indicated class */ public boolean supports(Class clazz); } diff --git a/core/src/main/java/org/acegisecurity/Authentication.java b/core/src/main/java/org/acegisecurity/Authentication.java index b184d7d705..ec3a61c412 100644 --- a/core/src/main/java/org/acegisecurity/Authentication.java +++ b/core/src/main/java/org/acegisecurity/Authentication.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,101 +37,71 @@ import java.security.Principal; * @version $Id$ */ public interface Authentication extends Principal, Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * See {@link #isAuthenticated()} for a full description. - * - *

- * Implementations should always allow this method to be called with - * a false parameter, as this is used by various classes to - * specify the authentication token should not be trusted. If an - * implementation wishes to reject an invocation with a true - * parameter (which would indicate the authentication token is trusted - a - * potential security risk) the implementation should throw an {@link - * IllegalArgumentException}. - *

+ * Set by an AuthenticationManager to indicate the authorities that the principal has been + * granted. Note that classes should not rely on this value as being valid unless it has been set by a trusted + * AuthenticationManager.

Implementations should ensure that modifications to the returned + * array do not affect the state of the Authentication object (e.g. by returning an array copy).

* - * @param isAuthenticated true if the token should be trusted - * (which may result in an exception) or false if the - * token should not be trusted - * - * @throws IllegalArgumentException if an attempt to make the - * authentication token trusted (by passing true as - * the argument) is rejected due to the implementation being - * immutable or implementing its own alternative approach to - * {@link #isAuthenticated()} - */ - public void setAuthenticated(boolean isAuthenticated) - throws IllegalArgumentException; - - /** - * Used to indicate to AbstractSecurityInterceptor whether it - * should present the authentication token to the - * AuthenticationManager. Typically an - * AuthenticationManager (or, more often, one of its - * AuthenticationProviders) will return an immutable - * authentication token after successful authentication, in which case - * that token can safely return true to this method. - * Returning true will improve performance, as calling the - * AuthenticationManager for every request will no longer be - * necessary. - * - *

- * For security reasons, implementations of this interface should be very - * careful about returning true to this method unless they - * are either immutable, or have some way of ensuring the properties have - * not been changed since original creation. - *

- * - * @return true if the token has been authenticated and the - * AbstractSecurityInterceptor does not need to - * represent the token for re-authentication to the - * AuthenticationManager - */ - public boolean isAuthenticated(); - - /** - * Set by an AuthenticationManager to indicate the authorities - * that the principal has been granted. Note that classes should not rely - * on this value as being valid unless it has been set by a trusted - * AuthenticationManager. - *

- * Implementations should ensure that modifications to the returned array - * do not affect the state of the Authentication object (e.g. by returning an - * array copy). - *

- * - * @return the authorities granted to the principal, or null - * if authentication has not been completed + * @return the authorities granted to the principal, or null if authentication has not been completed */ public GrantedAuthority[] getAuthorities(); /** - * The credentials that prove the principal is correct. This is usually a - * password, but could be anything relevant to the - * AuthenticationManager. Callers are expected to populate - * the credentials. + * The credentials that prove the principal is correct. This is usually a password, but could be anything + * relevant to the AuthenticationManager. Callers are expected to populate the credentials. * - * @return the credentials that prove the identity of the - * Principal + * @return the credentials that prove the identity of the Principal */ public Object getCredentials(); /** - * Stores additional details about the authentication request. These might - * be an IP address, certificate serial number etc. + * Stores additional details about the authentication request. These might be an IP address, certificate + * serial number etc. * - * @return additional details about the authentication request, or - * null if not used + * @return additional details about the authentication request, or null if not used */ public Object getDetails(); /** - * The identity of the principal being authenticated. This is usually a - * username. Callers are expected to populate the principal. + * The identity of the principal being authenticated. This is usually a username. Callers are expected to + * populate the principal. * * @return the Principal being authenticated */ public Object getPrincipal(); + + /** + * Used to indicate to AbstractSecurityInterceptor whether it should present the + * authentication token to the AuthenticationManager. Typically an AuthenticationManager + * (or, more often, one of its AuthenticationProviders) will return an immutable authentication token + * after successful authentication, in which case that token can safely return true to this method. + * Returning true will improve performance, as calling the AuthenticationManager for + * every request will no longer be necessary.

For security reasons, implementations of this interface + * should be very careful about returning true to this method unless they are either immutable, or + * have some way of ensuring the properties have not been changed since original creation.

+ * + * @return true if the token has been authenticated and the AbstractSecurityInterceptor does not need + * to represent the token for re-authentication to the AuthenticationManager + */ + public boolean isAuthenticated(); + + /** + * See {@link #isAuthenticated()} for a full description.

Implementations should always allow this + * method to be called with a false parameter, as this is used by various classes to specify the + * authentication token should not be trusted. If an implementation wishes to reject an invocation with a + * true parameter (which would indicate the authentication token is trusted - a potential security + * risk) the implementation should throw an {@link IllegalArgumentException}.

+ * + * @param isAuthenticated true if the token should be trusted (which may result in an exception) or + * false if the token should not be trusted + * + * @throws IllegalArgumentException if an attempt to make the authentication token trusted (by passing + * true as the argument) is rejected due to the implementation being immutable or + * implementing its own alternative approach to {@link #isAuthenticated()} + */ + public void setAuthenticated(boolean isAuthenticated) + throws IllegalArgumentException; } diff --git a/core/src/main/java/org/acegisecurity/AuthenticationCredentialsNotFoundException.java b/core/src/main/java/org/acegisecurity/AuthenticationCredentialsNotFoundException.java index db868a3cf5..f1a2481261 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationCredentialsNotFoundException.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationCredentialsNotFoundException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because there is no {@link - * Authentication} object in the {@link org.acegisecurity.context.SecurityContext SecurityContext}. + * Thrown if an authentication request is rejected because there is no {@link Authentication} object in the {@link + * org.acegisecurity.context.SecurityContext SecurityContext}. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationCredentialsNotFoundException - extends AuthenticationException { - //~ Constructors =========================================================== +public class AuthenticationCredentialsNotFoundException extends AuthenticationException { + //~ Constructors =================================================================================================== - /** +/** * Constructs an AuthenticationCredentialsNotFoundException * with the specified message. * @@ -36,7 +35,7 @@ public class AuthenticationCredentialsNotFoundException super(msg); } - /** +/** * Constructs an AuthenticationCredentialsNotFoundException * with the specified message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/AuthenticationException.java b/core/src/main/java/org/acegisecurity/AuthenticationException.java index f9a17565d6..c8eb374a50 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationException.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,24 +16,21 @@ package org.acegisecurity; /** - * Abstract superclass for all exceptions related an {@link Authentication} - * object being invalid for whatever reason. + * Abstract superclass for all exceptions related an {@link Authentication} object being invalid for whatever + * reason. * * @author Ben Alex * @version $Id$ */ public abstract class AuthenticationException extends AcegiSecurityException { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - /** - * The authentication that related to this exception (may be - * null) - */ + /** The authentication that related to this exception (may be null) */ private Authentication authentication; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AuthenticationException with the specified * message and root cause. * @@ -44,7 +41,7 @@ public abstract class AuthenticationException extends AcegiSecurityException { super(msg, t); } - /** +/** * Constructs an AuthenticationException with the specified * message and no root cause. * @@ -54,7 +51,7 @@ public abstract class AuthenticationException extends AcegiSecurityException { super(msg); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Authentication getAuthentication() { return authentication; diff --git a/core/src/main/java/org/acegisecurity/AuthenticationManager.java b/core/src/main/java/org/acegisecurity/AuthenticationManager.java index 70188f6291..e47f1f974b 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationManager.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,41 +22,21 @@ package org.acegisecurity; * @version $Id$ */ public interface AuthenticationManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Attempts to authenticate the passed {@link Authentication} object, - * returning a fully populated Authentication object - * (including granted authorities) if successful. - * - *

- * An AuthenticationManager must honour the following contract - * concerning exceptions: - *

- * - *

- * A {@link DisabledException} must be thrown if an account is disabled and - * the AuthenticationManager can test for this state. - *

- * - *

- * A {@link LockedException} must be thrown if an account is locked and the - * AuthenticationManager can test for account locking. - *

- * - *

- * A {@link BadCredentialsException} must be thrown if incorrect - * credentials are presented. Whilst the above exceptions are optional, an - * AuthenticationManager must always test credentials. - *

- * - *

- * Exceptions should be tested for and if applicable thrown in the order - * expressed above (ie if an account is disabled or locked, the - * authentication request is immediately rejected and the credentials - * testing process is not performed). This prevents credentials being - * tested against disabled or locked accounts. - *

+ * Attempts to authenticate the passed {@link Authentication} object, returning a fully populated + * Authentication object (including granted authorities) if successful.

An + * AuthenticationManager must honour the following contract concerning exceptions:

+ *

A {@link DisabledException} must be thrown if an account is disabled and the + * AuthenticationManager can test for this state.

+ *

A {@link LockedException} must be thrown if an account is locked and the + * AuthenticationManager can test for account locking.

+ *

A {@link BadCredentialsException} must be thrown if incorrect credentials are presented. Whilst the + * above exceptions are optional, an AuthenticationManager must always test credentials.

+ *

Exceptions should be tested for and if applicable thrown in the order expressed above (ie if an + * account is disabled or locked, the authentication request is immediately rejected and the credentials testing + * process is not performed). This prevents credentials being tested against disabled or locked accounts.

* * @param authentication the authentication request object * diff --git a/core/src/main/java/org/acegisecurity/AuthenticationServiceException.java b/core/src/main/java/org/acegisecurity/AuthenticationServiceException.java index 590aa62531..8231705b0d 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationServiceException.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationServiceException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request could not be processed due to a system - * problem. - * - *

- * This might be thrown if a backend authentication repository is unavailable. - *

+ * Thrown if an authentication request could not be processed due to a system problem.

This might be thrown if a + * backend authentication repository is unavailable.

* * @author Ben Alex * @version $Id$ */ public class AuthenticationServiceException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AuthenticationServiceException with the * specified message. * @@ -39,7 +35,7 @@ public class AuthenticationServiceException extends AuthenticationException { super(msg); } - /** +/** * Constructs an AuthenticationServiceException with the * specified message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/AuthenticationTrustResolver.java b/core/src/main/java/org/acegisecurity/AuthenticationTrustResolver.java index c912a743c7..7272c429bc 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationTrustResolver.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationTrustResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,45 +22,35 @@ package org.acegisecurity; * @version $Id$ */ public interface AuthenticationTrustResolver { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Indicates whether the passed Authentication token - * represents an anonymous user. Typically the framework will call this - * method if it is trying to decide whether an - * AccessDeniedException should result in a final rejection - * (ie as would be the case if the principal was non-anonymous/fully - * authenticated) or direct the principal to attempt actual authentication - * (ie as would be the case if the Authentication was merely - * anonymous). + * Indicates whether the passed Authentication token represents an anonymous user. Typically + * the framework will call this method if it is trying to decide whether an AccessDeniedException + * should result in a final rejection (ie as would be the case if the principal was non-anonymous/fully + * authenticated) or direct the principal to attempt actual authentication (ie as would be the case if the + * Authentication was merely anonymous). * - * @param authentication to test (may be null in which case - * the method will always return false) + * @param authentication to test (may be null in which case the method will always return + * false) * - * @return true the passed authentication token represented an - * anonymous principal, false otherwise + * @return true the passed authentication token represented an anonymous principal, false + * otherwise */ public boolean isAnonymous(Authentication authentication); /** - * Indicates whether the passed Authentication token - * represents user that has been remembered (ie not a user that has been - * fully authenticated). - * - *

- * No part of the framework uses this method, as it is a weak - * definition of trust levels. The method is provided simply to assist - * with custom AccessDecisionVoters and the like that you - * might develop. Of course, you don't need to use this method either and - * can develop your own "trust level" hierarchy instead. - *

+ * Indicates whether the passed Authentication token represents user that has been remembered + * (ie not a user that has been fully authenticated).

No part of the framework uses this method, + * as it is a weak definition of trust levels. The method is provided simply to assist with custom + * AccessDecisionVoters and the like that you might develop. Of course, you don't need to use this + * method either and can develop your own "trust level" hierarchy instead.

* - * @param authentication to test (may be null in which case - * the method will always return false) + * @param authentication to test (may be null in which case the method will always return + * false) * - * @return true the passed authentication token represented a - * principal authenticated using a remember-me token, - * false otherwise + * @return true the passed authentication token represented a principal authenticated using a + * remember-me token, false otherwise */ public boolean isRememberMe(Authentication authentication); } diff --git a/core/src/main/java/org/acegisecurity/AuthenticationTrustResolverImpl.java b/core/src/main/java/org/acegisecurity/AuthenticationTrustResolverImpl.java index f58985531b..92cf210e57 100644 --- a/core/src/main/java/org/acegisecurity/AuthenticationTrustResolverImpl.java +++ b/core/src/main/java/org/acegisecurity/AuthenticationTrustResolverImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,29 +20,29 @@ import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken; /** - * Basic implementation of {@link AuthenticationTrustResolver}. - * - *

- * Makes trust decisions based on whether the passed - * Authentication is an instance of a defined class. - *

- * - *

- * If {@link #anonymousClass} or {@link #rememberMeClass} is null, - * the corresponding method will always return false. - *

+ * Basic implementation of {@link AuthenticationTrustResolver}.

Makes trust decisions based on whether the passed + * Authentication is an instance of a defined class.

+ *

If {@link #anonymousClass} or {@link #rememberMeClass} is null, the corresponding method will + * always return false.

* * @author Ben Alex * @version $Id$ */ -public class AuthenticationTrustResolverImpl - implements AuthenticationTrustResolver { - //~ Instance fields ======================================================== +public class AuthenticationTrustResolverImpl implements AuthenticationTrustResolver { + //~ Instance fields ================================================================================================ private Class anonymousClass = AnonymousAuthenticationToken.class; private Class rememberMeClass = RememberMeAuthenticationToken.class; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public Class getAnonymousClass() { + return anonymousClass; + } + + public Class getRememberMeClass() { + return rememberMeClass; + } public boolean isAnonymous(Authentication authentication) { if ((anonymousClass == null) || (authentication == null)) { @@ -52,14 +52,6 @@ public class AuthenticationTrustResolverImpl return anonymousClass.isAssignableFrom(authentication.getClass()); } - public void setAnonymousClass(Class anonymousClass) { - this.anonymousClass = anonymousClass; - } - - public Class getAnonymousClass() { - return anonymousClass; - } - public boolean isRememberMe(Authentication authentication) { if ((rememberMeClass == null) || (authentication == null)) { return false; @@ -68,11 +60,11 @@ public class AuthenticationTrustResolverImpl return rememberMeClass.isAssignableFrom(authentication.getClass()); } + public void setAnonymousClass(Class anonymousClass) { + this.anonymousClass = anonymousClass; + } + public void setRememberMeClass(Class rememberMeClass) { this.rememberMeClass = rememberMeClass; } - - public Class getRememberMeClass() { - return rememberMeClass; - } } diff --git a/core/src/main/java/org/acegisecurity/AuthorizationServiceException.java b/core/src/main/java/org/acegisecurity/AuthorizationServiceException.java index a6463f344a..3bb850e3c2 100644 --- a/core/src/main/java/org/acegisecurity/AuthorizationServiceException.java +++ b/core/src/main/java/org/acegisecurity/AuthorizationServiceException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authorization request could not be processed due to a system - * problem. - * - *

- * This might be thrown if an AccessDecisionManager implementation - * could not locate a required method argument, for example. - *

+ * Thrown if an authorization request could not be processed due to a system problem.

This might be thrown if an + * AccessDecisionManager implementation could not locate a required method argument, for example.

* * @author Ben Alex * @version $Id$ */ public class AuthorizationServiceException extends AccessDeniedException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AuthorizationServiceException with the * specified message. * @@ -40,7 +35,7 @@ public class AuthorizationServiceException extends AccessDeniedException { super(msg); } - /** +/** * Constructs an AuthorizationServiceException with the * specified message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/BadCredentialsException.java b/core/src/main/java/org/acegisecurity/BadCredentialsException.java index 75e25f1555..fa7c2263f4 100644 --- a/core/src/main/java/org/acegisecurity/BadCredentialsException.java +++ b/core/src/main/java/org/acegisecurity/BadCredentialsException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,20 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the credentials are - * invalid. For this exception to be thrown, it means the account is neither - * locked nor disabled. + * Thrown if an authentication request is rejected because the credentials are invalid. For this exception to be + * thrown, it means the account is neither locked nor disabled. * * @author Ben Alex * @version $Id$ */ public class BadCredentialsException extends AuthenticationException { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object extraInformation; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a BadCredentialsException with the specified * message. * @@ -45,7 +44,7 @@ public class BadCredentialsException extends AuthenticationException { this.extraInformation = extraInformation; } - /** +/** * Constructs a BadCredentialsException with the specified * message and root cause. * @@ -56,11 +55,10 @@ public class BadCredentialsException extends AuthenticationException { super(msg, t); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Any additional information about the exception. Generally a - * UserDetails object. + * Any additional information about the exception. Generally a UserDetails object. * * @return extra information or null */ diff --git a/core/src/main/java/org/acegisecurity/ConfigAttribute.java b/core/src/main/java/org/acegisecurity/ConfigAttribute.java index dd2c407561..97af46423e 100644 --- a/core/src/main/java/org/acegisecurity/ConfigAttribute.java +++ b/core/src/main/java/org/acegisecurity/ConfigAttribute.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,28 +38,19 @@ import java.io.Serializable; * @version $Id$ */ public interface ConfigAttribute extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * If the ConfigAttribute can be represented as a - * String and that String is sufficient in - * precision to be relied upon as a configuration parameter by a {@link - * RunAsManager}, {@link AccessDecisionManager} or - * AccessDecisionManager delegate, this method should return - * such a String. - * - *

- * If the ConfigAttribute cannot be expressed with sufficient - * precision as a String, null should be - * returned. Returning null will require any relying classes - * to specifically support the ConfigAttribute - * implementation, so returning null should be avoided - * unless actually required. - *

+ * If the ConfigAttribute can be represented as a String and that + * String is sufficient in precision to be relied upon as a configuration parameter by a {@link + * RunAsManager}, {@link AccessDecisionManager} or AccessDecisionManager delegate, this method should + * return such a String.

If the ConfigAttribute cannot be expressed with + * sufficient precision as a String, null should be returned. Returning + * null will require any relying classes to specifically support the ConfigAttribute + * implementation, so returning null should be avoided unless actually required.

* - * @return a representation of the configuration attribute (or - * null if the configuration attribute cannot be - * expressed as a String with sufficient precision). + * @return a representation of the configuration attribute (or null if the configuration attribute + * cannot be expressed as a String with sufficient precision). */ public String getAttribute(); } diff --git a/core/src/main/java/org/acegisecurity/ConfigAttributeDefinition.java b/core/src/main/java/org/acegisecurity/ConfigAttributeDefinition.java index b7fc07a358..e071455dee 100644 --- a/core/src/main/java/org/acegisecurity/ConfigAttributeDefinition.java +++ b/core/src/main/java/org/acegisecurity/ConfigAttributeDefinition.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,52 +23,29 @@ import java.util.Vector; /** - * Holds a group of {@link ConfigAttribute}s that are associated with a given - * secure object target. - * - *

- * All the ConfigAttributeDefinitions associated with a given - * {@link org.acegisecurity.intercept.AbstractSecurityInterceptor} are - * stored in an {@link org.acegisecurity.intercept.ObjectDefinitionSource}. - *

+ * Holds a group of {@link ConfigAttribute}s that are associated with a given secure object target.

All the + * ConfigAttributeDefinitions associated with a given {@link + * org.acegisecurity.intercept.AbstractSecurityInterceptor} are stored in an {@link + * org.acegisecurity.intercept.ObjectDefinitionSource}.

* * @author Ben Alex * @version $Id$ */ public class ConfigAttributeDefinition implements Serializable { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List configAttributes = new Vector(); - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ConfigAttributeDefinition() { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Returns an Iterator over all the - * ConfigAttributes defined by this - * ConfigAttributeDefinition. - * - *

- * Allows AccessDecisionManagers and other classes to loop - * through every configuration attribute associated with a target secure - * object. - *

- * - * @return all the configuration attributes stored by the instance, or - * null if an Iterator is unavailable - */ - public Iterator getConfigAttributes() { - return this.configAttributes.iterator(); - } - - /** - * Adds a ConfigAttribute that is related to the secure object - * method. + * Adds a ConfigAttribute that is related to the secure object method. * * @param newConfigAttribute the new configuration attribute to add */ @@ -77,13 +54,13 @@ public class ConfigAttributeDefinition implements Serializable { } /** - * Indicates whether the specified ConfigAttribute is - * contained within this ConfigAttributeDefinition. + * Indicates whether the specified ConfigAttribute is contained within this + * ConfigAttributeDefinition. * * @param configAttribute the attribute to locate * - * @return true if the specified ConfigAttribute - * is contained, false otherwise + * @return true if the specified ConfigAttribute is contained, false + * otherwise */ public boolean contains(ConfigAttribute configAttribute) { return configAttributes.contains(configAttribute); @@ -117,6 +94,18 @@ public class ConfigAttributeDefinition implements Serializable { return false; } + /** + * Returns an Iterator over all the ConfigAttributes defined by this + * ConfigAttributeDefinition.

Allows AccessDecisionManagers and other classes + * to loop through every configuration attribute associated with a target secure object.

+ * + * @return all the configuration attributes stored by the instance, or null if an + * Iterator is unavailable + */ + public Iterator getConfigAttributes() { + return this.configAttributes.iterator(); + } + /** * Returns the number of ConfigAttributes defined by this * ConfigAttributeDefinition. diff --git a/core/src/main/java/org/acegisecurity/ConfigAttributeEditor.java b/core/src/main/java/org/acegisecurity/ConfigAttributeEditor.java index 6093a1ea73..929016cc17 100644 --- a/core/src/main/java/org/acegisecurity/ConfigAttributeEditor.java +++ b/core/src/main/java/org/acegisecurity/ConfigAttributeEditor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +21,15 @@ import java.beans.PropertyEditorSupport; /** - * A property editor that can create a populated {@link - * ConfigAttributeDefinition} from a comma separated list of values. - * - *

- * Trims preceding and trailing spaces from presented command separated tokens, - * as this can be a source of hard-to-spot configuration issues for end users. - *

+ * A property editor that can create a populated {@link ConfigAttributeDefinition} from a comma separated list of + * values.

Trims preceding and trailing spaces from presented command separated tokens, as this can be a source + * of hard-to-spot configuration issues for end users.

* * @author Ben Alex * @version $Id$ */ public class ConfigAttributeEditor extends PropertyEditorSupport { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void setAsText(String s) throws IllegalArgumentException { if ((s == null) || "".equals(s)) { @@ -43,8 +39,7 @@ public class ConfigAttributeEditor extends PropertyEditorSupport { ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition(); for (int i = 0; i < tokens.length; i++) { - configDefinition.addConfigAttribute(new SecurityConfig( - tokens[i].trim())); + configDefinition.addConfigAttribute(new SecurityConfig(tokens[i].trim())); } setValue(configDefinition); diff --git a/core/src/main/java/org/acegisecurity/CredentialsExpiredException.java b/core/src/main/java/org/acegisecurity/CredentialsExpiredException.java index b65e1448d0..950f6ad7a4 100644 --- a/core/src/main/java/org/acegisecurity/CredentialsExpiredException.java +++ b/core/src/main/java/org/acegisecurity/CredentialsExpiredException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the account's - * credentials have expired. Makes no assertion as to whether or not the - * credentials were valid. + * Thrown if an authentication request is rejected because the account's credentials have expired. Makes no + * assertion as to whether or not the credentials were valid. * * @author Ben Alex * @version $Id$ */ public class CredentialsExpiredException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a CredentialsExpiredException with the specified * message. * @@ -36,7 +35,7 @@ public class CredentialsExpiredException extends AuthenticationException { super(msg); } - /** +/** * Constructs a CredentialsExpiredException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/DisabledException.java b/core/src/main/java/org/acegisecurity/DisabledException.java index dbfb5e335f..bfa50edc2c 100644 --- a/core/src/main/java/org/acegisecurity/DisabledException.java +++ b/core/src/main/java/org/acegisecurity/DisabledException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the account is - * disabled. Makes no assertion as to whether or not the credentials were - * valid. + * Thrown if an authentication request is rejected because the account is disabled. Makes no assertion as to + * whether or not the credentials were valid. * * @author Ben Alex * @version $Id$ */ public class DisabledException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a DisabledException with the specified message. * * @param msg the detail message @@ -35,7 +34,7 @@ public class DisabledException extends AuthenticationException { super(msg); } - /** +/** * Constructs a DisabledException with the specified message * and root cause. * diff --git a/core/src/main/java/org/acegisecurity/GrantedAuthority.java b/core/src/main/java/org/acegisecurity/GrantedAuthority.java index 5b5374213e..1e312cf3af 100644 --- a/core/src/main/java/org/acegisecurity/GrantedAuthority.java +++ b/core/src/main/java/org/acegisecurity/GrantedAuthority.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,27 +28,19 @@ package org.acegisecurity; * @version $Id$ */ public interface GrantedAuthority { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * If the GrantedAuthority can be represented as a - * String and that String is sufficient in - * precision to be relied upon for an access control decision by an {@link - * AccessDecisionManager} (or delegate), this method should return such a - * String. - * - *

- * If the GrantedAuthority cannot be expressed with sufficient - * precision as a String, null should be - * returned. Returning null will require an - * AccessDecisionManager (or delegate) to specifically - * support the GrantedAuthority implementation, so returning - * null should be avoided unless actually required. - *

+ * If the GrantedAuthority can be represented as a String and that + * String is sufficient in precision to be relied upon for an access control decision by an {@link + * AccessDecisionManager} (or delegate), this method should return such a String.

If the + * GrantedAuthority cannot be expressed with sufficient precision as a String, + * null should be returned. Returning null will require an + * AccessDecisionManager (or delegate) to specifically support the GrantedAuthority + * implementation, so returning null should be avoided unless actually required.

* - * @return a representation of the granted authority (or null - * if the granted authority cannot be expressed as a - * String with sufficient precision). + * @return a representation of the granted authority (or null if the granted authority cannot be + * expressed as a String with sufficient precision). */ public String getAuthority(); } diff --git a/core/src/main/java/org/acegisecurity/GrantedAuthorityImpl.java b/core/src/main/java/org/acegisecurity/GrantedAuthorityImpl.java index 171154ca5e..0cd0c8fcb9 100644 --- a/core/src/main/java/org/acegisecurity/GrantedAuthorityImpl.java +++ b/core/src/main/java/org/acegisecurity/GrantedAuthorityImpl.java @@ -19,29 +19,25 @@ import java.io.Serializable; /** - * Basic concrete implementation of a {@link GrantedAuthority}. - * - *

- * Stores a String representation of an authority granted to the - * {@link Authentication} object. - *

+ * Basic concrete implementation of a {@link GrantedAuthority}.

Stores a String representation of an + * authority granted to the {@link Authentication} object.

* * @author Ben Alex * @version $Id$ */ public class GrantedAuthorityImpl implements GrantedAuthority, Serializable { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String role; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public GrantedAuthorityImpl(String role) { super(); this.role = role; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (obj instanceof String) { diff --git a/core/src/main/java/org/acegisecurity/InsufficientAuthenticationException.java b/core/src/main/java/org/acegisecurity/InsufficientAuthenticationException.java index 3c5c1f4fab..b3b9f79f33 100644 --- a/core/src/main/java/org/acegisecurity/InsufficientAuthenticationException.java +++ b/core/src/main/java/org/acegisecurity/InsufficientAuthenticationException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,19 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the credentials are - * not sufficiently trusted. - * - *

- * {@link org.acegisecurity.vote.AccessDecisionVoter}s will typically throw - * this exception if they are dissatisfied with the level of the - * authentication, such as if performed using a remember-me mechanism or - * anonymously. The commonly used {@link - * org.acegisecurity.ui.ExceptionTranslationFilter} will thus - * cause the AuthenticationEntryPoint to be called, allowing the - * principal to authenticate with a stronger level of authentication. - *

+ * Thrown if an authentication request is rejected because the credentials are not sufficiently trusted.

{{@link + * org.acegisecurity.vote.AccessDecisionVoter}s will typically throw this exception if they are dissatisfied with the + * level of the authentication, such as if performed using a remember-me mechanism or anonymously. The commonly used + * {@link org.acegisecurity.ui.ExceptionTranslationFilter} will thus cause the AuthenticationEntryPoint + * to be called, allowing the principal to authenticate with a stronger level of authentication.}

* * @author Ben Alex * @version $Id$ */ public class InsufficientAuthenticationException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an InsufficientAuthenticationException with the * specified message. * @@ -45,7 +38,7 @@ public class InsufficientAuthenticationException extends AuthenticationException super(msg); } - /** +/** * Constructs an InsufficientAuthenticationException with the * specified message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/LockedException.java b/core/src/main/java/org/acegisecurity/LockedException.java index 965136791c..df4048c6ef 100644 --- a/core/src/main/java/org/acegisecurity/LockedException.java +++ b/core/src/main/java/org/acegisecurity/LockedException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,16 @@ package org.acegisecurity; /** - * Thrown if an authentication request is rejected because the account is - * locked. Makes no assertion as to whether or not the credentials were valid. + * Thrown if an authentication request is rejected because the account is locked. Makes no assertion as to whether + * or not the credentials were valid. * * @author Ben Alex * @version $Id$ */ public class LockedException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a LockedException with the specified message. * * @param msg the detail message. @@ -34,7 +34,7 @@ public class LockedException extends AuthenticationException { super(msg); } - /** +/** * Constructs a LockedException with the specified message and * root cause. * diff --git a/core/src/main/java/org/acegisecurity/MockAuthenticationManager.java b/core/src/main/java/org/acegisecurity/MockAuthenticationManager.java index 9766dbe238..d55ecd7a5d 100644 --- a/core/src/main/java/org/acegisecurity/MockAuthenticationManager.java +++ b/core/src/main/java/org/acegisecurity/MockAuthenticationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,19 +16,18 @@ package org.acegisecurity; /** - * Simply accepts as valid whatever is passed to it, if - * grantAccess is set to true. + * Simply accepts as valid whatever is passed to it, if grantAccess is set to true. * * @author Ben Alex * @author Wesley Hall * @version $Id$ */ public class MockAuthenticationManager extends AbstractAuthenticationManager { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean grantAccess = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockAuthenticationManager(boolean grantAccess) { this.grantAccess = grantAccess; @@ -38,15 +37,14 @@ public class MockAuthenticationManager extends AbstractAuthenticationManager { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Authentication doAuthentication(Authentication authentication) throws AuthenticationException { if (grantAccess) { return authentication; } else { - throw new BadCredentialsException( - "MockAuthenticationManager instructed to deny access"); + throw new BadCredentialsException("MockAuthenticationManager instructed to deny access"); } } } diff --git a/core/src/main/java/org/acegisecurity/RunAsManager.java b/core/src/main/java/org/acegisecurity/RunAsManager.java index 840a96349b..25493bc73e 100644 --- a/core/src/main/java/org/acegisecurity/RunAsManager.java +++ b/core/src/main/java/org/acegisecurity/RunAsManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,47 +58,37 @@ package org.acegisecurity; * @version $Id$ */ public interface RunAsManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Returns a replacement Authentication object for the current - * secure object invocation, or null if replacement not - * required. + * Returns a replacement Authentication object for the current secure object invocation, or + * null if replacement not required. * * @param authentication the caller invoking the secure object * @param object the secured object being called - * @param config the configuration attributes associated with the secure - * object being invoked + * @param config the configuration attributes associated with the secure object being invoked * - * @return a replacement object to be used for duration of the secure - * object invocation, or null if the - * Authentication should be left as is + * @return a replacement object to be used for duration of the secure object invocation, or null if + * the Authentication should be left as is */ - public Authentication buildRunAs(Authentication authentication, - Object object, ConfigAttributeDefinition config); + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config); /** - * Indicates whether this RunAsManager is able to process the - * passed ConfigAttribute. - * - *

- * This allows the AbstractSecurityInterceptor to check every - * configuration attribute can be consumed by the configured - * AccessDecisionManager and/or RunAsManager - * and/or AfterInvocationManager. - *

+ * Indicates whether this RunAsManager is able to process the passed + * ConfigAttribute.

This allows the AbstractSecurityInterceptor to check every + * configuration attribute can be consumed by the configured AccessDecisionManager and/or + * RunAsManager and/or AfterInvocationManager.

* - * @param attribute a configuration attribute that has been configured - * against the AbstractSecurityInterceptor + * @param attribute a configuration attribute that has been configured against the + * AbstractSecurityInterceptor * - * @return true if this RunAsManager can support - * the passed configuration attribute + * @return true if this RunAsManager can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); /** - * Indicates whether the RunAsManager implementation is able - * to provide run-as replacement for the indicated secure object type. + * Indicates whether the RunAsManager implementation is able to provide run-as replacement for + * the indicated secure object type. * * @param clazz the class that is being queried * diff --git a/core/src/main/java/org/acegisecurity/SecurityConfig.java b/core/src/main/java/org/acegisecurity/SecurityConfig.java index e792ce717a..2df626f9bb 100644 --- a/core/src/main/java/org/acegisecurity/SecurityConfig.java +++ b/core/src/main/java/org/acegisecurity/SecurityConfig.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,21 +22,17 @@ package org.acegisecurity; * @version $Id$ */ public class SecurityConfig implements ConfigAttribute { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String attrib; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityConfig(String config) { this.attrib = config; } - //~ Methods ================================================================ - - public String getAttribute() { - return this.attrib; - } + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (obj instanceof String) { @@ -52,6 +48,10 @@ public class SecurityConfig implements ConfigAttribute { return false; } + public String getAttribute() { + return this.attrib; + } + public int hashCode() { return this.attrib.hashCode(); } diff --git a/core/src/main/java/org/acegisecurity/acl/AclEntry.java b/core/src/main/java/org/acegisecurity/acl/AclEntry.java index 1c2e6af3e8..a7fbed083b 100644 --- a/core/src/main/java/org/acegisecurity/acl/AclEntry.java +++ b/core/src/main/java/org/acegisecurity/acl/AclEntry.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.acl; import java.io.Serializable; + /** * Marker interface representing an access control list entry associated with a * specific domain object instance. diff --git a/core/src/main/java/org/acegisecurity/acl/AclManager.java b/core/src/main/java/org/acegisecurity/acl/AclManager.java index c167ebe86c..d259ae684e 100644 --- a/core/src/main/java/org/acegisecurity/acl/AclManager.java +++ b/core/src/main/java/org/acegisecurity/acl/AclManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,33 +26,26 @@ import org.acegisecurity.Authentication; * @version $Id$ */ public interface AclManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains the ACLs that apply to the specified domain instance. * - * @param domainInstance the instance for which ACL information is required - * (never null) + * @param domainInstance the instance for which ACL information is required (never null) * - * @return the ACLs that apply, or null if no ACLs apply to - * the specified domain instance + * @return the ACLs that apply, or null if no ACLs apply to the specified domain instance */ public AclEntry[] getAcls(Object domainInstance); /** - * Obtains the ACLs that apply to the specified domain instance, but only - * including those ACLs which have been granted to the presented - * Authentication object + * Obtains the ACLs that apply to the specified domain instance, but only including those ACLs which have + * been granted to the presented Authentication object * - * @param domainInstance the instance for which ACL information is required - * (never null) - * @param authentication the prncipal for which ACL information should be - * filtered (never null) + * @param domainInstance the instance for which ACL information is required (never null) + * @param authentication the prncipal for which ACL information should be filtered (never null) * - * @return only those ACLs applying to the domain instance that have been - * granted to the principal (or null) if no such ACLs - * are found + * @return only those ACLs applying to the domain instance that have been granted to the principal (or + * null) if no such ACLs are found */ - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication); + public AclEntry[] getAcls(Object domainInstance, Authentication authentication); } diff --git a/core/src/main/java/org/acegisecurity/acl/AclProvider.java b/core/src/main/java/org/acegisecurity/acl/AclProvider.java index b866f0d7e6..635957cee1 100644 --- a/core/src/main/java/org/acegisecurity/acl/AclProvider.java +++ b/core/src/main/java/org/acegisecurity/acl/AclProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.acl; import org.acegisecurity.Authentication; + /** * Indicates a class can process a given domain object instance and * authoritatively return the ACLs that apply. @@ -29,54 +30,38 @@ import org.acegisecurity.Authentication; * @version $Id$ */ public interface AclProvider { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the ACLs that apply to the specified domain instance. - * - *

- * Will never be called unless the {@link #supports(Object)} method - * returned true. - *

+ * Obtains the ACLs that apply to the specified domain instance.

Will never be called unless the {@link + * #supports(Object)} method returned true.

* - * @param domainInstance the instance for which ACL information is required - * (never null) + * @param domainInstance the instance for which ACL information is required (never null) * - * @return the ACLs that apply, or null if no ACLs apply to - * the specified domain instance + * @return the ACLs that apply, or null if no ACLs apply to the specified domain instance */ public AclEntry[] getAcls(Object domainInstance); /** - * Obtains the ACLs that apply to the specified domain instance - * and presented Authentication object. + * Obtains the ACLs that apply to the specified domain instance and presented Authentication + * object.

Will never be called unless the {@link #supports(Object)} method returned true.

* - *

- * Will never be called unless the {@link #supports(Object)} method - * returned true. - *

- * - * @param domainInstance the instance for which ACL information is required - * (never null) - * @param authentication the prncipal for which ACL information should be - * filtered (never null) + * @param domainInstance the instance for which ACL information is required (never null) + * @param authentication the prncipal for which ACL information should be filtered (never null) * - * @return only those ACLs applying to the domain instance that have been - * granted to the principal (or null) if no such ACLs - * are found + * @return only those ACLs applying to the domain instance that have been granted to the principal (or + * null) if no such ACLs are found */ - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication); + public AclEntry[] getAcls(Object domainInstance, Authentication authentication); /** - * Indicates whether this AclProvider can authoritatively - * return ACL information for the specified domain object instance. + * Indicates whether this AclProvider can authoritatively return ACL information for the + * specified domain object instance. * - * @param domainInstance the instance for which ACL information is required - * (never null) + * @param domainInstance the instance for which ACL information is required (never null) * - * @return true if this provider is authoritative for the - * specified domain object instance, false otherwise + * @return true if this provider is authoritative for the specified domain object instance, + * false otherwise */ public boolean supports(Object domainInstance); } diff --git a/core/src/main/java/org/acegisecurity/acl/AclProviderManager.java b/core/src/main/java/org/acegisecurity/acl/AclProviderManager.java index 508a757ddf..168e5594f5 100644 --- a/core/src/main/java/org/acegisecurity/acl/AclProviderManager.java +++ b/core/src/main/java/org/acegisecurity/acl/AclProviderManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.util.Iterator; @@ -28,27 +29,31 @@ import java.util.List; /** - * Iterates through a list of {@link AclProvider}s to locate the ACLs that - * apply to a given domain object instance. - * - *

- * If no compatible provider is found, it is assumed that no ACLs apply for the - * specified domain object instance and null is returned. - *

+ * Iterates through a list of {@link AclProvider}s to locate the ACLs that apply to a given domain object instance.

If + * no compatible provider is found, it is assumed that no ACLs apply for the specified domain object instance and + * null is returned.

* * @author Ben Alex * @version $Id$ */ public class AclProviderManager implements AclManager, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AclProviderManager.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List providers; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() throws Exception { + checkIfValidList(this.providers); + } + + private void checkIfValidList(List listToCheck) { + Assert.notEmpty(listToCheck, "A list of AclManagers is required"); + } public AclEntry[] getAcls(Object domainInstance) { Assert.notNull(domainInstance, "domainInstance is null - violating interface contract"); @@ -60,8 +65,7 @@ public class AclProviderManager implements AclManager, InitializingBean { if (provider.supports(domainInstance)) { if (logger.isDebugEnabled()) { - logger.debug("ACL lookup using " - + provider.getClass().getName()); + logger.debug("ACL lookup using " + provider.getClass().getName()); } return provider.getAcls(domainInstance); @@ -69,15 +73,13 @@ public class AclProviderManager implements AclManager, InitializingBean { } if (logger.isDebugEnabled()) { - logger.debug("No AclProvider found for " - + domainInstance.toString()); + logger.debug("No AclProvider found for " + domainInstance.toString()); } return null; } - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication) { + public AclEntry[] getAcls(Object domainInstance, Authentication authentication) { Assert.notNull(domainInstance, "domainInstance is null - violating interface contract"); Assert.notNull(authentication, "authentication is null - violating interface contract"); @@ -88,34 +90,34 @@ public class AclProviderManager implements AclManager, InitializingBean { if (provider.supports(domainInstance)) { if (logger.isDebugEnabled()) { - logger.debug("ACL lookup using " - + provider.getClass().getName()); + logger.debug("ACL lookup using " + provider.getClass().getName()); } return provider.getAcls(domainInstance, authentication); } else { if (logger.isDebugEnabled()) { - logger.debug("Provider " + provider.toString() - + " does not support " + domainInstance); + logger.debug("Provider " + provider.toString() + " does not support " + domainInstance); } } } if (logger.isDebugEnabled()) { - logger.debug("No AclProvider found for " - + domainInstance.toString()); + logger.debug("No AclProvider found for " + domainInstance.toString()); } return null; } + public List getProviders() { + return this.providers; + } + /** * Sets the {@link AclProvider} objects to be used for ACL determinations. * * @param newList that should be used for ACL determinations * - * @throws IllegalArgumentException if an invalid provider was included in - * the list + * @throws IllegalArgumentException if an invalid provider was included in the list */ public void setProviders(List newList) { checkIfValidList(newList); @@ -130,24 +132,11 @@ public class AclProviderManager implements AclManager, InitializingBean { AclProvider attemptToCast = (AclProvider) currentObject; } catch (ClassCastException cce) { - throw new IllegalArgumentException("AclProvider " - + currentObject.getClass().getName() + throw new IllegalArgumentException("AclProvider " + currentObject.getClass().getName() + " must implement AclProvider"); } } this.providers = newList; } - - public List getProviders() { - return this.providers; - } - - public void afterPropertiesSet() throws Exception { - checkIfValidList(this.providers); - } - - private void checkIfValidList(List listToCheck) { - Assert.notEmpty(listToCheck, "A list of AclManagers is required"); - } } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/AbstractBasicAclEntry.java b/core/src/main/java/org/acegisecurity/acl/basic/AbstractBasicAclEntry.java index 99fa2810fb..6382a19d9d 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/AbstractBasicAclEntry.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/AbstractBasicAclEntry.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,27 +17,24 @@ package org.acegisecurity.acl.basic; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; import java.util.Arrays; /** - * Abstract implementation of {@link BasicAclEntry}. - * - *

- * Provides core bit mask handling methods. - *

+ * Abstract implementation of {@link BasicAclEntry}.

Provides core bit mask handling methods.

* * @author Ben Alex * @version $Id$ */ public abstract class AbstractBasicAclEntry implements BasicAclEntry { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AbstractBasicAclEntry.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclObjectIdentity aclObjectIdentity; private AclObjectIdentity aclObjectParentIdentity; @@ -45,10 +42,9 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { private int[] validPermissions; private int mask = 0; // default means no permissions - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public AbstractBasicAclEntry(Object recipient, - AclObjectIdentity aclObjectIdentity, + public AbstractBasicAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity, AclObjectIdentity aclObjectParentIdentity, int mask) { Assert.notNull(recipient, "recipient cannot be null"); @@ -59,10 +55,8 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { for (int i = 0; i < validPermissions.length; i++) { if (logger.isDebugEnabled()) { - logger.debug("Valid permission: " - + printPermissionsBlock(validPermissions[i]) + " " - + printBinary(validPermissions[i]) + " (" - + validPermissions[i] + ")"); + logger.debug("Valid permission: " + printPermissionsBlock(validPermissions[i]) + " " + + printBinary(validPermissions[i]) + " (" + validPermissions[i] + ")"); } } @@ -72,7 +66,7 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { this.mask = mask; } - /** +/** * A protected constructor for use by Hibernate. */ protected AbstractBasicAclEntry() { @@ -80,86 +74,7 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { Arrays.sort(validPermissions); } - //~ Methods ================================================================ - - public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity) { - this.aclObjectIdentity = aclObjectIdentity; - } - - public AclObjectIdentity getAclObjectIdentity() { - return this.aclObjectIdentity; - } - - public void setAclObjectParentIdentity( - AclObjectIdentity aclObjectParentIdentity) { - this.aclObjectParentIdentity = aclObjectParentIdentity; - } - - public AclObjectIdentity getAclObjectParentIdentity() { - return this.aclObjectParentIdentity; - } - - /** - * Subclasses must indicate the permissions they support. Each base - * permission should be an integer with a base 2. ie: the first permission - * is 2^^0 (1), the second permission is 2^^1 (2), the third permission is - * 2^^2 (4) etc. Each base permission should be exposed by the subclass as - * a public static final int. It is further recommended that - * valid combinations of permissions are also exposed as public - * static final ints. - * - *

- * This method returns all permission integers that are allowed to be used - * together. This must include any combinations of valid - * permissions. So if the permissions indicated by 2^^2 (4) and 2^^1 - * (2) can be used together, one of the integers returned by this method - * must be 6 (4 + 2). Otherwise attempts to set the permission will be - * rejected, as the final resulting mask will be rejected. - *

- * - *

- * Whilst it may seem unduly time onerous to return every valid permission - * combination, doing so delivers maximum flexibility in ensuring - * ACLs only reflect logical combinations. For example, it would be - * inappropriate to grant a "read" and "write" permission along with an - * "unrestricted" permission, as the latter implies the former - * permissions. - *

- * - * @return every valid combination of permissions - */ - public abstract int[] getValidPermissions(); - - /** - * Outputs the permissions in a human-friendly format. For example, this - * method may return "CR-D" to indicate the passed integer permits create, - * permits read, does not permit update, and permits delete. - * - * @param i the integer containing the mask which should be printed - * - * @return the human-friend formatted block - */ - public abstract String printPermissionsBlock(int i); - - public void setMask(int mask) { - this.mask = mask; - } - - public int getMask() { - return this.mask; - } - - public boolean isPermitted(int permissionToCheck) { - return isPermitted(this.mask, permissionToCheck); - } - - public void setRecipient(Object recipient) { - this.recipient = recipient; - } - - public Object getRecipient() { - return this.recipient; - } + //~ Methods ======================================================================================================== public int addPermission(int permissionToAdd) { return addPermissions(new int[] {permissionToAdd}); @@ -167,29 +82,25 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { public int addPermissions(int[] permissionsToAdd) { if (logger.isDebugEnabled()) { - logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) - + " " + printBinary(mask) + " (" + mask + ")"); + logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask + + ")"); } for (int i = 0; i < permissionsToAdd.length; i++) { if (logger.isDebugEnabled()) { - logger.debug("Add permission: " - + printPermissionsBlock(permissionsToAdd[i]) + " " - + printBinary(permissionsToAdd[i]) + " (" - + permissionsToAdd[i] + ")"); + logger.debug("Add permission: " + printPermissionsBlock(permissionsToAdd[i]) + " " + + printBinary(permissionsToAdd[i]) + " (" + permissionsToAdd[i] + ")"); } this.mask |= permissionsToAdd[i]; } if (Arrays.binarySearch(validPermissions, this.mask) < 0) { - throw new IllegalArgumentException( - "Resulting permission set will be invalid."); + throw new IllegalArgumentException("Resulting permission set will be invalid."); } else { if (logger.isDebugEnabled()) { - logger.debug("AFTER Permissions: " - + printPermissionsBlock(mask) + " " + printBinary(mask) - + " (" + mask + ")"); + logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + + mask + ")"); } return this.mask; @@ -202,65 +113,67 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { public int deletePermissions(int[] permissionsToDelete) { if (logger.isDebugEnabled()) { - logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) - + " " + printBinary(mask) + " (" + mask + ")"); + logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask + + ")"); } for (int i = 0; i < permissionsToDelete.length; i++) { if (logger.isDebugEnabled()) { - logger.debug("Delete permission: " - + printPermissionsBlock(permissionsToDelete[i]) + " " - + printBinary(permissionsToDelete[i]) + " (" - + permissionsToDelete[i] + ")"); + logger.debug("Delete permission: " + printPermissionsBlock(permissionsToDelete[i]) + " " + + printBinary(permissionsToDelete[i]) + " (" + permissionsToDelete[i] + ")"); } this.mask &= ~permissionsToDelete[i]; } if (Arrays.binarySearch(validPermissions, this.mask) < 0) { - throw new IllegalArgumentException( - "Resulting permission set will be invalid."); + throw new IllegalArgumentException("Resulting permission set will be invalid."); } else { if (logger.isDebugEnabled()) { - logger.debug("AFTER Permissions: " - + printPermissionsBlock(mask) + " " + printBinary(mask) - + " (" + mask + ")"); + logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + + mask + ")"); } return this.mask; } } + public AclObjectIdentity getAclObjectIdentity() { + return this.aclObjectIdentity; + } + + public AclObjectIdentity getAclObjectParentIdentity() { + return this.aclObjectParentIdentity; + } + + public int getMask() { + return this.mask; + } + + public Object getRecipient() { + return this.recipient; + } + /** - * Outputs the permissions in human-friendly format for the current - * AbstractBasicAclEntry's mask. + * Subclasses must indicate the permissions they support. Each base permission should be an integer with a + * base 2. ie: the first permission is 2^^0 (1), the second permission is 2^^1 (2), the third permission is 2^^2 + * (4) etc. Each base permission should be exposed by the subclass as a public static final int. It + * is further recommended that valid combinations of permissions are also exposed as public static final + * ints.

This method returns all permission integers that are allowed to be used together. This + * must include any combinations of valid permissions. So if the permissions indicated by 2^^2 (4) and 2^^1 + * (2) can be used together, one of the integers returned by this method must be 6 (4 + 2). Otherwise attempts to + * set the permission will be rejected, as the final resulting mask will be rejected.

+ *

Whilst it may seem unduly time onerous to return every valid permission combination, doing so + * delivers maximum flexibility in ensuring ACLs only reflect logical combinations. For example, it would be + * inappropriate to grant a "read" and "write" permission along with an "unrestricted" permission, as the latter + * implies the former permissions.

* - * @return the human-friendly formatted block for this instance + * @return every valid combination of permissions */ - public String printPermissionsBlock() { - return printPermissionsBlock(this.mask); - } + public abstract int[] getValidPermissions(); - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); - sb.append("[").append(aclObjectIdentity).append(",").append(recipient); - sb.append("=").append(printPermissionsBlock(mask)).append(" "); - sb.append(printBinary(mask)).append(" ("); - sb.append(mask).append(")").append("]"); - - return sb.toString(); - } - - public int togglePermission(int permissionToToggle) { - this.mask ^= permissionToToggle; - - if (Arrays.binarySearch(validPermissions, this.mask) < 0) { - throw new IllegalArgumentException( - "Resulting permission set will be invalid."); - } else { - return this.mask; - } + public boolean isPermitted(int permissionToCheck) { + return isPermitted(this.mask, permissionToCheck); } protected boolean isPermitted(int maskToCheck, int permissionToCheck) { @@ -278,4 +191,61 @@ public abstract class AbstractBasicAclEntry implements BasicAclEntry { return temp2.replace('0', '.'); } + + /** + * Outputs the permissions in a human-friendly format. For example, this method may return "CR-D" to + * indicate the passed integer permits create, permits read, does not permit update, and permits delete. + * + * @param i the integer containing the mask which should be printed + * + * @return the human-friend formatted block + */ + public abstract String printPermissionsBlock(int i); + + /** + * Outputs the permissions in human-friendly format for the current AbstractBasicAclEntry's + * mask. + * + * @return the human-friendly formatted block for this instance + */ + public String printPermissionsBlock() { + return printPermissionsBlock(this.mask); + } + + public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity) { + this.aclObjectIdentity = aclObjectIdentity; + } + + public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity) { + this.aclObjectParentIdentity = aclObjectParentIdentity; + } + + public void setMask(int mask) { + this.mask = mask; + } + + public void setRecipient(Object recipient) { + this.recipient = recipient; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()); + sb.append("[").append(aclObjectIdentity).append(",").append(recipient); + sb.append("=").append(printPermissionsBlock(mask)).append(" "); + sb.append(printBinary(mask)).append(" ("); + sb.append(mask).append(")").append("]"); + + return sb.toString(); + } + + public int togglePermission(int permissionToToggle) { + this.mask ^= permissionToToggle; + + if (Arrays.binarySearch(validPermissions, this.mask) < 0) { + throw new IllegalArgumentException("Resulting permission set will be invalid."); + } else { + return this.mask; + } + } } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentity.java b/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentity.java index 6472af01a6..5ba4f97f10 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentity.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentity.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,22 +44,19 @@ import java.io.Serializable; * @version $Id$ */ public interface AclObjectIdentity extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @param obj to be compared * - * @return true if the objects are equal, false - * otherwise + * @return true if the objects are equal, false otherwise */ public boolean equals(Object obj); /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @return a hash code representation of this object */ diff --git a/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentityAware.java b/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentityAware.java index 4d1fbb502d..bfe7b2940b 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentityAware.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/AclObjectIdentityAware.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,13 +30,12 @@ package org.acegisecurity.acl.basic; * @version $Id$ */ public interface AclObjectIdentityAware { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Retrieves the AclObjectIdentity for this instance. * - * @return the ACL object identity for this instance (can never be - * null) + * @return the ACL object identity for this instance (can never be null) */ public AclObjectIdentity getAclObjectIdentity(); } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclDao.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclDao.java index 7da5e16448..fa5f979846 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclDao.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclDao.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,24 +35,18 @@ package org.acegisecurity.acl.basic; * @version $Id$ */ public interface BasicAclDao { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the ACLs that apply to the specified domain instance. - * - *

- * Does not perform caching, include ACLs from any inheritance - * hierarchy or filter returned objects based on effective permissions. - * Implementations are solely responsible for returning ACLs found in the - * ACL repository for the specified object identity. - *

+ * Obtains the ACLs that apply to the specified domain instance.

Does not perform caching, include + * ACLs from any inheritance hierarchy or filter returned objects based on effective permissions. Implementations + * are solely responsible for returning ACLs found in the ACL repository for the specified object identity.

* - * @param aclObjectIdentity the domain object instance that ACL information - * is being requested for (never null) + * @param aclObjectIdentity the domain object instance that ACL information is being requested for (never + * null) * - * @return the ACLs that apply (no nulls are permitted in the - * array), or null if no ACLs could be found for the - * specified ACL object identity + * @return the ACLs that apply (no nulls are permitted in the array), or null if no ACLs + * could be found for the specified ACL object identity */ public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity); } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntry.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntry.java index ac2a7131a3..7a7968c921 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntry.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntry.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,50 +25,79 @@ import org.acegisecurity.acl.AclEntry; * @version $Id$ */ public interface BasicAclEntry extends AclEntry { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This setter should only be used by DAO implementations. + * Indicates the domain object instance that is subject of this BasicAclEntry. This + * information may be of interest to relying classes (voters and business methods) that wish to know the actual + * origination of the ACL entry (so as to distinguish individual ACL entries from others contributed by the + * inheritance hierarchy). * - * @param aclObjectIdentity an object which can be used to uniquely - * identify the domain object instance subject of this ACL entry - */ - public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity); - - /** - * Indicates the domain object instance that is subject of this - * BasicAclEntry. This information may be of interest to - * relying classes (voters and business methods) that wish to know the - * actual origination of the ACL entry (so as to distinguish individual - * ACL entries from others contributed by the inheritance hierarchy). - * - * @return the ACL object identity that is subject of this ACL entry (never - * null) + * @return the ACL object identity that is subject of this ACL entry (never null) */ public AclObjectIdentity getAclObjectIdentity(); /** - * This setter should only be used by DAO implementations. + * Indicates any ACL parent of the domain object instance. This is used by BasicAclProvider to + * walk the inheritance hierarchy. An domain object instance need not have a parent. * - * @param aclObjectParentIdentity an object which represents the parent of - * the domain object instance subject of this ACL entry, or - * null if either the domain object instance has no - * parent or its parent should be not used to compute an - * inheritance hierarchy - */ - public void setAclObjectParentIdentity( - AclObjectIdentity aclObjectParentIdentity); - - /** - * Indicates any ACL parent of the domain object instance. This is used by - * BasicAclProvider to walk the inheritance hierarchy. An - * domain object instance need not have a parent. - * - * @return the ACL object identity that is the parent of this ACL entry - * (may be null if no parent should be consulted) + * @return the ACL object identity that is the parent of this ACL entry (may be null if no parent + * should be consulted) */ public AclObjectIdentity getAclObjectParentIdentity(); + /** + * Access control lists in this package are based on bit masking. The integer value of the bit mask can be + * obtained from this method. + * + * @return the bit mask applicable to this ACL entry (zero indicates a bit mask where no permissions have been + * granted) + */ + public int getMask(); + + /** + * A domain object instance will usually have multiple BasicAclEntrys. Each separate + * BasicAclEntry applies to a particular "recipient". Typical examples of recipients include (but do + * not necessarily have to include) usernames, role names, complex granted authorities etc.

It is + * essential that only one BasicAclEntry exists for a given recipient. Otherwise conflicts as to + * the mask that should apply to a given recipient will occur.

+ *

This method indicates which recipient this BasicAclEntry applies to. The returned + * object type will vary depending on the type of recipient. For instance, it might be a String + * containing a username, or a GrantedAuthorityImpl containing a complex granted authority that is + * being granted the permissions contained in this access control entry. The {@link EffectiveAclsResolver} and + * {@link BasicAclProvider#getAcls(Object, Authentication)} can process the different recipient types and return + * only those that apply to a specified Authentication object.

+ * + * @return the recipient of this access control list entry (never null) + */ + public Object getRecipient(); + + /** + * Determine if the mask of this entry includes this permission or not + * + * @param permissionToCheck + * + * @return if the entry's mask includes this permission + */ + public boolean isPermitted(int permissionToCheck); + + /** + * This setter should only be used by DAO implementations. + * + * @param aclObjectIdentity an object which can be used to uniquely identify the domain object instance subject of + * this ACL entry + */ + public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity); + + /** + * This setter should only be used by DAO implementations. + * + * @param aclObjectParentIdentity an object which represents the parent of the domain object instance subject of + * this ACL entry, or null if either the domain object instance has no parent or its parent + * should be not used to compute an inheritance hierarchy + */ + public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity); + /** * This setter should only be used by DAO implementations. * @@ -76,59 +105,11 @@ public interface BasicAclEntry extends AclEntry { */ public void setMask(int mask); - /** - * Access control lists in this package are based on bit masking. The - * integer value of the bit mask can be obtained from this method. - * - * @return the bit mask applicable to this ACL entry (zero indicates a bit - * mask where no permissions have been granted) - */ - public int getMask(); - /** * This setter should only be used by DAO implementations. * - * @param recipient a representation of the recipient of this ACL entry - * that makes sense to an EffectiveAclsResolver - * implementation + * @param recipient a representation of the recipient of this ACL entry that makes sense to an + * EffectiveAclsResolver implementation */ public void setRecipient(Object recipient); - - /** - * A domain object instance will usually have multiple - * BasicAclEntrys. Each separate BasicAclEntry - * applies to a particular "recipient". Typical examples of recipients - * include (but do not necessarily have to include) usernames, role names, - * complex granted authorities etc. - * - *

- * It is essential that only one BasicAclEntry exists for a - * given recipient. Otherwise conflicts as to the mask that should - * apply to a given recipient will occur. - *

- * - *

- * This method indicates which recipient this BasicAclEntry - * applies to. The returned object type will vary depending on the type of - * recipient. For instance, it might be a String containing a - * username, or a GrantedAuthorityImpl containing a complex - * granted authority that is being granted the permissions contained in - * this access control entry. The {@link EffectiveAclsResolver} and {@link - * BasicAclProvider#getAcls(Object, Authentication)} can process the - * different recipient types and return only those that apply to a - * specified Authentication object. - *

- * - * @return the recipient of this access control list entry (never - * null) - */ - public Object getRecipient(); - - /** - * Determine if the mask of this entry includes this permission or not - * - * @param permissionToCheck - * @return if the entry's mask includes this permission - */ - public boolean isPermitted(int permissionToCheck); } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java index 1302d45996..2bdd862b32 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclEntryCache.java @@ -31,37 +31,29 @@ package org.acegisecurity.acl.basic; * @version $Id$ */ public interface BasicAclEntryCache { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains an array of {@link BasicAclEntry}s from the cache. * * @param aclObjectIdentity which should be obtained from the cache * - * @return any applicable BasicAclEntrys (no - * nulls are permitted in the returned array) or - * null if the object identity could not be found or - * if the cache entry has expired + * @return any applicable BasicAclEntrys (no nulls are permitted in the returned array) + * or null if the object identity could not be found or if the cache entry has expired */ - public BasicAclEntry[] getEntriesFromCache( - AclObjectIdentity aclObjectIdentity); + public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity); /** - * Places an array of {@link BasicAclEntry}s in the cache. - * - *

- * No nulls are allowed in the passed array. If any - * null is passed, the implementation may throw an exception. - *

+ * Places an array of {@link BasicAclEntry}s in the cache.

No nulls are allowed in the + * passed array. If any null is passed, the implementation may throw an exception.

* - * @param basicAclEntry the ACL entries to cache (the key will be extracted - * from the {@link BasicAclEntry#getAclObjectIdentity()} method + * @param basicAclEntry the ACL entries to cache (the key will be extracted from the {@link + * BasicAclEntry#getAclObjectIdentity()} method */ public void putEntriesInCache(BasicAclEntry[] basicAclEntry); /** - * Removes all ACL entries related to an {@link AclObjectIdentity} from the - * cache. + * Removes all ACL entries related to an {@link AclObjectIdentity} from the cache. * * @param aclObjectIdentity which should be removed from the cache */ diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclExtendedDao.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclExtendedDao.java index 67fd6ff0f9..218a7ada98 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclExtendedDao.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclExtendedDao.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.acl.basic; import org.springframework.dao.DataAccessException; + /** * Represents a more extensive data access object * for {@link BasicAclEntry}s. @@ -30,35 +31,42 @@ import org.springframework.dao.DataAccessException; * @version $Id$ */ public interface BasicAclExtendedDao extends BasicAclDao { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void create(BasicAclEntry basicAclEntry) throws DataAccessException; - - /** - * Deletes all entries associated with the - * specified AclObjectIdentity. - * - * @param aclObjectIdentity to delete, including any BasicAclEntrys - */ - public void delete(AclObjectIdentity aclObjectIdentity) throws DataAccessException; - - /** - * Deletes the BasicAclEntry associated with the specified - * AclObjectIdentity and recipient Object. - * - * @param aclObjectIdentity to delete - * @param recipient to delete - */ - public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) throws DataAccessException; - - /** - * Changes the permission mask assigned to the BasicAclEntry - * associated with the specified - * AclObjectIdentity and recipient Object. - * - * @param aclObjectIdentity to locate the relevant BasicAclEntry - * @param recipient to locate the relevant BasicAclEntry - * @param newMask indicating the new permission - */ - public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) throws DataAccessException; + /** + * Changes the permission mask assigned to the BasicAclEntry associated with the specified + * AclObjectIdentity and recipient Object. + * + * @param aclObjectIdentity to locate the relevant BasicAclEntry + * @param recipient to locate the relevant BasicAclEntry + * @param newMask indicating the new permission + * + * @throws DataAccessException DOCUMENT ME! + */ + public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) + throws DataAccessException; + + public void create(BasicAclEntry basicAclEntry) throws DataAccessException; + + /** + * Deletes all entries associated with the specified AclObjectIdentity. + * + * @param aclObjectIdentity to delete, including any BasicAclEntrys + * + * @throws DataAccessException DOCUMENT ME! + */ + public void delete(AclObjectIdentity aclObjectIdentity) + throws DataAccessException; + + /** + * Deletes the BasicAclEntry associated with the specified AclObjectIdentity and + * recipient Object. + * + * @param aclObjectIdentity to delete + * @param recipient to delete + * + * @throws DataAccessException DOCUMENT ME! + */ + public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) + throws DataAccessException; } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java index 1f643f923e..ccbf7e3c9b 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.acl.basic; import org.acegisecurity.Authentication; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclProvider; import org.acegisecurity.acl.basic.cache.NullAclEntryCache; @@ -24,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.lang.reflect.Constructor; @@ -34,70 +36,59 @@ import java.util.Map; /** - *

- * Retrieves access control lists (ACL) entries for domain object instances - * from a data access object (DAO). - *

- * - *

- * This implementation will provide ACL lookup services for any object that it - * can determine the {@link AclObjectIdentity} for by calling the {@link - * #obtainIdentity(Object)} method. Subclasses can override this method if - * they only want the BasicAclProvider responding to particular - * domain object instances. - *

- * - *

- * BasicAclProvider will walk an inheritance hierarchy if a - * BasicAclEntry returned by the DAO indicates it has a parent. - * NB: inheritance occurs at a domain instance object level. It does - * not occur at an ACL recipient level. This means - * allBasicAclEntrys for a given domain instance object - * must have the same parent identity, or - * allBasicAclEntrys must have null as their - * parent identity. - *

- * - *

- * A cache should be used. This is provided by the {@link BasicAclEntryCache}. - * BasicAclProvider by default is setup to use the {@link - * NullAclEntryCache}, which performs no caching. - *

- * - *

- * To implement the {@link #getAcls(Object, Authentication)} method, - * BasicAclProvider requires a {@link EffectiveAclsResolver} to - * be configured against it. By default the {@link - * GrantedAuthorityEffectiveAclsResolver} is used. - *

+ *

Retrieves access control lists (ACL) entries for domain object instances from a data access object (DAO).

+ *

This implementation will provide ACL lookup services for any object that it can determine the {@link + * AclObjectIdentity} for by calling the {@link #obtainIdentity(Object)} method. Subclasses can override this method + * if they only want the BasicAclProvider responding to particular domain object instances.

+ *

BasicAclProvider will walk an inheritance hierarchy if a BasicAclEntry returned by + * the DAO indicates it has a parent. NB: inheritance occurs at a domain instance object level. It does not + * occur at an ACL recipient level. This means allBasicAclEntrys for a given domain instance + * object must have the same parent identity, or allBasicAclEntrys must have + * null as their parent identity.

+ *

A cache should be used. This is provided by the {@link BasicAclEntryCache}. BasicAclProvider by + * default is setup to use the {@link NullAclEntryCache}, which performs no caching.

+ *

To implement the {@link #getAcls(Object, Authentication)} method, BasicAclProvider requires a + * {@link EffectiveAclsResolver} to be configured against it. By default the {@link + * GrantedAuthorityEffectiveAclsResolver} is used.

* * @author Ben Alex * @version $Id$ */ public class BasicAclProvider implements AclProvider, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(BasicAclProvider.class); - /** - * Marker added to the cache to indicate an AclObjectIdentity has no - * corresponding BasicAclEntry[]s - */ + /** Marker added to the cache to indicate an AclObjectIdentity has no corresponding BasicAclEntry[]s */ private static String RECIPIENT_FOR_CACHE_EMPTY = "RESERVED_RECIPIENT_NOBODY"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - /** - * Must be set to an appropriate data access object. Defaults to - * null. - */ + /** Must be set to an appropriate data access object. Defaults to null. */ private BasicAclDao basicAclDao; private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache(); private Class defaultAclObjectIdentityClass = NamedEntityObjectIdentity.class; private Class restrictSupportToClass = null; private EffectiveAclsResolver effectiveAclsResolver = new GrantedAuthorityEffectiveAclsResolver(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() { + Assert.notNull(basicAclDao, "basicAclDao required"); + Assert.notNull(basicAclEntryCache, "basicAclEntryCache required"); + Assert.notNull(basicAclEntryCache, "basicAclEntryCache required"); + Assert.notNull(effectiveAclsResolver, "effectiveAclsResolver required"); + Assert.notNull(defaultAclObjectIdentityClass, "defaultAclObjectIdentityClass required"); + Assert.isTrue(AclObjectIdentity.class.isAssignableFrom(this.defaultAclObjectIdentityClass), + "defaultAclObjectIdentityClass must implement AclObjectIdentity"); + + try { + Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class}); + } catch (NoSuchMethodException nsme) { + throw new IllegalArgumentException( + "defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!"); + } + } public AclEntry[] getAcls(Object domainInstance) { Map map = new HashMap(); @@ -120,15 +111,13 @@ public class BasicAclProvider implements AclProvider, InitializingBean { // Add the leaf objects to the Map, keyed on recipient for (int i = 0; i < instanceAclEntries.length; i++) { if (logger.isDebugEnabled()) { - logger.debug("Explicit add: " - + instanceAclEntries[i].toString()); + logger.debug("Explicit add: " + instanceAclEntries[i].toString()); } map.put(instanceAclEntries[i].getRecipient(), instanceAclEntries[i]); } - AclObjectIdentity parent = instanceAclEntries[0] - .getAclObjectParentIdentity(); + AclObjectIdentity parent = instanceAclEntries[0].getAclObjectParentIdentity(); while (parent != null) { BasicAclEntry[] parentAclEntries = lookup(parent); @@ -150,16 +139,13 @@ public class BasicAclProvider implements AclProvider, InitializingBean { for (int i = 0; i < parentAclEntries.length; i++) { if (!map.containsKey(parentAclEntries[i].getRecipient())) { if (logger.isDebugEnabled()) { - logger.debug("Added parent to map: " - + parentAclEntries[i].toString()); + logger.debug("Added parent to map: " + parentAclEntries[i].toString()); } - map.put(parentAclEntries[i].getRecipient(), - parentAclEntries[i]); + map.put(parentAclEntries[i].getRecipient(), parentAclEntries[i]); } else { if (logger.isDebugEnabled()) { - logger.debug("Did NOT add parent to map: " - + parentAclEntries[i].toString()); + logger.debug("Did NOT add parent to map: " + parentAclEntries[i].toString()); } } } @@ -170,211 +156,35 @@ public class BasicAclProvider implements AclProvider, InitializingBean { Collection collection = map.values(); - return (AclEntry[]) collection.toArray(new AclEntry[]{}); + return (AclEntry[]) collection.toArray(new AclEntry[] {}); } - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication) { + public AclEntry[] getAcls(Object domainInstance, Authentication authentication) { AclEntry[] allAcls = (AclEntry[]) this.getAcls(domainInstance); - return this.effectiveAclsResolver.resolveEffectiveAcls(allAcls, - authentication); - } - - public void setBasicAclDao(BasicAclDao basicAclDao) { - this.basicAclDao = basicAclDao; + return this.effectiveAclsResolver.resolveEffectiveAcls(allAcls, authentication); } public BasicAclDao getBasicAclDao() { return basicAclDao; } - public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) { - this.basicAclEntryCache = basicAclEntryCache; - } - public BasicAclEntryCache getBasicAclEntryCache() { return basicAclEntryCache; } - /** - * Allows selection of the AclObjectIdentity class that an - * attempt should be made to construct if the passed object does not - * implement AclObjectIdentityAware. - * - *

- * NB: Any defaultAclObjectIdentityClassmust provide a - * public constructor that accepts an Object. Otherwise it is - * not possible for the BasicAclProvider to try to create the - * AclObjectIdentity instance at runtime. - *

- * - * @param defaultAclObjectIdentityClass - */ - public void setDefaultAclObjectIdentityClass( - Class defaultAclObjectIdentityClass) { - this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass; - } - public Class getDefaultAclObjectIdentityClass() { return defaultAclObjectIdentityClass; } - public void setEffectiveAclsResolver( - EffectiveAclsResolver effectiveAclsResolver) { - this.effectiveAclsResolver = effectiveAclsResolver; - } - public EffectiveAclsResolver getEffectiveAclsResolver() { return effectiveAclsResolver; } - /** - * If set to a value other than null, the {@link - * #supports(Object)} method will only support the indicates class. - * This is useful if you wish to wire multiple - * BasicAclProviders in a list of - * AclProviderManager.providers but only have particular - * instances respond to particular domain object types. - * - * @param restrictSupportToClass the class to restrict this - * BasicAclProvider to service request for, or - * null (the default) if the - * BasicAclProvider should respond to every class - * presented - */ - public void setRestrictSupportToClass(Class restrictSupportToClass) { - this.restrictSupportToClass = restrictSupportToClass; - } - public Class getRestrictSupportToClass() { return restrictSupportToClass; } - public void afterPropertiesSet() { - Assert.notNull(basicAclDao, "basicAclDao required"); - Assert.notNull(basicAclEntryCache, "basicAclEntryCache required"); - Assert.notNull(basicAclEntryCache, "basicAclEntryCache required"); - Assert.notNull(effectiveAclsResolver, "effectiveAclsResolver required"); - Assert.notNull(defaultAclObjectIdentityClass, "defaultAclObjectIdentityClass required"); - Assert.isTrue(AclObjectIdentity.class.isAssignableFrom(this.defaultAclObjectIdentityClass), - "defaultAclObjectIdentityClass must implement AclObjectIdentity"); - - try { - Constructor constructor = defaultAclObjectIdentityClass - .getConstructor(new Class[]{Object.class}); - } catch (NoSuchMethodException nsme) { - throw new IllegalArgumentException("defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!"); - } - } - - /** - * Indicates support for the passed object. - * - *

- * An object will only be supported if it (i) is allowed to be supported as - * defined by the {@link #setRestrictSupportToClass(Class)} method, - * and (ii) if an AclObjectIdentity is returned by - * {@link #obtainIdentity(Object)} for that object. - *

- * - * @param domainInstance the instance to check - * - * @return true if this provider supports the passed object, - * false otherwise - */ - public boolean supports(Object domainInstance) { - if (domainInstance == null) { - if (logger.isDebugEnabled()) { - logger.debug("domainInstance is null"); - } - - return false; - } - - if ((restrictSupportToClass != null) - && !restrictSupportToClass.isAssignableFrom( - domainInstance.getClass())) { - if (logger.isDebugEnabled()) { - logger.debug("domainInstance not instance of " - + restrictSupportToClass); - } - - return false; - } - - if (obtainIdentity(domainInstance) == null) { - if (logger.isDebugEnabled()) { - logger.debug("obtainIdentity returned null"); - } - - return false; - } else { - if (logger.isDebugEnabled()) { - logger.debug("obtainIdentity returned " - + obtainIdentity(domainInstance)); - } - - return true; - } - } - - /** - * This method looks up the AclObjectIdentity of a passed - * domain object instance. - * - *

- * This implementation attempts to obtain the - * AclObjectIdentity via reflection inspection of the class - * for the {@link AclObjectIdentityAware} interface. If this fails, an - * attempt is made to construct a {@link - * #getDefaultAclObjectIdentityClass()} object by passing the domain - * instance object into its constructor. - *

- * - * @param domainInstance the domain object instance (never - * null) - * - * @return an ACL object identity, or null if one could not be - * obtained - */ - protected AclObjectIdentity obtainIdentity(Object domainInstance) { - if (domainInstance instanceof AclObjectIdentityAware) { - AclObjectIdentityAware aclObjectIdentityAware = (AclObjectIdentityAware) domainInstance; - - if (logger.isDebugEnabled()) { - logger.debug("domainInstance: " + domainInstance - + " cast to AclObjectIdentityAware"); - } - - return aclObjectIdentityAware.getAclObjectIdentity(); - } - - try { - Constructor constructor = defaultAclObjectIdentityClass - .getConstructor(new Class[] {Object.class}); - - if (logger.isDebugEnabled()) { - logger.debug("domainInstance: " + domainInstance - + " attempting to pass to constructor: " + constructor); - } - - return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance}); - } catch (Exception ex) { - if (logger.isDebugEnabled()) { - logger.debug("Error attempting construction of " - + defaultAclObjectIdentityClass + ": " + ex.getMessage(), ex); - - if (ex.getCause() != null) { - logger.debug("Cause: " + ex.getCause().getMessage(), - ex.getCause()); - } - } - - return null; - } - } - private BasicAclEntry[] lookup(AclObjectIdentity aclObjectIdentity) { BasicAclEntry[] result = basicAclEntryCache.getEntriesFromCache(aclObjectIdentity); @@ -389,8 +199,9 @@ public class BasicAclProvider implements AclProvider, InitializingBean { result = basicAclDao.getAcls(aclObjectIdentity); if (result == null) { - SimpleAclEntry[] emptyAclEntries = {new SimpleAclEntry(RECIPIENT_FOR_CACHE_EMPTY, - aclObjectIdentity, null, 0)}; + SimpleAclEntry[] emptyAclEntries = { + new SimpleAclEntry(RECIPIENT_FOR_CACHE_EMPTY, aclObjectIdentity, null, 0) + }; basicAclEntryCache.putEntriesInCache(emptyAclEntries); return null; @@ -400,4 +211,127 @@ public class BasicAclProvider implements AclProvider, InitializingBean { return result; } + + /** + * This method looks up the AclObjectIdentity of a passed domain object instance.

This + * implementation attempts to obtain the AclObjectIdentity via reflection inspection of the class for + * the {@link AclObjectIdentityAware} interface. If this fails, an attempt is made to construct a {@link + * #getDefaultAclObjectIdentityClass()} object by passing the domain instance object into its constructor.

+ * + * @param domainInstance the domain object instance (never null) + * + * @return an ACL object identity, or null if one could not be obtained + */ + protected AclObjectIdentity obtainIdentity(Object domainInstance) { + if (domainInstance instanceof AclObjectIdentityAware) { + AclObjectIdentityAware aclObjectIdentityAware = (AclObjectIdentityAware) domainInstance; + + if (logger.isDebugEnabled()) { + logger.debug("domainInstance: " + domainInstance + " cast to AclObjectIdentityAware"); + } + + return aclObjectIdentityAware.getAclObjectIdentity(); + } + + try { + Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class}); + + if (logger.isDebugEnabled()) { + logger.debug("domainInstance: " + domainInstance + " attempting to pass to constructor: " + constructor); + } + + return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance}); + } catch (Exception ex) { + if (logger.isDebugEnabled()) { + logger.debug("Error attempting construction of " + defaultAclObjectIdentityClass + ": " + + ex.getMessage(), ex); + + if (ex.getCause() != null) { + logger.debug("Cause: " + ex.getCause().getMessage(), ex.getCause()); + } + } + + return null; + } + } + + public void setBasicAclDao(BasicAclDao basicAclDao) { + this.basicAclDao = basicAclDao; + } + + public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) { + this.basicAclEntryCache = basicAclEntryCache; + } + + /** + * Allows selection of the AclObjectIdentity class that an attempt should be made to construct + * if the passed object does not implement AclObjectIdentityAware.

NB: Any + * defaultAclObjectIdentityClassmust provide a public constructor that accepts an + * Object. Otherwise it is not possible for the BasicAclProvider to try to create the + * AclObjectIdentity instance at runtime.

+ * + * @param defaultAclObjectIdentityClass + */ + public void setDefaultAclObjectIdentityClass(Class defaultAclObjectIdentityClass) { + this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass; + } + + public void setEffectiveAclsResolver(EffectiveAclsResolver effectiveAclsResolver) { + this.effectiveAclsResolver = effectiveAclsResolver; + } + + /** + * If set to a value other than null, the {@link #supports(Object)} method will only + * support the indicates class. This is useful if you wish to wire multiple BasicAclProviders in a + * list of AclProviderManager.providers but only have particular instances respond to particular + * domain object types. + * + * @param restrictSupportToClass the class to restrict this BasicAclProvider to service request for, + * or null (the default) if the BasicAclProvider should respond to every class + * presented + */ + public void setRestrictSupportToClass(Class restrictSupportToClass) { + this.restrictSupportToClass = restrictSupportToClass; + } + + /** + * Indicates support for the passed object.

An object will only be supported if it (i) is allowed to be + * supported as defined by the {@link #setRestrictSupportToClass(Class)} method, and (ii) if an + * AclObjectIdentity is returned by {@link #obtainIdentity(Object)} for that object.

+ * + * @param domainInstance the instance to check + * + * @return true if this provider supports the passed object, false otherwise + */ + public boolean supports(Object domainInstance) { + if (domainInstance == null) { + if (logger.isDebugEnabled()) { + logger.debug("domainInstance is null"); + } + + return false; + } + + if ((restrictSupportToClass != null) && !restrictSupportToClass.isAssignableFrom(domainInstance.getClass())) { + if (logger.isDebugEnabled()) { + logger.debug("domainInstance not instance of " + restrictSupportToClass); + } + + return false; + } + + if (obtainIdentity(domainInstance) == null) { + if (logger.isDebugEnabled()) { + logger.debug("obtainIdentity returned null"); + } + + return false; + } else { + if (logger.isDebugEnabled()) { + logger.debug("obtainIdentity returned " + obtainIdentity(domainInstance)); + } + + return true; + } + } } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/EffectiveAclsResolver.java b/core/src/main/java/org/acegisecurity/acl/basic/EffectiveAclsResolver.java index 4519130627..6e51e18909 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/EffectiveAclsResolver.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/EffectiveAclsResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.acl.basic; import org.acegisecurity.Authentication; + import org.acegisecurity.acl.AclEntry; @@ -45,21 +46,16 @@ import org.acegisecurity.acl.AclEntry; * @version $Id$ */ public interface EffectiveAclsResolver { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Determines the ACLs that apply to the presented - * Authentication object. + * Determines the ACLs that apply to the presented Authentication object. * * @param allAcls every ACL assigned to a domain object instance - * @param filteredBy the principal (populated with - * GrantedAuthoritys along with any other members that - * relate to role or group membership) that effective ACLs should - * be returned for + * @param filteredBy the principal (populated with GrantedAuthoritys along with any other members that + * relate to role or group membership) that effective ACLs should be returned for * - * @return the ACLs that apply to the presented principal, or - * null if there are none after filtering + * @return the ACLs that apply to the presented principal, or null if there are none after filtering */ - public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, - Authentication filteredBy); + public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy); } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolver.java b/core/src/main/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolver.java index e812f571e9..999964f98c 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolver.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ package org.acegisecurity.acl.basic; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.acl.AclEntry; + import org.acegisecurity.userdetails.UserDetails; import org.apache.commons.logging.Log; @@ -28,45 +30,29 @@ import java.util.Vector; /** - * Simple implementation of {@link EffectiveAclsResolver}. - * - *

- * This implementation does not need to understand the "recipient" types - * presented in a BasicAclEntry because it merely delegates to - * the detected {@link Authentication#getPrincipal()} or {@link - * Authentication#getAuthorities()}. The principal object or granted - * authorities object has its Object.equals(recipient) method - * called to make the decision as to whether the recipient in the - * BasicAclEntry is the same as the principal or granted - * authority. - *

- * - *

- * This class should prove an adequate ACLs resolver if you're using standard - * Acegi Security classes. This is because the typical - * Authentication token is - * UsernamePasswordAuthenticationToken, which for its - * principal is usually a String. The - * GrantedAuthorityImpl is typically used for granted - * authorities, which tests for equality based on a String. This - * means BasicAclDaos simply need to return a String - * to represent the recipient. If you use non-String objects, you - * will probably require an alternative EffectiveAclsResolver. - *

+ * Simple implementation of {@link EffectiveAclsResolver}.

This implementation does not need to understand the + * "recipient" types presented in a BasicAclEntry because it merely delegates to the detected {@link + * Authentication#getPrincipal()} or {@link Authentication#getAuthorities()}. The principal object or granted + * authorities object has its Object.equals(recipient) method called to make the decision as to whether + * the recipient in the BasicAclEntry is the same as the principal or granted authority.

+ *

This class should prove an adequate ACLs resolver if you're using standard Acegi Security classes. This is + * because the typical Authentication token is UsernamePasswordAuthenticationToken, which + * for its principal is usually a String. The GrantedAuthorityImpl is typically + * used for granted authorities, which tests for equality based on a String. This means + * BasicAclDaos simply need to return a String to represent the recipient. If you use + * non-String objects, you will probably require an alternative EffectiveAclsResolver.

* * @author Ben Alex * @version $Id$ */ -public class GrantedAuthorityEffectiveAclsResolver - implements EffectiveAclsResolver { - //~ Static fields/initializers ============================================= +public class GrantedAuthorityEffectiveAclsResolver implements EffectiveAclsResolver { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(GrantedAuthorityEffectiveAclsResolver.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, - Authentication filteredBy) { + public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy) { if ((allAcls == null) || (allAcls.length == 0)) { return null; } @@ -74,8 +60,7 @@ public class GrantedAuthorityEffectiveAclsResolver List list = new Vector(); if (logger.isDebugEnabled()) { - logger.debug("Locating AclEntry[]s (from set of " - + ((allAcls == null) ? 0 : allAcls.length) + logger.debug("Locating AclEntry[]s (from set of " + ((allAcls == null) ? 0 : allAcls.length) + ") that apply to Authentication: " + filteredBy); } @@ -84,26 +69,21 @@ public class GrantedAuthorityEffectiveAclsResolver continue; } - Object recipient = ((BasicAclEntry) allAcls[i]) - .getRecipient(); + Object recipient = ((BasicAclEntry) allAcls[i]).getRecipient(); // Allow the Authentication's getPrincipal to decide whether // the presented recipient is "equal" (allows BasicAclDaos to // return Strings rather than proper objects in simple cases) if (filteredBy.getPrincipal().equals(recipient)) { if (logger.isDebugEnabled()) { - logger.debug("Principal matches AclEntry recipient: " - + recipient); + logger.debug("Principal matches AclEntry recipient: " + recipient); } list.add(allAcls[i]); } else if (filteredBy.getPrincipal() instanceof UserDetails - && ((UserDetails) filteredBy.getPrincipal()).getUsername() - .equals(recipient)) { + && ((UserDetails) filteredBy.getPrincipal()).getUsername().equals(recipient)) { if (logger.isDebugEnabled()) { - logger.debug( - "Principal (from UserDetails) matches AclEntry recipient: " - + recipient); + logger.debug("Principal (from UserDetails) matches AclEntry recipient: " + recipient); } list.add(allAcls[i]); @@ -127,8 +107,7 @@ public class GrantedAuthorityEffectiveAclsResolver for (int k = 0; k < authorities.length; k++) { if (authorities[k].equals(recipient)) { if (logger.isDebugEnabled()) { - logger.debug("GrantedAuthority: " + authorities[k] - + " matches recipient: " + recipient); + logger.debug("GrantedAuthority: " + authorities[k] + " matches recipient: " + recipient); } list.add(allAcls[i]); @@ -140,15 +119,13 @@ public class GrantedAuthorityEffectiveAclsResolver // return null if appropriate (as per interface contract) if (list.size() > 0) { if (logger.isDebugEnabled()) { - logger.debug("Returning effective AclEntry array with " - + list.size() + " elements"); + logger.debug("Returning effective AclEntry array with " + list.size() + " elements"); } return (BasicAclEntry[]) list.toArray(new BasicAclEntry[] {}); } else { if (logger.isDebugEnabled()) { - logger.debug( - "Returning null AclEntry array as zero effective AclEntrys found"); + logger.debug("Returning null AclEntry array as zero effective AclEntrys found"); } return null; diff --git a/core/src/main/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentity.java b/core/src/main/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentity.java index 1266be39e1..dac671709b 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentity.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentity.java @@ -23,21 +23,16 @@ import java.lang.reflect.Method; /** - * Simple implementation of {@link AclObjectIdentity}. - * - *

- * Uses Strings to store the identity of the domain object - * instance. Also offers a constructor that uses reflection to build the - * identity information. - *

+ * Simple implementation of {@link AclObjectIdentity}.

Uses Strings to store the identity of the + * domain object instance. Also offers a constructor that uses reflection to build the identity information.

*/ public class NamedEntityObjectIdentity implements AclObjectIdentity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String classname; private String id; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NamedEntityObjectIdentity(String classname, String id) { Assert.hasText(classname, "classname required"); @@ -46,7 +41,7 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity { this.id = id; } - /** +/** * Creates the NamedEntityObjectIdentity based on the passed * object instance. The passed object must provide a getId() * method, otherwise an exception will be thrown. @@ -57,15 +52,13 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity { * @throws InvocationTargetException * @throws IllegalArgumentException */ - public NamedEntityObjectIdentity(Object object) - throws IllegalAccessException, InvocationTargetException { + public NamedEntityObjectIdentity(Object object) throws IllegalAccessException, InvocationTargetException { Assert.notNull(object, "object cannot be null"); this.classname = (getPackageName(object.getClass().getName()) == null) - ? ClassUtils.getShortName(object.getClass()) - : getPackageName(object.getClass().getName()) + "." - + ClassUtils.getShortName(object.getClass()); - + ? ClassUtils.getShortName(object.getClass()) + : (getPackageName(object.getClass().getName()) + "." + ClassUtils.getShortName(object.getClass())); + Class clazz = object.getClass(); try { @@ -78,15 +71,11 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity { } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Important so caching operates properly. - * - *

- * Considers an object of the same class equal if it has the same - * classname and id properties. - *

+ * Important so caching operates properly.

Considers an object of the same class equal if it has the same + * classname and id properties.

* * @param arg0 object to compare * @@ -103,8 +92,7 @@ public class NamedEntityObjectIdentity implements AclObjectIdentity { NamedEntityObjectIdentity other = (NamedEntityObjectIdentity) arg0; - if (this.getId().equals(other.getId()) - && this.getClassname().equals(other.getClassname())) { + if (this.getId().equals(other.getId()) && this.getClassname().equals(other.getClassname())) { return true; } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java b/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java index 6ff5e0d2bd..7fda017ae1 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.apache.commons.logging.LogFactory; * @version $Id$ */ public class SimpleAclEntry extends AbstractBasicAclEntry { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(SimpleAclEntry.class); @@ -39,18 +39,20 @@ public class SimpleAclEntry extends AbstractBasicAclEntry { public static final int DELETE = (int) Math.pow(2, 4); // Combinations of base permissions we permit - public static final int READ_WRITE_CREATE_DELETE = READ | WRITE | CREATE - | DELETE; + public static final int READ_WRITE_CREATE_DELETE = READ | WRITE | CREATE | DELETE; public static final int READ_WRITE_CREATE = READ | WRITE | CREATE; public static final int READ_WRITE = READ | WRITE; public static final int READ_WRITE_DELETE = READ | WRITE | DELETE; // Array required by the abstract superclass via getValidPermissions() - private static final int[] validPermissions = {NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE, READ_WRITE, READ_WRITE_DELETE}; + private static final int[] validPermissions = { + NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE, + READ_WRITE, READ_WRITE_DELETE + }; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Allows {@link BasicAclDao} implementations to construct this object * using newInstance(). * @@ -62,13 +64,12 @@ public class SimpleAclEntry extends AbstractBasicAclEntry { super(); } - public SimpleAclEntry(Object recipient, - AclObjectIdentity aclObjectIdentity, + public SimpleAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity, AclObjectIdentity aclObjectParentIdentity, int mask) { super(recipient, aclObjectIdentity, aclObjectParentIdentity, mask); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public int[] getValidPermissions() { return validPermissions; diff --git a/core/src/main/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolder.java b/core/src/main/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolder.java index ed352ed8d9..ba3a0df832 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolder.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,36 +17,28 @@ package org.acegisecurity.acl.basic.cache; import org.acegisecurity.acl.basic.BasicAclEntry; -import java.io.Serializable; - import org.springframework.util.Assert; +import java.io.Serializable; + /** - * Used by {@link EhCacheBasedAclEntryCache} to store the array of - * BasicAclEntrys in the cache. - * - *

- * This is necessary because caches store a single object per key, not an - * array. - *

- * - *

- * This class uses value object semantics. ie: construction-based - * initialisation without any setters for the properties. - *

+ * Used by {@link EhCacheBasedAclEntryCache} to store the array of BasicAclEntrys in the cache.

This + * is necessary because caches store a single object per key, not an array.

+ *

This class uses value object semantics. ie: construction-based initialisation without any setters for the + * properties.

* * @author Ben Alex * @version $Id$ */ public class BasicAclEntryHolder implements Serializable { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private BasicAclEntry[] basicAclEntries; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs the BasicAclEntryHolder. * * @param aclEntries to cache (any nulls will cause an @@ -68,7 +60,7 @@ public class BasicAclEntryHolder implements Serializable { this.basicAclEntries = aclEntries; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public BasicAclEntry[] getBasicAclEntries() { return basicAclEntries; diff --git a/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java index dbc2996dc6..868c3165bc 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java @@ -40,17 +40,16 @@ import org.springframework.util.Assert; * @author Ben Alex * @version $Id$ */ -public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, - InitializingBean { - //~ Static fields/initializers ============================================= +public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Cache cache; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(cache, "cache mandatory"); @@ -60,15 +59,13 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, return cache; } - public BasicAclEntry[] getEntriesFromCache( - AclObjectIdentity aclObjectIdentity) { + public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) { Element element = null; try { element = cache.get(aclObjectIdentity); } catch (CacheException cacheException) { - throw new DataRetrievalFailureException("Cache failure: " - + cacheException.getMessage()); + throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage()); } // Return null if cache element has expired or not found @@ -81,8 +78,7 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, } if (logger.isDebugEnabled()) { - logger.debug("Cache hit: " + (element != null) + "; object: " - + aclObjectIdentity); + logger.debug("Cache hit: " + (element != null) + "; object: " + aclObjectIdentity); } BasicAclEntryHolder holder = (BasicAclEntryHolder) element.getValue(); @@ -92,8 +88,7 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, public void putEntriesInCache(BasicAclEntry[] basicAclEntry) { BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry); - Element element = new Element(basicAclEntry[0].getAclObjectIdentity(), - holder); + Element element = new Element(basicAclEntry[0].getAclObjectIdentity(), holder); if (logger.isDebugEnabled()) { logger.debug("Cache put: " + element.getKey()); diff --git a/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java b/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java index 50f8b09356..494c61cc7c 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/cache/NullAclEntryCache.java @@ -21,29 +21,23 @@ import org.acegisecurity.acl.basic.BasicAclEntryCache; /** - * Does not perform any caching. - * - *

- * Do not use in production settings, as ACL queries are likely to be - * extensive. - *

+ * Does not perform any caching.

Do not use in production settings, as ACL queries are likely to be + * extensive.

* * @author Ben Alex * @version $Id$ */ public class NullAclEntryCache implements BasicAclEntryCache { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * As nothing ever stored in the cache, will always return - * null. + * As nothing ever stored in the cache, will always return null. * * @param aclObjectIdentity ignored * * @return always null */ - public BasicAclEntry[] getEntriesFromCache( - AclObjectIdentity aclObjectIdentity) { + public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) { return null; } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java index 29095fe627..5095c1227c 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java @@ -42,56 +42,48 @@ import javax.sql.DataSource; /** - *

- * Retrieves ACL details from a JDBC location. - *

- * - *

- * A default database structure is assumed. This may be overridden by setting - * the default query strings to use. If this does not provide enough - * flexibility, another strategy would be to subclass this class and override - * the {@link MappingSqlQuery} instance used, via the {@link - * #initMappingSqlQueries()} extension point. - *

+ *

Retrieves ACL details from a JDBC location.

+ *

A default database structure is assumed. This may be overridden by setting the default query strings to use. + * If this does not provide enough flexibility, another strategy would be to subclass this class and override the + * {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.

*/ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___"; public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY = "SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?"; public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?"; private static final Log logger = LogFactory.getLog(JdbcDaoImpl.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MappingSqlQuery aclsByObjectIdentity; protected MappingSqlQuery objectProperties; private String aclsByObjectIdentityQuery; private String objectPropertiesQuery; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcDaoImpl() { aclsByObjectIdentityQuery = DEF_ACLS_BY_OBJECT_IDENTITY_QUERY; objectPropertiesQuery = DEF_OBJECT_PROPERTIES_QUERY; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Responsible for covering a AclObjectIdentity to a - * String that can be located in the RDBMS. + * Responsible for covering a AclObjectIdentity to a String that can be located + * in the RDBMS. * * @param aclObjectIdentity to locate * * @return the object identity as a String */ - protected String convertAclObjectIdentityToString( - AclObjectIdentity aclObjectIdentity) { + protected String convertAclObjectIdentityToString(AclObjectIdentity aclObjectIdentity) { // Ensure we can process this type of AclObjectIdentity Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity, - "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: " - + aclObjectIdentity + ")"); + "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: " + aclObjectIdentity + + ")"); NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity; @@ -100,37 +92,26 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } /** - * Constructs an individual BasicAclEntry from the passed - * AclDetailsHolders. - * - *

- * Guarantees to never return null (exceptions are thrown in - * the event of any issues). - *

+ * Constructs an individual BasicAclEntry from the passed AclDetailsHolders.

Guarantees + * to never return null (exceptions are thrown in the event of any issues).

* - * @param propertiesInformation mandatory information about which instance - * to create, the object identity, and the parent object identity - * (null or empty Strings prohibited for + * @param propertiesInformation mandatory information about which instance to create, the object identity, and the + * parent object identity (null or empty Strings prohibited for * aclClass and aclObjectIdentity - * @param aclInformation optional information about the individual ACL - * record (if null only an "inheritence marker" - * instance is returned which will include a recipient of {@link - * #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not - * null, it is prohibited to present null - * or an empty String for recipient) + * @param aclInformation optional information about the individual ACL record (if null only an + * "inheritence marker" instance is returned which will include a recipient of {@link + * #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not null, it is prohibited to present + * null or an empty String for recipient) * * @return a fully populated instance suitable for use by external objects * - * @throws IllegalArgumentException if the indicated ACL class could not be - * created + * @throws IllegalArgumentException if the indicated ACL class could not be created */ - private BasicAclEntry createBasicAclEntry( - AclDetailsHolder propertiesInformation, AclDetailsHolder aclInformation) { + private BasicAclEntry createBasicAclEntry(AclDetailsHolder propertiesInformation, AclDetailsHolder aclInformation) { BasicAclEntry entry; try { - entry = (BasicAclEntry) propertiesInformation.getAclClass() - .newInstance(); + entry = (BasicAclEntry) propertiesInformation.getAclClass().newInstance(); } catch (InstantiationException ie) { throw new IllegalArgumentException(ie.getMessage()); } catch (IllegalAccessException iae) { @@ -138,8 +119,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } entry.setAclObjectIdentity(propertiesInformation.getAclObjectIdentity()); - entry.setAclObjectParentIdentity(propertiesInformation - .getAclObjectParentIdentity()); + entry.setAclObjectParentIdentity(propertiesInformation.getAclObjectParentIdentity()); if (aclInformation == null) { // this is an inheritence marker instance only @@ -155,30 +135,19 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } /** - * Returns the ACLs associated with the requested - * AclObjectIdentity. - * - *

- * The {@link BasicAclEntry}s returned by this method will have - * String-based recipients. This will not be a problem if you - * are using the GrantedAuthorityEffectiveAclsResolver, which - * is the default configured against BasicAclProvider. - *

- * - *

- * This method will only return ACLs for requests where the - * AclObjectIdentity is of type {@link - * NamedEntityObjectIdentity}. Of course, you can subclass or replace this - * class and support your own custom AclObjectIdentity types. - *

+ * Returns the ACLs associated with the requested AclObjectIdentity.

The {@link + * BasicAclEntry}s returned by this method will have String-based recipients. This will not be a + * problem if you are using the GrantedAuthorityEffectiveAclsResolver, which is the default + * configured against BasicAclProvider.

+ *

This method will only return ACLs for requests where the AclObjectIdentity is of type + * {@link NamedEntityObjectIdentity}. Of course, you can subclass or replace this class and support your own + * custom AclObjectIdentity types.

* - * @param aclObjectIdentity for which ACL information is required (cannot - * be null and must be an instance of - * NamedEntityObjectIdentity) + * @param aclObjectIdentity for which ACL information is required (cannot be null and must be an + * instance of NamedEntityObjectIdentity) * - * @return the ACLs that apply (without any nulls inside the - * array), or null if not found or if an incompatible - * AclObjectIdentity was requested + * @return the ACLs that apply (without any nulls inside the array), or null if not found + * or if an incompatible AclObjectIdentity was requested */ public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) { String aclObjectIdentityString; @@ -201,21 +170,18 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0); // Lookup the object's ACLs from RDBMS (guaranteed no nulls) - List acls = aclsByObjectIdentity.execute(propertiesInformation - .getForeignKeyId()); + List acls = aclsByObjectIdentity.execute(propertiesInformation.getForeignKeyId()); if (acls.size() == 0) { // return merely an inheritence marker (as we know about the object but it has no related ACLs) - return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation, - null)}; + return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation, null)}; } else { // return the individual ACL instances AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {}); List toReturnAcls = new Vector(); for (int i = 0; i < aclHolders.length; i++) { - toReturnAcls.add(createBasicAclEntry(propertiesInformation, - aclHolders[i])); + toReturnAcls.add(createBasicAclEntry(propertiesInformation, aclHolders[i])); } return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {}); @@ -239,26 +205,22 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } /** - * Extension point to allow other MappingSqlQuery objects to be substituted - * in a subclass + * Extension point to allow other MappingSqlQuery objects to be substituted in a subclass */ protected void initMappingSqlQueries() { setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource())); setObjectProperties(new ObjectPropertiesMapping(getDataSource())); } - public void setAclsByObjectIdentity( - MappingSqlQuery aclsByObjectIdentityQuery) { + public void setAclsByObjectIdentity(MappingSqlQuery aclsByObjectIdentityQuery) { this.aclsByObjectIdentity = aclsByObjectIdentityQuery; } /** - * Allows the default query string used to retrieve ACLs based on object - * identity to be overriden, if default table or column names need to be - * changed. The default query is {@link - * #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure - * that all returned columns are mapped back to the same column names as - * in the default query. + * Allows the default query string used to retrieve ACLs based on object identity to be overriden, if + * default table or column names need to be changed. The default query is {@link + * #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure that all returned columns are mapped + * back to the same column names as in the default query. * * @param queryString The query string to set */ @@ -274,22 +236,14 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { objectPropertiesQuery = queryString; } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** - * Used to hold details of a domain object instance's properties, or an - * individual ACL entry. - * - *

- * Not all properties will be set. The actual properties set will depend on - * which MappingSqlQuery creates the object. - *

- * - *

- * Does not enforce nulls or empty Strings as - * this is performed by the MappingSqlQuery objects (or - * preferably the backend RDBMS via schema constraints). - *

+ * Used to hold details of a domain object instance's properties, or an individual ACL entry.

Not all + * properties will be set. The actual properties set will depend on which MappingSqlQuery creates the + * object.

+ *

Does not enforce nulls or empty Strings as this is performed by the + * MappingSqlQuery objects (or preferably the backend RDBMS via schema constraints).

*/ protected final class AclDetailsHolder { private AclObjectIdentity aclObjectIdentity; @@ -299,7 +253,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { private int mask; private long foreignKeyId; - /** +/** * Record details of an individual ACL entry (usually from the * ACL_PERMISSION table) * @@ -311,7 +265,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { this.mask = mask; } - /** +/** * Record details of a domain object instance's properties (usually * from the ACL_OBJECT_IDENTITY table) * @@ -326,8 +280,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { * created for each individual ACL entry (or an inheritence * "holder" class if there are no ACL entries) */ - public AclDetailsHolder(long foreignKeyId, - AclObjectIdentity aclObjectIdentity, + public AclDetailsHolder(long foreignKeyId, AclObjectIdentity aclObjectIdentity, AclObjectIdentity aclObjectParentIdentity, Class aclClass) { this.foreignKeyId = foreignKeyId; this.aclObjectIdentity = aclObjectIdentity; @@ -361,21 +314,11 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } /** - * Query object to look up individual ACL entries. - * - *

- * Returns the generic AclDetailsHolder object. - *

- * - *

- * Guarantees to never return null (exceptions are thrown in - * the event of any issues). - *

- * - *

- * The executed SQL requires the following information be made available - * from the indicated placeholders: 1. RECIPIENT, 2. MASK. - *

+ * Query object to look up individual ACL entries.

Returns the generic AclDetailsHolder + * object.

+ *

Guarantees to never return null (exceptions are thrown in the event of any issues).

+ *

The executed SQL requires the following information be made available from the indicated + * placeholders: 1. RECIPIENT, 2. MASK.

*/ protected class AclsByObjectIdentityMapping extends MappingSqlQuery { protected AclsByObjectIdentityMapping(DataSource ds) { @@ -395,22 +338,11 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { } /** - * Query object to look up properties for an object identity. - * - *

- * Returns the generic AclDetailsHolder object. - *

- * - *

- * Guarantees to never return null (exceptions are thrown in - * the event of any issues). - *

- * - *

- * The executed SQL requires the following information be made available - * from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. - * ACL_CLASS and 4. PARENT_OBJECT_IDENTITY. - *

+ * Query object to look up properties for an object identity.

Returns the generic + * AclDetailsHolder object.

+ *

Guarantees to never return null (exceptions are thrown in the event of any issues).

+ *

The executed SQL requires the following information be made available from the indicated + * placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.

*/ protected class ObjectPropertiesMapping extends MappingSqlQuery { protected ObjectPropertiesMapping(DataSource ds) { @@ -440,8 +372,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { String parentObjectIdentity = rs.getString(4); // optional Assert.hasText(objectIdentity, "required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty"); - Assert.hasText(aclClass, - "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty"); + Assert.hasText(aclClass, "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty"); Class aclClazz; @@ -451,8 +382,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { throw new IllegalArgumentException(cnf.getMessage()); } - return new AclDetailsHolder(id, buildIdentity(objectIdentity), - buildIdentity(parentObjectIdentity), aclClazz); + return new AclDetailsHolder(id, buildIdentity(objectIdentity), buildIdentity(parentObjectIdentity), aclClazz); } } } diff --git a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java index c4af3bade6..219cf44465 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImpl.java @@ -47,36 +47,20 @@ import javax.sql.DataSource; /** - *

- * Extension of the base {@link JdbcDaoImpl}, which implements {@link - * BasicAclExtendedDao}. - *

- * - *

- * A default database structure is assumed. This may be overridden by setting - * the default query strings to use. - *

- * - *

- * If you are using a cache with BasicAclProvider, you should - * specify that cache via {@link #setBasicAclEntryCache(BasicAclEntryCache)}. - * This will cause cache evictions (removals) to take place whenever a DAO - * mutator method is called. - *

- * - *

- * This implementation works with String based recipients and - * {@link org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The - * latter can be changed by overriding {@link - * #convertAclObjectIdentityToString(AclObjectIdentity)}. - *

+ *

Extension of the base {@link JdbcDaoImpl}, which implements {@link BasicAclExtendedDao}.

+ *

A default database structure is assumed. This may be overridden by setting the default query strings to use.

+ *

If you are using a cache with BasicAclProvider, you should specify that cache via {@link + * #setBasicAclEntryCache(BasicAclEntryCache)}. This will cause cache evictions (removals) to take place whenever a + * DAO mutator method is called.

+ *

This implementation works with String based recipients and {@link + * org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The latter can be changed by overriding {@link + * #convertAclObjectIdentityToString(AclObjectIdentity)}.

* * @author Ben Alex * @version $Id$ */ -public class JdbcExtendedDaoImpl extends JdbcDaoImpl - implements BasicAclExtendedDao { - //~ Static fields/initializers ============================================= +public class JdbcExtendedDaoImpl extends JdbcDaoImpl implements BasicAclExtendedDao { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class); public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT = "DELETE FROM acl_object_identity WHERE id = ?"; @@ -86,7 +70,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT = "UPDATE acl_permission SET mask = ? WHERE id = ?"; public static final String DEF_LOOKUP_PERMISSION_ID_QUERY = "SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclObjectIdentityDelete aclObjectIdentityDelete; private AclObjectIdentityInsert aclObjectIdentityInsert; @@ -102,7 +86,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl private String aclPermissionUpdateStatement; private String lookupPermissionIdQuery; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcExtendedDaoImpl() { aclObjectIdentityDeleteStatement = DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT; @@ -113,22 +97,20 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl lookupPermissionIdQuery = DEF_LOOKUP_PERMISSION_ID_QUERY; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void changeMask(AclObjectIdentity aclObjectIdentity, - Object recipient, Integer newMask) throws DataAccessException { + public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) + throws DataAccessException { basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity); // Retrieve acl_object_identity record details AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Retrieve applicable acl_permission.id - long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), - recipient.toString()); + long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), recipient.toString()); if (permissionId == -1) { - throw new DataRetrievalFailureException( - "Could not locate existing acl_permission for aclObjectIdentity: " + throw new DataRetrievalFailureException("Could not locate existing acl_permission for aclObjectIdentity: " + aclObjectIdentity + ", recipient: " + recipient.toString()); } @@ -147,59 +129,48 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl } // Retrieve acl_object_identity record details - AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry - .getAclObjectIdentity()); + AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry.getAclObjectIdentity()); // Ensure there isn't an existing record for this recipient - long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), - basicAclEntry.getRecipient()); + long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), basicAclEntry.getRecipient()); if (permissionId != -1) { - throw new DataIntegrityViolationException("Recipient '" - + basicAclEntry.getRecipient() - + "' already exists for aclObjectIdentity ID " - + aclDetailsHolder.getForeignKeyId() + " (permission ID " + ")"); + throw new DataIntegrityViolationException("Recipient '" + basicAclEntry.getRecipient() + + "' already exists for aclObjectIdentity ID " + aclDetailsHolder.getForeignKeyId() + + " (permission ID " + ")"); } // Create acl_permission aclPermissionInsert.insert(new Long(aclDetailsHolder.getForeignKeyId()), - basicAclEntry.getRecipient().toString(), - new Integer(basicAclEntry.getMask())); + basicAclEntry.getRecipient().toString(), new Integer(basicAclEntry.getMask())); } /** - * Convenience method that creates an acl_object_identity record if - * required. + * Convenience method that creates an acl_object_identity record if required. * - * @param basicAclEntry containing the AclObjectIdentity to - * create + * @param basicAclEntry containing the AclObjectIdentity to create * * @throws DataAccessException */ private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry) throws DataAccessException { - basicAclEntryCache.removeEntriesFromCache(basicAclEntry - .getAclObjectIdentity()); + basicAclEntryCache.removeEntriesFromCache(basicAclEntry.getAclObjectIdentity()); - String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry - .getAclObjectIdentity()); + String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry.getAclObjectIdentity()); // Lookup the object's main properties from the RDBMS (guaranteed no nulls) List objects = objectProperties.execute(aclObjectIdentityString); if (objects.size() == 0) { if (basicAclEntry.getAclObjectParentIdentity() != null) { - AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry - .getAclObjectParentIdentity()); + AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry.getAclObjectParentIdentity()); // Must create the acl_object_identity record - aclObjectIdentityInsert.insert(aclObjectIdentityString, - new Long(parentDetails.getForeignKeyId()), + aclObjectIdentityInsert.insert(aclObjectIdentityString, new Long(parentDetails.getForeignKeyId()), basicAclEntry.getClass().getName()); } else { // Must create the acl_object_identity record - aclObjectIdentityInsert.insert(aclObjectIdentityString, null, - basicAclEntry.getClass().getName()); + aclObjectIdentityInsert.insert(aclObjectIdentityString, null, basicAclEntry.getClass().getName()); } } } @@ -212,8 +183,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Retrieve all acl_permissions applying to this acl_object_identity - Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder - .getForeignKeyId()).iterator(); + Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder.getForeignKeyId()).iterator(); // Delete all existing acl_permissions applying to this acl_object_identity while (acls.hasNext()) { @@ -222,8 +192,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl } // Delete acl_object_identity - aclObjectIdentityDelete.delete(new Long( - aclDetailsHolder.getForeignKeyId())); + aclObjectIdentityDelete.delete(new Long(aclDetailsHolder.getForeignKeyId())); } public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) @@ -234,8 +203,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Delete acl_permission - aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()), - recipient.toString()); + aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()), recipient.toString()); } public AclObjectIdentityDelete getAclObjectIdentityDelete() { @@ -309,8 +277,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl * * @throws DataRetrievalFailureException if record could not be found */ - private AclDetailsHolder lookupAclDetailsHolder( - AclObjectIdentity aclObjectIdentity) + private AclDetailsHolder lookupAclDetailsHolder(AclObjectIdentity aclObjectIdentity) throws DataRetrievalFailureException { String aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity); @@ -318,8 +285,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl List objects = objectProperties.execute(aclObjectIdentityString); if (objects.size() == 0) { - throw new DataRetrievalFailureException( - "aclObjectIdentity not found: " + aclObjectIdentityString); + throw new DataRetrievalFailureException("aclObjectIdentity not found: " + aclObjectIdentityString); } // Should only be one record @@ -327,8 +293,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl } /** - * Convenience method to lookup the acl_permission applying to a given - * acl_object_identity.id and acl_permission.recipient. + * Convenience method to lookup the acl_permission applying to a given acl_object_identity.id and + * acl_permission.recipient. * * @param aclObjectIdentityId to locate * @param recipient to locate @@ -339,8 +305,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl */ private long lookupPermissionId(long aclObjectIdentityId, Object recipient) throws DataAccessException { - List list = lookupPermissionIdMapping.execute(new Object[] {new Long( - aclObjectIdentityId), recipient}); + List list = lookupPermissionIdMapping.execute(new Object[] {new Long(aclObjectIdentityId), recipient}); if (list.size() == 0) { return -1; @@ -349,23 +314,19 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl return ((Long) list.get(0)).longValue(); } - public void setAclObjectIdentityDelete( - AclObjectIdentityDelete aclObjectIdentityDelete) { + public void setAclObjectIdentityDelete(AclObjectIdentityDelete aclObjectIdentityDelete) { this.aclObjectIdentityDelete = aclObjectIdentityDelete; } - public void setAclObjectIdentityDeleteStatement( - String aclObjectIdentityDeleteStatement) { + public void setAclObjectIdentityDeleteStatement(String aclObjectIdentityDeleteStatement) { this.aclObjectIdentityDeleteStatement = aclObjectIdentityDeleteStatement; } - public void setAclObjectIdentityInsert( - AclObjectIdentityInsert aclObjectIdentityInsert) { + public void setAclObjectIdentityInsert(AclObjectIdentityInsert aclObjectIdentityInsert) { this.aclObjectIdentityInsert = aclObjectIdentityInsert; } - public void setAclObjectIdentityInsertStatement( - String aclObjectIdentityInsertStatement) { + public void setAclObjectIdentityInsertStatement(String aclObjectIdentityInsertStatement) { this.aclObjectIdentityInsertStatement = aclObjectIdentityInsertStatement; } @@ -373,8 +334,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl this.aclPermissionDelete = aclPermissionDelete; } - public void setAclPermissionDeleteStatement( - String aclPermissionDeleteStatement) { + public void setAclPermissionDeleteStatement(String aclPermissionDeleteStatement) { this.aclPermissionDeleteStatement = aclPermissionDeleteStatement; } @@ -382,8 +342,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl this.aclPermissionInsert = aclPermissionInsert; } - public void setAclPermissionInsertStatement( - String aclPermissionInsertStatement) { + public void setAclPermissionInsertStatement(String aclPermissionInsertStatement) { this.aclPermissionInsertStatement = aclPermissionInsertStatement; } @@ -391,8 +350,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl this.aclPermissionUpdate = aclPermissionUpdate; } - public void setAclPermissionUpdateStatement( - String aclPermissionUpdateStatement) { + public void setAclPermissionUpdateStatement(String aclPermissionUpdateStatement) { this.aclPermissionUpdateStatement = aclPermissionUpdateStatement; } @@ -401,8 +359,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl this.basicAclEntryCache = basicAclEntryCache; } - public void setLookupPermissionIdMapping( - MappingSqlQuery lookupPermissionIdMapping) { + public void setLookupPermissionIdMapping(MappingSqlQuery lookupPermissionIdMapping) { this.lookupPermissionIdMapping = lookupPermissionIdMapping; } @@ -410,7 +367,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl this.lookupPermissionIdQuery = lookupPermissionIdQuery; } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== protected class AclObjectIdentityDelete extends SqlUpdate { protected AclObjectIdentityDelete(DataSource ds) { @@ -419,8 +376,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl compile(); } - protected void delete(Long aclObjectIdentity) - throws DataAccessException { + protected void delete(Long aclObjectIdentity) throws DataAccessException { super.update(aclObjectIdentity.intValue()); } } @@ -434,8 +390,7 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl compile(); } - protected void insert(String objectIdentity, - Long parentAclObjectIdentity, String aclClass) + protected void insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass) throws DataAccessException { Object[] objs = new Object[] {objectIdentity, parentAclObjectIdentity, aclClass}; super.update(objs); @@ -465,8 +420,8 @@ public class JdbcExtendedDaoImpl extends JdbcDaoImpl compile(); } - protected void insert(Long aclObjectIdentity, String recipient, - Integer mask) throws DataAccessException { + protected void insert(Long aclObjectIdentity, String recipient, Integer mask) + throws DataAccessException { Object[] objs = new Object[] {aclObjectIdentity, recipient, mask}; super.update(objs); } diff --git a/core/src/main/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationToken.java b/core/src/main/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationToken.java index 44ef365562..39322c6e03 100644 --- a/core/src/main/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationToken.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.adapters; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.providers.AbstractAuthenticationToken; @@ -25,19 +26,18 @@ import org.acegisecurity.providers.AbstractAuthenticationToken; * @author Ben Alex * @version $Id$ */ -public abstract class AbstractAdapterAuthenticationToken - extends AbstractAuthenticationToken implements AuthByAdapter { - //~ Instance fields ======================================================== +public abstract class AbstractAdapterAuthenticationToken extends AbstractAuthenticationToken implements AuthByAdapter { + //~ Instance fields ================================================================================================ private int keyHash; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== protected AbstractAdapterAuthenticationToken() { super(null); } - /** +/** * The only way an AbstractAdapterAuthentication should be * constructed. * @@ -45,62 +45,12 @@ public abstract class AbstractAdapterAuthenticationToken * #getKeyHash()} * @param authorities the authorities granted to this principal */ - protected AbstractAdapterAuthenticationToken(String key, - GrantedAuthority[] authorities) { + protected AbstractAdapterAuthenticationToken(String key, GrantedAuthority[] authorities) { super(authorities); this.keyHash = key.hashCode(); } - //~ Methods ================================================================ - - /** - * Setting is ignored. Always considered authenticated. - * - * @param ignored DOCUMENT ME! - */ - public void setAuthenticated(boolean ignored) { - // ignored - } - - /** - * Always returns true. - * - * @return DOCUMENT ME! - */ - public boolean isAuthenticated() { - return true; - } - - public int getKeyHash() { - return this.keyHash; - } - - /** - * Iterates the granted authorities and indicates whether or not the - * specified role is held. - * - *

- * Comparison is based on the String returned by {@link - * GrantedAuthority#getAuthority}. - *

- * - * @param role the role being searched for in this object's granted - * authorities list - * - * @return true if the granted authority is held, or - * false otherwise - */ - public boolean isUserInRole(String role) { - GrantedAuthority[] authorities = super.getAuthorities(); - - for (int i = 0; i < authorities.length; i++) { - if (role.equals(authorities[i].getAuthority())) { - return true; - } - } - - return false; - } + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (obj instanceof AbstractAdapterAuthenticationToken) { @@ -115,4 +65,46 @@ public abstract class AbstractAdapterAuthenticationToken return false; } + + public int getKeyHash() { + return this.keyHash; + } + + /** + * Always returns true. + * + * @return DOCUMENT ME! + */ + public boolean isAuthenticated() { + return true; + } + + /** + * Iterates the granted authorities and indicates whether or not the specified role is held.

Comparison + * is based on the String returned by {@link GrantedAuthority#getAuthority}.

+ * + * @param role the role being searched for in this object's granted authorities list + * + * @return true if the granted authority is held, or false otherwise + */ + public boolean isUserInRole(String role) { + GrantedAuthority[] authorities = super.getAuthorities(); + + for (int i = 0; i < authorities.length; i++) { + if (role.equals(authorities[i].getAuthority())) { + return true; + } + } + + return false; + } + + /** + * Setting is ignored. Always considered authenticated. + * + * @param ignored DOCUMENT ME! + */ + public void setAuthenticated(boolean ignored) { + // ignored + } } diff --git a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapter.java b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapter.java index 01747f0147..b1f99feb11 100644 --- a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapter.java +++ b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,13 +32,12 @@ import org.acegisecurity.Authentication; * @version $Id$ */ public interface AuthByAdapter extends Authentication { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Returns the hash code of the key that was passed to the constructor of - * the AuthByAdapter implementation. The implementation - * should convert the value to a hash code at construction time, rather - * than storing the key itself. + * Returns the hash code of the key that was passed to the constructor of the AuthByAdapter + * implementation. The implementation should convert the value to a hash code at construction time, rather than + * storing the key itself. * * @return the hash code of the key used when the object was created. */ diff --git a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java index 777f64727d..bfb8b73388 100644 --- a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java +++ b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,32 +32,22 @@ import org.springframework.util.Assert; /** - * An {@link AuthenticationProvider} implementation that can authenticate an - * {@link AuthByAdapter}. - * - *

- * Configured in the bean context with a key that should match the key used by - * adapters to generate AuthByAdapter instances. It treats as - * valid any such instance presenting a hash code that matches the - * AuthByAdapterProvider-configured key. - *

- * - *

- * If the key does not match, a BadCredentialsException is thrown. - *

+ * An {@link AuthenticationProvider} implementation that can authenticate an {@link AuthByAdapter}.

Configured in + * the bean context with a key that should match the key used by adapters to generate AuthByAdapter + * instances. It treats as valid any such instance presenting a hash code that matches the + * AuthByAdapterProvider-configured key.

+ *

If the key does not match, a BadCredentialsException is thrown.

*/ -public class AuthByAdapterProvider implements InitializingBean, - AuthenticationProvider, MessageSourceAware { - //~ Instance fields ======================================================== +public class AuthByAdapterProvider implements InitializingBean, AuthenticationProvider, MessageSourceAware { + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private String key; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(key, - "A Key is required and should match that configured for the adapters"); + Assert.notNull(key, "A Key is required and should match that configured for the adapters"); Assert.notNull(messages, "A message source must be set"); } @@ -68,8 +58,7 @@ public class AuthByAdapterProvider implements InitializingBean, if (token.getKeyHash() == key.hashCode()) { return authentication; } else { - throw new BadCredentialsException(messages.getMessage( - "AuthByAdapterProvider.incorrectKey", + throw new BadCredentialsException(messages.getMessage("AuthByAdapterProvider.incorrectKey", "The presented AuthByAdapter implementation does not contain the expected key")); } } diff --git a/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java b/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java index 6ae1f0cebc..5ec0b273f2 100644 --- a/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.adapters; import org.acegisecurity.Authentication; + import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.logging.Log; @@ -35,63 +36,47 @@ import javax.servlet.http.HttpServletRequest; /** - * Populates SecurityContext with the Authentication - * obtained from the container's - * HttpServletRequest.getUserPrincipal(). - * - *

- * Use this filter with container adapters only. - *

- * - *

- * This filter never preserves the Authentication on the - * SecurityContext - it is replaced every request. - *

- * - *

- * See {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter} - * for further information. - *

+ * Populates SecurityContext with the Authentication obtained from the container's + * HttpServletRequest.getUserPrincipal().

Use this filter with container adapters only.

+ *

This filter never preserves the Authentication on the SecurityContext - it + * is replaced every request.

+ *

See {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter} for further information.

* * @author Ben Alex * @version $Id$ */ public class HttpRequestIntegrationFilter implements Filter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(HttpRequestIntegrationFilter.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Does nothing. We use IoC container lifecycle services instead. */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (request instanceof HttpServletRequest) { - Principal principal = ((HttpServletRequest) request) - .getUserPrincipal(); + Principal principal = ((HttpServletRequest) request).getUserPrincipal(); if ((principal != null) && principal instanceof Authentication) { SecurityContextHolder.getContext().setAuthentication((Authentication) principal); if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder updated with Authentication from container: '" - + principal + "'"); + logger.debug("SecurityContextHolder updated with Authentication from container: '" + principal + + "'"); } } else { if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder not set with new Authentication as Principal was: '" + logger.debug("SecurityContextHolder not set with new Authentication as Principal was: '" + principal + "'"); } } } else { - throw new IllegalArgumentException( - "Only HttpServletRequest is acceptable"); + throw new IllegalArgumentException("Only HttpServletRequest is acceptable"); } chain.doFilter(request, response); diff --git a/core/src/main/java/org/acegisecurity/adapters/PrincipalAcegiUserToken.java b/core/src/main/java/org/acegisecurity/adapters/PrincipalAcegiUserToken.java index 1b27551f4f..ce9055a206 100644 --- a/core/src/main/java/org/acegisecurity/adapters/PrincipalAcegiUserToken.java +++ b/core/src/main/java/org/acegisecurity/adapters/PrincipalAcegiUserToken.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,31 +21,29 @@ import java.security.Principal; /** - * A {@link Principal} compatible {@link org.acegisecurity.Authentication} - * object. + * A {@link Principal} compatible {@link org.acegisecurity.Authentication} object. * * @author Ben Alex * @version $Id$ */ -public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken - implements Principal { - //~ Instance fields ======================================================== +public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken implements Principal { + //~ Instance fields ================================================================================================ private Object principal; private String password; private String username; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public PrincipalAcegiUserToken(String key, String username, - String password, GrantedAuthority[] authorities, Object principal) { + public PrincipalAcegiUserToken(String key, String username, String password, GrantedAuthority[] authorities, + Object principal) { super(key, authorities); this.username = username; this.password = password; this.principal = principal; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return this.password; diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProvider.java b/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProvider.java index 91068eb42c..48bcefb009 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProvider.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,36 +29,28 @@ import org.acegisecurity.ConfigAttributeDefinition; * @version $Id$ */ public interface AfterInvocationProvider { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException; + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException; /** - * Indicates whether this AfterInvocationProvider is able to - * participate in a decision involving the passed - * ConfigAttribute. - * - *

- * This allows the AbstractSecurityInterceptor to check every - * configuration attribute can be consumed by the configured - * AccessDecisionManager and/or RunAsManager - * and/or AccessDecisionManager. - *

+ * Indicates whether this AfterInvocationProvider is able to participate in a decision + * involving the passed ConfigAttribute.

This allows the + * AbstractSecurityInterceptor to check every configuration attribute can be consumed by the + * configured AccessDecisionManager and/or RunAsManager and/or + * AccessDecisionManager.

* - * @param attribute a configuration attribute that has been configured - * against the AbstractSecurityInterceptor + * @param attribute a configuration attribute that has been configured against the + * AbstractSecurityInterceptor * - * @return true if this AfterInvocationProvider can support - * the passed configuration attribute + * @return true if this AfterInvocationProvider can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); /** - * Indicates whether the AfterInvocationProvider is able to - * provide "after invocation" processing for the indicated secured object - * type. + * Indicates whether the AfterInvocationProvider is able to provide "after invocation" + * processing for the indicated secured object type. * * @param clazz the class of secure object that is being queried * diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManager.java b/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManager.java index 70a3836c29..1a60ac4e1e 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManager.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,38 +31,55 @@ import java.util.List; /** - * Provider-based implementation of {@link AfterInvocationManager}. - * - *

- * Handles configuration of a bean context defined list of {@link - * AfterInvocationProvider}s. - *

- * - *

- * Every AfterInvocationProvider will be polled when the {@link - * #decide(Authentication, Object, ConfigAttributeDefinition, Object)} method - * is called. The Object returned from each provider will be - * presented to the successive provider for processing. This means each - * provider must ensure they return the Object, even if - * they are not interested in the "after invocation" decision (perhaps as the - * secure object invocation did not include a configuration attribute a given - * provider is configured to respond to). - *

+ * Provider-based implementation of {@link AfterInvocationManager}.

Handles configuration of a bean context + * defined list of {@link AfterInvocationProvider}s.

+ *

Every AfterInvocationProvider will be polled when the {@link #decide(Authentication, Object, + * ConfigAttributeDefinition, Object)} method is called. The Object returned from each provider will be + * presented to the successive provider for processing. This means each provider must ensure they return the + * Object, even if they are not interested in the "after invocation" decision (perhaps as the secure + * object invocation did not include a configuration attribute a given provider is configured to respond to).

* * @author Ben Alex * @version $Id$ */ -public class AfterInvocationProviderManager implements AfterInvocationManager, - InitializingBean { - //~ Static fields/initializers ============================================= +public class AfterInvocationProviderManager implements AfterInvocationManager, InitializingBean { + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(AfterInvocationProviderManager.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List providers; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() throws Exception { + checkIfValidList(this.providers); + } + + private void checkIfValidList(List listToCheck) { + if ((listToCheck == null) || (listToCheck.size() == 0)) { + throw new IllegalArgumentException("A list of AfterInvocationProviders is required"); + } + } + + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { + Iterator iter = this.providers.iterator(); + + Object result = returnedObject; + + while (iter.hasNext()) { + AfterInvocationProvider provider = (AfterInvocationProvider) iter.next(); + result = provider.decide(authentication, object, config, result); + } + + return result; + } + + public List getProviders() { + return this.providers; + } public void setProviders(List newList) { checkIfValidList(newList); @@ -77,8 +94,7 @@ public class AfterInvocationProviderManager implements AfterInvocationManager, AfterInvocationProvider attemptToCast = (AfterInvocationProvider) currentObject; } catch (ClassCastException cce) { - throw new IllegalArgumentException("AfterInvocationProvider " - + currentObject.getClass().getName() + throw new IllegalArgumentException("AfterInvocationProvider " + currentObject.getClass().getName() + " must implement AfterInvocationProvider"); } } @@ -86,36 +102,11 @@ public class AfterInvocationProviderManager implements AfterInvocationManager, this.providers = newList; } - public List getProviders() { - return this.providers; - } - - public void afterPropertiesSet() throws Exception { - checkIfValidList(this.providers); - } - - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException { - Iterator iter = this.providers.iterator(); - - Object result = returnedObject; - - while (iter.hasNext()) { - AfterInvocationProvider provider = (AfterInvocationProvider) iter - .next(); - result = provider.decide(authentication, object, config, result); - } - - return result; - } - public boolean supports(ConfigAttribute attribute) { Iterator iter = this.providers.iterator(); while (iter.hasNext()) { - AfterInvocationProvider provider = (AfterInvocationProvider) iter - .next(); + AfterInvocationProvider provider = (AfterInvocationProvider) iter.next(); if (logger.isDebugEnabled()) { logger.debug("Evaluating " + attribute + " against " + provider); @@ -130,27 +121,19 @@ public class AfterInvocationProviderManager implements AfterInvocationManager, } /** - * Iterates through all AfterInvocationProviders and ensures - * each can support the presented class. - * - *

- * If one or more providers cannot support the presented class, - * false is returned. - *

+ * Iterates through all AfterInvocationProviders and ensures each can support the presented + * class.

If one or more providers cannot support the presented class, false is returned.

* * @param clazz the secure object class being queries * - * @return if the AfterInvocationProviderManager can support - * the secure object class, which requires every one of its - * AfterInvocationProviders to support the secure - * object class + * @return if the AfterInvocationProviderManager can support the secure object class, which requires + * every one of its AfterInvocationProviders to support the secure object class */ public boolean supports(Class clazz) { Iterator iter = this.providers.iterator(); while (iter.hasNext()) { - AfterInvocationProvider provider = (AfterInvocationProvider) iter - .next(); + AfterInvocationProvider provider = (AfterInvocationProvider) iter.next(); if (!provider.supports(clazz)) { return false; @@ -159,11 +142,4 @@ public class AfterInvocationProviderManager implements AfterInvocationManager, return true; } - - private void checkIfValidList(List listToCheck) { - if ((listToCheck == null) || (listToCheck.size() == 0)) { - throw new IllegalArgumentException( - "A list of AfterInvocationProviders is required"); - } - } } diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java index 5c2aabef53..3a67393b3f 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.AuthorizationServiceException; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.BasicAclEntry; @@ -42,125 +43,61 @@ import java.util.Set; /** - *

- * Given a Collection of domain object instances returned from a - * secure object invocation, remove any Collection elements the - * principal does not have appropriate permission to access as defined by the - * {@link AclManager}. - *

- * - *

- * The AclManager is used to retrieve the access control list - * (ACL) permissions associated with each Collection domain - * object instance element for the current Authentication object. - * This class is designed to process {@link AclEntry}s that are subclasses of - * {@link org.acegisecurity.acl.basic.BasicAclEntry} only. - * Generally these are obtained by using the {@link - * org.acegisecurity.acl.basic.BasicAclProvider}. - *

- * - *

- * This after invocation provider will fire if any {@link - * ConfigAttribute#getAttribute()} matches the {@link - * #processConfigAttribute}. The provider will then lookup the ACLs from the - * AclManager and ensure the principal is {@link - * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for - * at least one of the {@link #requirePermission}s for each - * Collection element. If the principal does not have at least - * one of the permissions, that element will not be included in the returned - * Collection. - *

- * - *

- * Often users will setup a BasicAclEntryAfterInvocationProvider - * with a {@link #processConfigAttribute} of - * AFTER_ACL_COLLECTION_READ and a {@link #requirePermission} of - * SimpleAclEntry.READ. These are also the defaults. - *

- * - *

- * The AclManager is allowed to return any implementations of - * AclEntry it wishes. However, this provider will only be able - * to validate against BasicAclEntrys, and thus a - * Collection element will be filtered from the resulting - * Collection if no AclEntry is of type - * BasicAclEntry. - *

- * - *

- * If the provided returnObject is null, a - * nullCollection will be returned. If the provided - * returnObject is not a Collection, an {@link - * AuthorizationServiceException} will be thrown. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Given a Collection of domain object instances returned from a secure object invocation, remove + * any Collection elements the principal does not have appropriate permission to access as defined by the + * {@link AclManager}.

+ *

The AclManager is used to retrieve the access control list (ACL) permissions associated with + * each Collection domain object instance element for the current Authentication object. + * This class is designed to process {@link AclEntry}s that are subclasses of {@link + * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are obtained by using the {@link + * org.acegisecurity.acl.basic.BasicAclProvider}.

+ *

This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link + * #processConfigAttribute}. The provider will then lookup the ACLs from the AclManager and ensure the + * principal is {@link org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link + * #requirePermission}s for each Collection element. If the principal does not have at least one of the + * permissions, that element will not be included in the returned Collection.

+ *

Often users will setup a BasicAclEntryAfterInvocationProvider with a {@link + * #processConfigAttribute} of AFTER_ACL_COLLECTION_READ and a {@link #requirePermission} of + * SimpleAclEntry.READ. These are also the defaults.

+ *

The AclManager is allowed to return any implementations of AclEntry it wishes. + * However, this provider will only be able to validate against BasicAclEntrys, and thus a + * Collection element will be filtered from the resulting Collection if no + * AclEntry is of type BasicAclEntry.

+ *

If the provided returnObject is null, a nullCollection + * will be returned. If the provided returnObject is not a Collection, an {@link + * AuthorizationServiceException} will be thrown.

+ *

All comparisons and prefixes are case sensitive.

* * @author Ben Alex * @author Paulo Neves * @version $Id$ */ -public class BasicAclEntryAfterInvocationCollectionFilteringProvider - implements AfterInvocationProvider, InitializingBean { - //~ Static fields/initializers ============================================= +public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements AfterInvocationProvider, + InitializingBean { + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclManager aclManager; + private Class processDomainObjectClass = Object.class; private String processConfigAttribute = "AFTER_ACL_COLLECTION_READ"; private int[] requirePermission = {SimpleAclEntry.READ}; - private Class processDomainObjectClass = Object.class; - //~ Methods ================================================================ - - public void setProcessDomainObjectClass(Class processDomainObjectClass) { - Assert.notNull(processDomainObjectClass, - "processDomainObjectClass cannot be set to null"); - this.processDomainObjectClass = processDomainObjectClass; - } - - public void setAclManager(AclManager aclManager) { - this.aclManager = aclManager; - } - - public AclManager getAclManager() { - return aclManager; - } - - public void setProcessConfigAttribute(String processConfigAttribute) { - this.processConfigAttribute = processConfigAttribute; - } - - public String getProcessConfigAttribute() { - return processConfigAttribute; - } - - public void setRequirePermission(int[] requirePermission) { - this.requirePermission = requirePermission; - } - - public int[] getRequirePermission() { - return requirePermission; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(processConfigAttribute, - "A processConfigAttribute is mandatory"); + Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory"); Assert.notNull(aclManager, "An aclManager is mandatory"); if ((requirePermission == null) || (requirePermission.length == 0)) { - throw new IllegalArgumentException( - "One or more requirePermission entries is mandatory"); + throw new IllegalArgumentException("One or more requirePermission entries is mandatory"); } } - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException { + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { @@ -203,7 +140,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider if (domainObject == null) { hasPermission = true; } else if (!processDomainObjectClass.isAssignableFrom(domainObject.getClass())) { - hasPermission = true; + hasPermission = true; } else { acls = aclManager.getAcls(domainObject, authentication); } @@ -212,21 +149,16 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider for (int i = 0; i < acls.length; i++) { // Locate processable AclEntrys if (acls[i] instanceof BasicAclEntry) { - BasicAclEntry processableAcl = (BasicAclEntry) acls[i]; + BasicAclEntry processableAcl = (BasicAclEntry) acls[i]; // See if principal has any of the required permissions - for (int y = 0; y < requirePermission.length; - y++) { - if (processableAcl.isPermitted( - requirePermission[y])) { + for (int y = 0; y < requirePermission.length; y++) { + if (processableAcl.isPermitted(requirePermission[y])) { hasPermission = true; if (logger.isDebugEnabled()) { - logger.debug( - "Principal is authorised for element: " - + domainObject - + " due to ACL: " - + processableAcl.toString()); + logger.debug("Principal is authorised for element: " + domainObject + + " due to ACL: " + processableAcl.toString()); } } } @@ -238,9 +170,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider filterer.remove(domainObject); if (logger.isDebugEnabled()) { - logger.debug( - "Principal is NOT authorised for element: " - + domainObject); + logger.debug("Principal is NOT authorised for element: " + domainObject); } } } @@ -252,9 +182,37 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider return returnedObject; } + public AclManager getAclManager() { + return aclManager; + } + + public String getProcessConfigAttribute() { + return processConfigAttribute; + } + + public int[] getRequirePermission() { + return requirePermission; + } + + public void setAclManager(AclManager aclManager) { + this.aclManager = aclManager; + } + + public void setProcessConfigAttribute(String processConfigAttribute) { + this.processConfigAttribute = processConfigAttribute; + } + + public void setProcessDomainObjectClass(Class processDomainObjectClass) { + Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null"); + this.processDomainObjectClass = processDomainObjectClass; + } + + public void setRequirePermission(int[] requirePermission) { + this.requirePermission = requirePermission; + } + public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) - && attribute.getAttribute().equals(getProcessConfigAttribute())) { + if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) { return true; } else { return false; @@ -262,8 +220,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider } /** - * This implementation supports any type of class, because it does not - * query the presented secure object. + * This implementation supports any type of class, because it does not query the presented secure object. * * @param clazz the secure object * @@ -279,7 +236,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider * Filter strategy interface. */ interface Filterer { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Gets the filtered collection or array. @@ -308,11 +265,11 @@ interface Filterer { * A filter used to filter Collections. */ class CollectionFilterer implements Filterer { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Collection collection; @@ -321,7 +278,7 @@ class CollectionFilterer implements Filterer { private Iterator collectionIter; private Set removeList; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== CollectionFilterer(Collection collection) { this.collection = collection; @@ -336,9 +293,10 @@ class CollectionFilterer implements Filterer { removeList = new HashSet(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** + * * @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject() */ public Object getFilteredObject() { @@ -352,14 +310,15 @@ class CollectionFilterer implements Filterer { } if (logger.isDebugEnabled()) { - logger.debug("Original collection contained " + originalSize - + " elements; now contains " + collection.size() + " elements"); + logger.debug("Original collection contained " + originalSize + " elements; now contains " + + collection.size() + " elements"); } return collection; } /** + * * @see org.acegisecurity.afterinvocation.Filterer#iterator() */ public Iterator iterator() { @@ -369,6 +328,7 @@ class CollectionFilterer implements Filterer { } /** + * * @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object) */ public void remove(Object object) { @@ -381,16 +341,16 @@ class CollectionFilterer implements Filterer { * A filter used to filter arrays. */ class ArrayFilterer implements Filterer { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Set removeList; private Object[] list; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== ArrayFilterer(Object[] list) { this.list = list; @@ -401,18 +361,17 @@ class ArrayFilterer implements Filterer { removeList = new HashSet(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** + * * @see org.acegisecurity.afterinvocation.Filterer#getFilteredObject() */ public Object getFilteredObject() { // Recreate an array of same type and filter the removed objects. int originalSize = list.length; int sizeOfResultingList = originalSize - removeList.size(); - Object[] filtered = (Object[]) Array.newInstance(list.getClass() - .getComponentType(), - sizeOfResultingList); + Object[] filtered = (Object[]) Array.newInstance(list.getClass().getComponentType(), sizeOfResultingList); for (int i = 0, j = 0; i < list.length; i++) { Object object = list[i]; @@ -424,8 +383,7 @@ class ArrayFilterer implements Filterer { } if (logger.isDebugEnabled()) { - logger.debug("Original array contained " + originalSize - + " elements; now contains " + sizeOfResultingList + logger.debug("Original array contained " + originalSize + " elements; now contains " + sizeOfResultingList + " elements"); } @@ -433,6 +391,7 @@ class ArrayFilterer implements Filterer { } /** + * * @see org.acegisecurity.afterinvocation.Filterer#iterator() */ public Iterator iterator() { @@ -440,6 +399,7 @@ class ArrayFilterer implements Filterer { } /** + * * @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object) */ public void remove(Object object) { diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java index eddba12c33..fb856c3055 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,116 +15,81 @@ package org.acegisecurity.afterinvocation; -import java.util.Iterator; - import org.acegisecurity.AccessDeniedException; import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.BasicAclEntry; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.util.Iterator; + /** - *

- * Given a domain object instance returned from a secure object invocation, - * ensures the principal has appropriate permission as defined by the {@link - * AclManager}. - *

- * - *

- * The AclManager is used to retrieve the access control list - * (ACL) permissions associated with a domain object instance for the current - * Authentication object. This class is designed to process - * {@link AclEntry}s that are subclasses of {@link - * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are - * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}. - *

- * - *

- * This after invocation provider will fire if any {@link - * ConfigAttribute#getAttribute()} matches the {@link - * #processConfigAttribute}. The provider will then lookup the ACLs from the - * AclManager and ensure the principal is {@link - * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least - * one of the {@link #requirePermission}s. - *

- * - *

- * Often users will setup a BasicAclEntryAfterInvocationProvider - * with a {@link #processConfigAttribute} of AFTER_ACL_READ and a - * {@link #requirePermission} of SimpleAclEntry.READ. These are - * also the defaults. - *

- * - *

- * If the principal does not have sufficient permissions, an - * AccessDeniedException will be thrown. - *

- * - *

- * The AclManager is allowed to return any implementations of - * AclEntry it wishes. However, this provider will only be able - * to validate against BasicAclEntrys, and thus access will be - * denied if no AclEntry is of type BasicAclEntry. - *

- * - *

- * If the provided returnObject is null, permission - * will always be granted and null will be returned. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Given a domain object instance returned from a secure object invocation, ensures the principal has + * appropriate permission as defined by the {@link AclManager}.

+ *

The AclManager is used to retrieve the access control list (ACL) permissions associated with a + * domain object instance for the current Authentication object. This class is designed to process {@link + * AclEntry}s that are subclasses of {@link org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are + * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.

+ *

This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link + * #processConfigAttribute}. The provider will then lookup the ACLs from the AclManager and ensure the + * principal is {@link org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link + * #requirePermission}s.

+ *

Often users will setup a BasicAclEntryAfterInvocationProvider with a {@link + * #processConfigAttribute} of AFTER_ACL_READ and a {@link #requirePermission} of + * SimpleAclEntry.READ. These are also the defaults.

+ *

If the principal does not have sufficient permissions, an AccessDeniedException will be thrown.

+ *

The AclManager is allowed to return any implementations of AclEntry it wishes. + * However, this provider will only be able to validate against BasicAclEntrys, and thus access will be + * denied if no AclEntry is of type BasicAclEntry.

+ *

If the provided returnObject is null, permission will always be granted and + * null will be returned.

+ *

All comparisons and prefixes are case sensitive.

*/ -public class BasicAclEntryAfterInvocationProvider - implements AfterInvocationProvider, InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean, + MessageSourceAware { + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclManager aclManager; + private Class processDomainObjectClass = Object.class; protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private String processConfigAttribute = "AFTER_ACL_READ"; private int[] requirePermission = {SimpleAclEntry.READ}; - private Class processDomainObjectClass = Object.class; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setProcessDomainObjectClass(Class processDomainObjectClass) { - Assert.notNull(processDomainObjectClass, - "processDomainObjectClass cannot be set to null"); - this.processDomainObjectClass = processDomainObjectClass; - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(processConfigAttribute, - "A processConfigAttribute is mandatory"); + public void afterPropertiesSet() throws Exception { + Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory"); Assert.notNull(aclManager, "An aclManager is mandatory"); Assert.notNull(messages, "A message source must be set"); if ((requirePermission == null) || (requirePermission.length == 0)) { - throw new IllegalArgumentException( - "One or more requirePermission entries is mandatory"); + throw new IllegalArgumentException("One or more requirePermission entries is mandatory"); } } - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException { + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { @@ -141,7 +106,7 @@ public class BasicAclEntryAfterInvocationProvider return null; } - + if (!processDomainObjectClass.isAssignableFrom(returnedObject.getClass())) { if (logger.isDebugEnabled()) { logger.debug("Return object is not applicable for this provider, skipping"); @@ -150,8 +115,7 @@ public class BasicAclEntryAfterInvocationProvider return null; } - AclEntry[] acls = aclManager.getAcls(returnedObject, - authentication); + AclEntry[] acls = aclManager.getAcls(returnedObject, authentication); if ((acls == null) || (acls.length == 0)) { throw new AccessDeniedException(messages.getMessage( @@ -169,10 +133,8 @@ public class BasicAclEntryAfterInvocationProvider for (int y = 0; y < requirePermission.length; y++) { if (processableAcl.isPermitted(requirePermission[y])) { if (logger.isDebugEnabled()) { - logger.debug( - "Principal DOES have permission to return object: " - + returnedObject + " due to ACL: " - + processableAcl.toString()); + logger.debug("Principal DOES have permission to return object: " + returnedObject + + " due to ACL: " + processableAcl.toString()); } return returnedObject; @@ -216,13 +178,17 @@ public class BasicAclEntryAfterInvocationProvider this.processConfigAttribute = processConfigAttribute; } + public void setProcessDomainObjectClass(Class processDomainObjectClass) { + Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null"); + this.processDomainObjectClass = processDomainObjectClass; + } + public void setRequirePermission(int[] requirePermission) { this.requirePermission = requirePermission; } public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) - && attribute.getAttribute().equals(getProcessConfigAttribute())) { + if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) { return true; } else { return false; @@ -230,8 +196,7 @@ public class BasicAclEntryAfterInvocationProvider } /** - * This implementation supports any type of class, because it does not - * query the presented secure object. + * This implementation supports any type of class, because it does not query the presented secure object. * * @param clazz the secure object * diff --git a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessor.java b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessor.java index 901e45ae2f..ca7d0bd80a 100644 --- a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,25 +19,21 @@ package org.acegisecurity.captcha; /** - *

- * return false if ny CaptchaChannelProcessorTemplate of mapped urls has been - * requested more than thresold;
- * Default keyword : REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS - *

+ *

return false if ny CaptchaChannelProcessorTemplate of mapped urls has been requested more than thresold;
+ * Default keyword : REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS

* * @author Marc-Antoine Garrigue * @version $Id$ */ -public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor - extends CaptchaChannelProcessorTemplate { - //~ Static fields/initializers ============================================= +public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate { + //~ Static fields/initializers ===================================================================================== /** Keyword for this channelProcessor */ public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor */ public AlwaysTestAfterMaxRequestsCaptchaChannelProcessor() { @@ -45,7 +41,7 @@ public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessor this.setKeyword(DEFAULT_KEYWORD); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Verify wheter the context is valid concerning humanity diff --git a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessor.java b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessor.java index 4282396c23..8fd089bfe7 100644 --- a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,27 +12,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.captcha; /** - *

- * return false if thresold is greater than millis since last captcha test has occured;
- * Default keyword : REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS - *

+ *

return false if thresold is greater than millis since last captcha test has occured;
+ * Default keyword : REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS

* * @author Marc-Antoine Garrigue * @version $Id$ */ -public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor - extends CaptchaChannelProcessorTemplate { - //~ Static fields/initializers ============================================= +public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate { + //~ Static fields/initializers ===================================================================================== /** Keyword for this channelProcessor */ public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor */ public AlwaysTestAfterTimeInMillisCaptchaChannelProcessor() { @@ -40,7 +38,7 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor this.setKeyword(DEFAULT_KEYWORD); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Verify wheter the context is valid concerning humanity @@ -50,15 +48,12 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessor * @return true if valid, false otherwise */ boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) { - if ((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis()) < getThresold()) { - logger.debug( - "context is valid : last passed captcha date - current time < thresold"); + if ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < getThresold()) { + logger.debug("context is valid : last passed captcha date - current time < thresold"); return true; } else { - logger.debug( - "context is not valid : last passed captcha date - current time > thresold"); + logger.debug("context is not valid : last passed captcha date - current time > thresold"); return false; } diff --git a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.java b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.java index a7586e1200..900dfb45bf 100644 --- a/core/src/main/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,26 +19,23 @@ import org.springframework.util.Assert; /** - *

- * return false if thresold is lower than average time millis between any - * CaptchaChannelProcessorTemplate mapped urls requests and is human;
+ *

return false if thresold is lower than average time millis between any CaptchaChannelProcessorTemplate mapped + * urls requests and is human;
* Default keyword : REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS
- * Note : before first humanity check - *

+ * Note : before first humanity check

* * @author Marc-Antoine Garrigue * @version $Id$ */ -public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - extends CaptchaChannelProcessorTemplate { - //~ Static fields/initializers ============================================= +public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor extends CaptchaChannelProcessorTemplate { + //~ Static fields/initializers ===================================================================================== /** Keyword for this channelProcessor */ public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor */ public AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor() { @@ -46,7 +43,7 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor this.setKeyword(DEFAULT_KEYWORD); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Verify if thresold is > 0 @@ -68,8 +65,7 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) { int req = context.getHumanRestrictedResourcesRequestsCount(); float thresold = getThresold(); - float duration = System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis(); + float duration = System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis(); float average; if (req == 0) { @@ -79,13 +75,11 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor } if (context.isHuman() && (average > thresold)) { - logger.debug( - "context is valid : average time between requests < thresold && is human"); + logger.debug("context is valid : average time between requests < thresold && is human"); return true; } else { - logger.debug( - "context is not valid : request count > thresold or is not human"); + logger.debug("context is not valid : request count > thresold or is not human"); return false; } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplate.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplate.java index 744751c9fa..1a037b746b 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplate.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplate.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,11 @@ package org.acegisecurity.captcha; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.intercept.web.FilterInvocation; + import org.acegisecurity.securechannel.ChannelEntryPoint; import org.acegisecurity.securechannel.ChannelProcessor; @@ -37,67 +40,32 @@ import javax.servlet.ServletException; /** - *

- * CaptchaChannel template : Ensures the user has enough human privileges by - * review of the {@link CaptchaSecurityContext} and using an abstract routine - * {@link #isContextValidConcerningHumanity(CaptchaSecurityContext)} - * (implemented by sub classes) - *

- * - *

- * The component uses 2 main parameters for its configuration : - * - *

    - *
  • - * a keyword to be mapped to urls in the {@link - * org.acegisecurity.securechannel.ChannelProcessingFilter} configuration
    - * default value provided by sub classes. - *
  • - *
  • - * and a thresold : used by the routine {@link - * #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate - * whether the {@link CaptchaSecurityContext} is valid default value = 0 - *
  • - *
- *

+ *

CaptchaChannel template : Ensures the user has enough human privileges by review of the {@link + * CaptchaSecurityContext} and using an abstract routine {@link + * #isContextValidConcerningHumanity(CaptchaSecurityContext)} (implemented by sub classes)

+ *

The component uses 2 main parameters for its configuration : + *

    + *
  • a keyword to be mapped to urls in the {@link + * org.acegisecurity.securechannel.ChannelProcessingFilter} configuration
    + * default value provided by sub classes.
  • + *
  • and a thresold : used by the routine {@link + * #isContextValidConcerningHumanity(CaptchaSecurityContext)} to evaluate whether the {@link + * CaptchaSecurityContext} is valid default value = 0
  • + *
+ *

* * @author marc antoine Garrigue * @version $Id$ */ -public abstract class CaptchaChannelProcessorTemplate - implements ChannelProcessor, InitializingBean { - //~ Instance fields ======================================================== +public abstract class CaptchaChannelProcessorTemplate implements ChannelProcessor, InitializingBean { + //~ Instance fields ================================================================================================ - protected Log logger = LogFactory.getLog(this.getClass()); private ChannelEntryPoint entryPoint; + protected Log logger = LogFactory.getLog(this.getClass()); private String keyword = null; private int thresold = 0; - //~ Methods ================================================================ - - public void setEntryPoint(ChannelEntryPoint entryPoint) { - this.entryPoint = entryPoint; - } - - public ChannelEntryPoint getEntryPoint() { - return entryPoint; - } - - public void setKeyword(String keyword) { - this.keyword = keyword; - } - - public String getKeyword() { - return keyword; - } - - public void setThresold(int thresold) { - this.thresold = thresold; - } - - public int getThresold() { - return thresold; - } + //~ Methods ======================================================================================================== /** * Verify if entryPoint and keyword are ok @@ -109,8 +77,8 @@ public abstract class CaptchaChannelProcessorTemplate Assert.hasLength(keyword, "keyword required"); } - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException { + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException { if ((invocation == null) || (config == null)) { throw new IllegalArgumentException("Nulls cannot be provided"); } @@ -127,12 +95,10 @@ public abstract class CaptchaChannelProcessorTemplate logger.debug("supports this attribute : " + attribute); if (!isContextValidConcerningHumanity(context)) { - logger.debug( - "context is not allowed to access ressource, redirect to captcha entry point"); + logger.debug("context is not allowed to access ressource, redirect to captcha entry point"); redirectToEntryPoint(invocation); } else { - logger.debug( - "has been successfully checked this keyword, increment request count"); + logger.debug("has been successfully checked this keyword, increment request count"); context.incrementHumanRestrictedRessoucesRequestsCount(); } } else { @@ -141,16 +107,19 @@ public abstract class CaptchaChannelProcessorTemplate } } - public boolean supports(ConfigAttribute attribute) { - if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) { - return true; - } else { - return false; - } + public ChannelEntryPoint getEntryPoint() { + return entryPoint; } - abstract boolean isContextValidConcerningHumanity( - CaptchaSecurityContext context); + public String getKeyword() { + return keyword; + } + + public int getThresold() { + return thresold; + } + + abstract boolean isContextValidConcerningHumanity(CaptchaSecurityContext context); private void redirectToEntryPoint(FilterInvocation invocation) throws IOException, ServletException { @@ -160,4 +129,24 @@ public abstract class CaptchaChannelProcessorTemplate entryPoint.commence(invocation.getRequest(), invocation.getResponse()); } + + public void setEntryPoint(ChannelEntryPoint entryPoint) { + this.entryPoint = entryPoint; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public void setThresold(int thresold) { + this.thresold = thresold; + } + + public boolean supports(ConfigAttribute attribute) { + if ((attribute != null) && (keyword.equals(attribute.getAttribute()))) { + return true; + } else { + return false; + } + } } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java index 8238cb8367..fc9467ce82 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.captcha; import org.acegisecurity.securechannel.ChannelEntryPoint; + import org.acegisecurity.util.PortMapper; import org.acegisecurity.util.PortMapperImpl; import org.acegisecurity.util.PortResolver; @@ -43,47 +44,25 @@ import javax.servlet.http.HttpServletResponse; /** - * The captcha entry point : redirect to the captcha test page.
- * - *

- * This entry point can force the use of SSL : see {@link #getForceHttps()}
- *

- * This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}
- * / Original request can be added to the redirect path using a custom - * translation : see {@link #setIncludeOriginalRequest(boolean)}
- * Original request is translated using URLEncoding and the following - * translation mapping in the redirect url : - * - *
    - *
  • - * original url => {@link #getOriginalRequestUrlParameterName()} - *
  • - *
  • - * If {@link #isIncludeOriginalParameters()} - *
  • - *
  • - * original method => {@link #getOriginalRequestMethodParameterName()} - *
  • - *
  • - * original parameters => {@link #getOriginalRequestParametersParameterName()} - *
  • - *
  • - * The original parameters string is contructed using : - * - *
      - *
    • - * a parameter separator {@link #getOriginalRequestParametersSeparator()} - *
    • - *
    • - * a parameter name value pair separator for each parameter {@link - * #getOriginalRequestParametersNameValueSeparator()} - *
    • - *
    - * - *
  • - *
- * - *

+ * The captcha entry point : redirect to the captcha test page.

This entry point can force the use of SSL : + * see {@link #getForceHttps()}

+ * This entry point allows internal OR external redirect : see {@link #setOutsideWebApp(boolean)}
+ * / Original request can be added to the redirect path using a custom translation : see {@link #setIncludeOriginalRequest(boolean)}
+ * Original request is translated using URLEncoding and the following translation mapping in the redirect url : + *
    + *
  • original url => {@link #getOriginalRequestUrlParameterName()}
  • + *
  • If {@link #isIncludeOriginalParameters()}
  • + *
  • original method => {@link #getOriginalRequestMethodParameterName()}
  • + *
  • original parameters => {@link #getOriginalRequestParametersParameterName()}
  • + *
  • The original parameters string is contructed using : + *
      + *
    • a parameter separator {@link #getOriginalRequestParametersSeparator()}
    • + *
    • a parameter name value pair separator for each parameter {@link + * #getOriginalRequestParametersNameValueSeparator()}
    • + *
    + *
  • + *
+ *

* Default values :
* forceHttps = false
* includesOriginalRequest = true
@@ -100,13 +79,13 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== // ~ Static fields/initializers // ============================================= private static final Log logger = LogFactory.getLog(CaptchaEntryPoint.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ // ~ Instance fields // ======================================================== @@ -124,197 +103,24 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { private boolean includeOriginalRequest = true; private boolean isOutsideWebApp = false; - //~ Methods ================================================================ - - /** - * The URL where the CaptchaProcessingFilter login page can be - * found. Should be relative to the web-app context path, and include a - * leading / - * - * @param captchaFormUrl - */ - public void setCaptchaFormUrl(String captchaFormUrl) { - this.captchaFormUrl = captchaFormUrl; - } - - /** - * DOCUMENT ME! - * - * @return the captcha test page to redirect to. - */ - public String getCaptchaFormUrl() { - return captchaFormUrl; - } - - // ~ Methods - // ================================================================ - - /** - * Set to true to force captcha form access to be via https. If this value - * is ture (the default is false), and the incoming request for the - * protected resource which triggered the interceptor was not already - * https, then - * - * @param forceHttps - */ - public void setForceHttps(boolean forceHttps) { - this.forceHttps = forceHttps; - } - - public boolean getForceHttps() { - return forceHttps; - } - - public void setIncludeOriginalParameters(boolean includeOriginalParameters) { - this.includeOriginalParameters = includeOriginalParameters; - } - - public boolean isIncludeOriginalParameters() { - return includeOriginalParameters; - } - - /** - * If set to true, the original request url will be appended to the - * redirect url using the {@link #getOriginalRequestUrlParameterName()}. - * - * @param includeOriginalRequest - */ - public void setIncludeOriginalRequest(boolean includeOriginalRequest) { - this.includeOriginalRequest = includeOriginalRequest; - } - - public boolean isIncludeOriginalRequest() { - return includeOriginalRequest; - } - - public void setOriginalRequestMethodParameterName( - String originalRequestMethodParameterName) { - this.originalRequestMethodParameterName = originalRequestMethodParameterName; - } - - public String getOriginalRequestMethodParameterName() { - return originalRequestMethodParameterName; - } - - public void setOriginalRequestParametersNameValueSeparator( - String originalRequestParametersNameValueSeparator) { - this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator; - } - - public String getOriginalRequestParametersNameValueSeparator() { - return originalRequestParametersNameValueSeparator; - } - - public void setOriginalRequestParametersParameterName( - String originalRequestParametersParameterName) { - this.originalRequestParametersParameterName = originalRequestParametersParameterName; - } - - public String getOriginalRequestParametersParameterName() { - return originalRequestParametersParameterName; - } - - public void setOriginalRequestParametersSeparator( - String originalRequestParametersSeparator) { - this.originalRequestParametersSeparator = originalRequestParametersSeparator; - } - - public String getOriginalRequestParametersSeparator() { - return originalRequestParametersSeparator; - } - - public void setOriginalRequestUrlParameterName( - String originalRequestUrlParameterName) { - this.originalRequestUrlParameterName = originalRequestUrlParameterName; - } - - public String getOriginalRequestUrlParameterName() { - return originalRequestUrlParameterName; - } - - /** - * if set to true, the {@link #commence(ServletRequest, ServletResponse)} - * method uses the {@link #getCaptchaFormUrl()} as a complete URL, else it - * as a 'inside WebApp' path. - * - * @param isOutsideWebApp - */ - public void setOutsideWebApp(boolean isOutsideWebApp) { - this.isOutsideWebApp = isOutsideWebApp; - } - - public boolean isOutsideWebApp() { - return isOutsideWebApp; - } - - public void setPortMapper(PortMapper portMapper) { - this.portMapper = portMapper; - } - - public PortMapper getPortMapper() { - return portMapper; - } - - public void setPortResolver(PortResolver portResolver) { - this.portResolver = portResolver; - } - - public PortResolver getPortResolver() { - return portResolver; - } - - public void setUrlEncodingCharset(String urlEncodingCharset) { - this.urlEncodingCharset = urlEncodingCharset; - } - - public String getUrlEncodingCharset() { - return urlEncodingCharset; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(captchaFormUrl, "captchaFormUrl must be specified"); - Assert.hasLength(originalRequestMethodParameterName, - "originalRequestMethodParameterName must be specified"); + Assert.hasLength(originalRequestMethodParameterName, "originalRequestMethodParameterName must be specified"); Assert.hasLength(originalRequestParametersNameValueSeparator, "originalRequestParametersNameValueSeparator must be specified"); Assert.hasLength(originalRequestParametersParameterName, "originalRequestParametersParameterName must be specified"); - Assert.hasLength(originalRequestParametersSeparator, - "originalRequestParametersSeparator must be specified"); - Assert.hasLength(originalRequestUrlParameterName, - "originalRequestUrlParameterName must be specified"); - Assert.hasLength(urlEncodingCharset, - "urlEncodingCharset must be specified"); + Assert.hasLength(originalRequestParametersSeparator, "originalRequestParametersSeparator must be specified"); + Assert.hasLength(originalRequestUrlParameterName, "originalRequestUrlParameterName must be specified"); + Assert.hasLength(urlEncodingCharset, "urlEncodingCharset must be specified"); Assert.notNull(portMapper, "portMapper must be specified"); Assert.notNull(portResolver, "portResolver must be specified"); URLEncoder.encode(" fzaef é& à ", urlEncodingCharset); } - public void commence(ServletRequest request, ServletResponse response) - throws IOException, ServletException { - StringBuffer redirectUrl = new StringBuffer(); - HttpServletRequest req = (HttpServletRequest) request; - - if (isOutsideWebApp) { - redirectUrl = redirectUrl.append(captchaFormUrl); - } else { - buildInternalRedirect(redirectUrl, req); - } - - if (includeOriginalRequest) { - includeOriginalRequest(redirectUrl, req); - } - - // add post parameter? DONE! - if (logger.isDebugEnabled()) { - logger.debug("Redirecting to: " + redirectUrl); - } - - ((HttpServletResponse) response).sendRedirect(redirectUrl.toString()); - } - - private void buildInternalRedirect(StringBuffer redirectUrl, - HttpServletRequest req) { + private void buildInternalRedirect(StringBuffer redirectUrl, HttpServletRequest req) { // construct it StringBuffer simpleRedirect = new StringBuffer(); @@ -373,8 +179,75 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { } } - private void includeOriginalRequest(StringBuffer redirectUrl, - HttpServletRequest req) { + public void commence(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + StringBuffer redirectUrl = new StringBuffer(); + HttpServletRequest req = (HttpServletRequest) request; + + if (isOutsideWebApp) { + redirectUrl = redirectUrl.append(captchaFormUrl); + } else { + buildInternalRedirect(redirectUrl, req); + } + + if (includeOriginalRequest) { + includeOriginalRequest(redirectUrl, req); + } + + // add post parameter? DONE! + if (logger.isDebugEnabled()) { + logger.debug("Redirecting to: " + redirectUrl); + } + + ((HttpServletResponse) response).sendRedirect(redirectUrl.toString()); + } + + /** + * DOCUMENT ME! + * + * @return the captcha test page to redirect to. + */ + public String getCaptchaFormUrl() { + return captchaFormUrl; + } + + public boolean getForceHttps() { + return forceHttps; + } + + public String getOriginalRequestMethodParameterName() { + return originalRequestMethodParameterName; + } + + public String getOriginalRequestParametersNameValueSeparator() { + return originalRequestParametersNameValueSeparator; + } + + public String getOriginalRequestParametersParameterName() { + return originalRequestParametersParameterName; + } + + public String getOriginalRequestParametersSeparator() { + return originalRequestParametersSeparator; + } + + public String getOriginalRequestUrlParameterName() { + return originalRequestUrlParameterName; + } + + public PortMapper getPortMapper() { + return portMapper; + } + + public PortResolver getPortResolver() { + return portResolver; + } + + public String getUrlEncodingCharset() { + return urlEncodingCharset; + } + + private void includeOriginalRequest(StringBuffer redirectUrl, HttpServletRequest req) { // add original request to the url if (redirectUrl.indexOf("?") >= 0) { redirectUrl.append("&"); @@ -386,8 +259,7 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { redirectUrl.append("="); try { - redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(), - urlEncodingCharset)); + redirectUrl.append(URLEncoder.encode(req.getRequestURL().toString(), urlEncodingCharset)); } catch (UnsupportedEncodingException e) { logger.warn(e); } @@ -423,11 +295,101 @@ public class CaptchaEntryPoint implements ChannelEntryPoint, InitializingBean { } try { - redirectUrl.append(URLEncoder.encode(qp.toString(), - urlEncodingCharset)); + redirectUrl.append(URLEncoder.encode(qp.toString(), urlEncodingCharset)); } catch (Exception e) { logger.warn(e); } } } + + public boolean isIncludeOriginalParameters() { + return includeOriginalParameters; + } + + public boolean isIncludeOriginalRequest() { + return includeOriginalRequest; + } + + public boolean isOutsideWebApp() { + return isOutsideWebApp; + } + + /** + * The URL where the CaptchaProcessingFilter login page can be found. Should be relative to + * the web-app context path, and include a leading / + * + * @param captchaFormUrl + */ + public void setCaptchaFormUrl(String captchaFormUrl) { + this.captchaFormUrl = captchaFormUrl; + } + + // ~ Methods + // ================================================================ + /** + * Set to true to force captcha form access to be via https. If this value is ture (the default is false), + * and the incoming request for the protected resource which triggered the interceptor was not already + * https, then + * + * @param forceHttps + */ + public void setForceHttps(boolean forceHttps) { + this.forceHttps = forceHttps; + } + + public void setIncludeOriginalParameters(boolean includeOriginalParameters) { + this.includeOriginalParameters = includeOriginalParameters; + } + + /** + * If set to true, the original request url will be appended to the redirect url using the {@link + * #getOriginalRequestUrlParameterName()}. + * + * @param includeOriginalRequest + */ + public void setIncludeOriginalRequest(boolean includeOriginalRequest) { + this.includeOriginalRequest = includeOriginalRequest; + } + + public void setOriginalRequestMethodParameterName(String originalRequestMethodParameterName) { + this.originalRequestMethodParameterName = originalRequestMethodParameterName; + } + + public void setOriginalRequestParametersNameValueSeparator(String originalRequestParametersNameValueSeparator) { + this.originalRequestParametersNameValueSeparator = originalRequestParametersNameValueSeparator; + } + + public void setOriginalRequestParametersParameterName(String originalRequestParametersParameterName) { + this.originalRequestParametersParameterName = originalRequestParametersParameterName; + } + + public void setOriginalRequestParametersSeparator(String originalRequestParametersSeparator) { + this.originalRequestParametersSeparator = originalRequestParametersSeparator; + } + + public void setOriginalRequestUrlParameterName(String originalRequestUrlParameterName) { + this.originalRequestUrlParameterName = originalRequestUrlParameterName; + } + + /** + * if set to true, the {@link #commence(ServletRequest, ServletResponse)} method uses the {@link + * #getCaptchaFormUrl()} as a complete URL, else it as a 'inside WebApp' path. + * + * @param isOutsideWebApp + */ + public void setOutsideWebApp(boolean isOutsideWebApp) { + this.isOutsideWebApp = isOutsideWebApp; + } + + public void setPortMapper(PortMapper portMapper) { + this.portMapper = portMapper; + } + + public void setPortResolver(PortResolver portResolver) { + this.portResolver = portResolver; + } + + public void setUrlEncodingCharset(String urlEncodingCharset) { + this.urlEncodingCharset = urlEncodingCharset; + } } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java index 14f37ca536..6a04dae869 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContext.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +24,26 @@ import org.acegisecurity.context.SecurityContext; * @author marc antoine garrigue */ public interface CaptchaSecurityContext extends SecurityContext { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * set human attribute, should called after captcha validation. + * DOCUMENT ME! + * + * @return number of human restricted resources requests since the last passed captcha. */ - void setHuman(); + int getHumanRestrictedResourcesRequestsCount(); + + /** + * DOCUMENT ME! + * + * @return the date of the last passed Captcha in millis, 0 if the user never passed captcha. + */ + long getLastPassedCaptchaDateInMillis(); + + /** + * Method to increment the human Restricted Resrouces Requests Count; + */ + void incrementHumanRestrictedRessoucesRequestsCount(); /** * DOCUMENT ME! @@ -39,23 +53,7 @@ public interface CaptchaSecurityContext extends SecurityContext { boolean isHuman(); /** - * DOCUMENT ME! - * - * @return number of human restricted resources requests since the last - * passed captcha. + * set human attribute, should called after captcha validation. */ - int getHumanRestrictedResourcesRequestsCount(); - - /** - * DOCUMENT ME! - * - * @return the date of the last passed Captcha in millis, 0 if the user - * never passed captcha. - */ - long getLastPassedCaptchaDateInMillis(); - - /** - * Method to increment the human Restricted Resrouces Requests Count; - */ - void incrementHumanRestrictedRessoucesRequestsCount(); + void setHuman(); } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContextImpl.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContextImpl.java index 4029f17ddf..7b1c76bd9e 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContextImpl.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaSecurityContextImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,15 +23,14 @@ import org.acegisecurity.context.SecurityContextImpl; * * @author mag */ -public class CaptchaSecurityContextImpl extends SecurityContextImpl - implements CaptchaSecurityContext { - //~ Instance fields ======================================================== +public class CaptchaSecurityContextImpl extends SecurityContextImpl implements CaptchaSecurityContext { + //~ Instance fields ================================================================================================ private boolean human; private int humanRestrictedResourcesRequestsCount; private long lastPassedCaptchaDate; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CaptchaSecurityContextImpl() { super(); @@ -40,19 +39,28 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl humanRestrictedResourcesRequestsCount = 0; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - /** - * Reset the lastPassedCaptchaDate and count. - */ - public void setHuman() { - this.human = true; - this.lastPassedCaptchaDate = System.currentTimeMillis(); - this.humanRestrictedResourcesRequestsCount = 0; - } + public boolean equals(Object obj) { + if (obj instanceof CaptchaSecurityContextImpl) { + CaptchaSecurityContextImpl rhs = (CaptchaSecurityContextImpl) obj; - public boolean isHuman() { - return human; + if (this.isHuman() != rhs.isHuman()) { + return false; + } + + if (this.getHumanRestrictedResourcesRequestsCount() != rhs.getHumanRestrictedResourcesRequestsCount()) { + return false; + } + + if (this.getLastPassedCaptchaDateInMillis() != rhs.getLastPassedCaptchaDateInMillis()) { + return false; + } + + return super.equals(obj); + } + + return false; } public int getHumanRestrictedResourcesRequestsCount() { @@ -63,6 +71,18 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl return lastPassedCaptchaDate; } + public int hashCode() { + int code = super.hashCode(); + code ^= this.humanRestrictedResourcesRequestsCount; + code ^= this.lastPassedCaptchaDate; + + if (this.isHuman()) { + code ^= -37; + } + + return code; + } + /** * Method to increment the human Restricted Resrouces Requests Count; */ @@ -70,30 +90,16 @@ public class CaptchaSecurityContextImpl extends SecurityContextImpl humanRestrictedResourcesRequestsCount++; } - public boolean equals(Object obj) { - if (obj instanceof CaptchaSecurityContextImpl) { - CaptchaSecurityContextImpl rhs = (CaptchaSecurityContextImpl) obj; - if (this.isHuman() != rhs.isHuman()) { - return false; - } - if (this.getHumanRestrictedResourcesRequestsCount() != rhs.getHumanRestrictedResourcesRequestsCount()) { - return false; - } - if (this.getLastPassedCaptchaDateInMillis() != rhs.getLastPassedCaptchaDateInMillis()) { - return false; - } - return super.equals(obj); - } - return false; - } + public boolean isHuman() { + return human; + } - public int hashCode() { - int code = super.hashCode(); - code ^= this.humanRestrictedResourcesRequestsCount; - code ^= this.lastPassedCaptchaDate; - if (this.isHuman()) { - code ^= -37; - } - return code; - } + /** + * Reset the lastPassedCaptchaDate and count. + */ + public void setHuman() { + this.human = true; + this.lastPassedCaptchaDate = System.currentTimeMillis(); + this.humanRestrictedResourcesRequestsCount = 0; + } } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java index bce9d921dd..c2c1360927 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaServiceProxy.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ package org.acegisecurity.captcha; - - /** * Provide a common interface for captcha validation. * @@ -24,7 +22,7 @@ package org.acegisecurity.captcha; * @version $Id$ */ public interface CaptchaServiceProxy { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * DOCUMENT ME! @@ -32,8 +30,7 @@ public interface CaptchaServiceProxy { * @param id the id token * @param captchaResponse the user response * - * @return true if the response is validated by the back end captcha - * service. + * @return true if the response is validated by the back end captcha service. */ boolean validateReponseForId(String id, Object captchaResponse); } diff --git a/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java b/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java index c467d9aea2..f9a6974bf5 100644 --- a/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,64 +31,39 @@ import javax.servlet.http.HttpSession; /** * Filter for web integration of the {@link CaptchaServiceProxy}.
- * It basically intercept calls containing the specific validation parameter, - * use the {@link CaptchaServiceProxy} to validate the request, and update the - * {@link CaptchaSecurityContext} if the request passed the validation.
- * This Filter should be placed after the ContextIntegration filter and before - * the {@link CaptchaChannelProcessorTemplate} filter in the filter stack in - * order to update the {@link CaptchaSecurityContext} before the humanity - * verification routine occurs.
- * This filter should only be used in conjunction with the {@link - * CaptchaSecurityContext}
+ * It basically intercept calls containing the specific validation parameter, use the {@link CaptchaServiceProxy} to + * validate the request, and update the {@link CaptchaSecurityContext} if the request passed the validation.
+ * This Filter should be placed after the ContextIntegration filter and before the {@link + * CaptchaChannelProcessorTemplate} filter in the filter stack in order to update the {@link CaptchaSecurityContext} + * before the humanity verification routine occurs.
+ * This filter should only be used in conjunction with the {@link CaptchaSecurityContext}
* * @author marc antoine Garrigue * @version $Id$ */ -public class CaptchaValidationProcessingFilter implements InitializingBean, - Filter { - //~ Static fields/initializers ============================================= +public class CaptchaValidationProcessingFilter implements InitializingBean, Filter { + //~ Static fields/initializers ===================================================================================== // ~ Static fields/initializers // ============================================= protected static final Log logger = LogFactory.getLog(CaptchaValidationProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ // ~ Instance fields // ======================================================== private CaptchaServiceProxy captchaService; private String captchaValidationParameter = "_captcha_parameter"; - //~ Methods ================================================================ - - public void setCaptchaService(CaptchaServiceProxy captchaService) { - this.captchaService = captchaService; - } - - // ~ Methods - // ================================================================ - public CaptchaServiceProxy getCaptchaService() { - return captchaService; - } - - public void setCaptchaValidationParameter(String captchaValidationParameter) { - this.captchaValidationParameter = captchaValidationParameter; - } - - public String getCaptchaValidationParameter() { - return captchaValidationParameter; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { if (this.captchaService == null) { - throw new IllegalArgumentException( - "CaptchaServiceProxy must be defined "); + throw new IllegalArgumentException("CaptchaServiceProxy must be defined "); } - if ((this.captchaValidationParameter == null) - || "".equals(captchaValidationParameter)) { - throw new IllegalArgumentException( - "captchaValidationParameter must not be empty or null"); + if ((this.captchaValidationParameter == null) || "".equals(captchaValidationParameter)) { + throw new IllegalArgumentException("captchaValidationParameter must not be empty or null"); } } @@ -97,12 +72,11 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { String captcha_reponse = request.getParameter(captchaValidationParameter); - if ((request != null) && request instanceof HttpServletRequest - && (captcha_reponse != null)) { + if ((request != null) && request instanceof HttpServletRequest && (captcha_reponse != null)) { logger.debug("captcha validation parameter found"); // validate the request against CaptchaServiceProxy @@ -115,23 +89,19 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, if (session != null) { String id = session.getId(); - valid = this.captchaService.validateReponseForId(id, - captcha_reponse); - logger.debug("captchaServiceProxy says : request is valid = " - + valid); + valid = this.captchaService.validateReponseForId(id, captcha_reponse); + logger.debug("captchaServiceProxy says : request is valid = " + valid); if (valid) { logger.debug("update the context"); - ((CaptchaSecurityContext) SecurityContextHolder.getContext()) - .setHuman(); + ((CaptchaSecurityContext) SecurityContextHolder.getContext()).setHuman(); //logger.debug("retrieve original request from ") } else { logger.debug("captcha test failed"); } } else { - logger.debug( - "no session found, user don't even ask a captcha challenge"); + logger.debug("no session found, user don't even ask a captcha challenge"); } } else { logger.debug("captcha validation parameter not found, do nothing"); @@ -144,6 +114,16 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, chain.doFilter(request, response); } + // ~ Methods + // ================================================================ + public CaptchaServiceProxy getCaptchaService() { + return captchaService; + } + + public String getCaptchaValidationParameter() { + return captchaValidationParameter; + } + /** * Does nothing. We use IoC container lifecycle services instead. * @@ -152,4 +132,12 @@ public class CaptchaValidationProcessingFilter implements InitializingBean, * @throws ServletException ignored */ public void init(FilterConfig filterConfig) throws ServletException {} + + public void setCaptchaService(CaptchaServiceProxy captchaService) { + this.captchaService = captchaService; + } + + public void setCaptchaValidationParameter(String captchaValidationParameter) { + this.captchaValidationParameter = captchaValidationParameter; + } } diff --git a/core/src/main/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessor.java b/core/src/main/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessor.java index 901ca1406c..e2503e64d8 100644 --- a/core/src/main/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,43 +12,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.captcha; /** - *

- * return false if ny CaptchaChannelProcessorTemplate mapped urls has been - * requested more than thresold and humanity is false;
- * Default keyword : REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS - *

+ *

return false if ny CaptchaChannelProcessorTemplate mapped urls has been requested more than thresold and + * humanity is false;
+ * Default keyword : REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS

* * @author Marc-Antoine Garrigue * @version $Id$ */ -public class TestOnceAfterMaxRequestsCaptchaChannelProcessor - extends CaptchaChannelProcessorTemplate { - //~ Static fields/initializers ============================================= +public class TestOnceAfterMaxRequestsCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate { + //~ Static fields/initializers ===================================================================================== public static final String DEFAULT_KEYWORD = "REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public TestOnceAfterMaxRequestsCaptchaChannelProcessor() { super(); this.setKeyword(DEFAULT_KEYWORD); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) { - if (context.isHuman() - || (context.getHumanRestrictedResourcesRequestsCount() < getThresold())) { - logger.debug( - "context is valid concerning humanity or request count < thresold"); + if (context.isHuman() || (context.getHumanRestrictedResourcesRequestsCount() < getThresold())) { + logger.debug("context is valid concerning humanity or request count < thresold"); return true; } else { - logger.debug( - "context is not valid concerning humanity and request count > thresold"); + logger.debug("context is not valid concerning humanity and request count > thresold"); return false; } diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentLoginException.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentLoginException.java index a4e53c9428..e08f7e7845 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentLoginException.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentLoginException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,20 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.concurrent; import org.acegisecurity.AuthenticationException; /** - * Thrown by ConcurrentSessionControllerImpl if - * an attempt is made to login and the user has already exceeded - * their maxmimum allowed sessions. + * Thrown by ConcurrentSessionControllerImpl if an attempt is made to login and the user has already + * exceeded their maxmimum allowed sessions. * * @author Ben Alex * @version $Id$ */ public class ConcurrentLoginException extends AuthenticationException { + //~ Constructors =================================================================================================== + public ConcurrentLoginException(String msg) { super(msg); } diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionController.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionController.java index 136d7d85c2..9d349ab16a 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionController.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,38 +28,28 @@ import org.acegisecurity.AuthenticationException; * @version $Id$ */ public interface ConcurrentSessionController { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Called by any class that wishes to know whether the current - * authentication request should be permitted. Generally callers will be - * AuthenticationManagers before they authenticate, but could - * equally include Filters or other interceptors that wish to - * confirm the ongoing validity of a previously authenticated - * Authentication. - * - *

- * The implementation should throw a suitable exception if the user has - * exceeded their maximum allowed concurrent sessions. - *

+ * Called by any class that wishes to know whether the current authentication request should be permitted. + * Generally callers will be AuthenticationManagers before they authenticate, but could equally + * include Filters or other interceptors that wish to confirm the ongoing validity of a previously + * authenticated Authentication.

The implementation should throw a suitable exception if the + * user has exceeded their maximum allowed concurrent sessions.

* * @param request the authentication request (never null) * - * @throws AuthenticationException if the user has exceeded their maximum - * allowed current sessions + * @throws AuthenticationException if the user has exceeded their maximum allowed current sessions */ public void checkAuthenticationAllowed(Authentication request) throws AuthenticationException; /** - * Called by an AuthenticationManager when the authentication - * was successful. An implementation is expected to register the - * authenticated user in some sort of registry, for future concurrent - * tracking via the {@link #checkConcurrentAuthentication(Authentication)} - * method. + * Called by an AuthenticationManager when the authentication was successful. An + * implementation is expected to register the authenticated user in some sort of registry, for future concurrent + * tracking via the {@link #checkConcurrentAuthentication(Authentication)} method. * - * @param authentication the successfully authenticated user (never - * null) + * @param authentication the successfully authenticated user (never null) */ public void registerSuccessfulAuthentication(Authentication authentication); } diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java index 5ffc2e3f2f..632798ef84 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java @@ -29,29 +29,22 @@ import org.springframework.util.Assert; /** - * Base implementation of {@link ConcurrentSessionControllerImpl} which - * prohibits simultaneous logins. - * - *

- * By default uses {@link SessionRegistryImpl}, although any - * SessionRegistry may be used. - *

+ * Base implementation of {@link ConcurrentSessionControllerImpl} which prohibits simultaneous logins.

By default + * uses {@link SessionRegistryImpl}, although any SessionRegistry may be used.

* * @author Ben Alex * @version $Id$ */ -public class ConcurrentSessionControllerImpl - implements ConcurrentSessionController, InitializingBean, - MessageSourceAware { - //~ Instance fields ======================================================== +public class ConcurrentSessionControllerImpl implements ConcurrentSessionController, InitializingBean, + MessageSourceAware { + //~ Instance fields ================================================================================================ - protected MessageSourceAccessor messages = AcegiMessageSource - .getAccessor(); + protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private SessionRegistry sessionRegistry = new SessionRegistryImpl(); private boolean exceptionIfMaximumExceeded = false; private int maximumSessions = 1; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(sessionRegistry, "SessionRegistry required"); @@ -61,35 +54,27 @@ public class ConcurrentSessionControllerImpl } /** - * Allows subclasses to customise behaviour when too many sessions are - * detected. + * Allows subclasses to customise behaviour when too many sessions are detected. * * @param sessionId the session ID of the present request - * @param sessions either null or all unexpired sessions - * associated with the principal + * @param sessions either null or all unexpired sessions associated with the principal * @param allowableSessions DOCUMENT ME! - * @param registry an instance of the SessionRegistry for - * subclass use + * @param registry an instance of the SessionRegistry for subclass use * * @throws ConcurrentLoginException DOCUMENT ME! */ - protected void allowableSessionsExceeded(String sessionId, - SessionInformation[] sessions, int allowableSessions, + protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions, SessionRegistry registry) { if (exceptionIfMaximumExceeded || (sessions == null)) { - throw new ConcurrentLoginException(messages.getMessage( - "ConcurrentSessionControllerImpl.exceededAllowed", - new Object[] {new Integer(allowableSessions)}, - "Maximum sessions of {0} for this principal exceeded")); + throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed", + new Object[] {new Integer(allowableSessions)}, "Maximum sessions of {0} for this principal exceeded")); } // Determine least recently used session, and mark it for invalidation SessionInformation leastRecentlyUsed = null; for (int i = 0; i < sessions.length; i++) { - if ((leastRecentlyUsed == null) - || sessions[i].getLastRequest() - .before(leastRecentlyUsed.getLastRequest())) { + if ((leastRecentlyUsed == null) || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) { leastRecentlyUsed = sessions[i]; } } @@ -99,16 +84,12 @@ public class ConcurrentSessionControllerImpl public void checkAuthenticationAllowed(Authentication request) throws AuthenticationException { - Assert.notNull(request, - "Authentication request cannot be null (violation of interface contract)"); + Assert.notNull(request, "Authentication request cannot be null (violation of interface contract)"); - Object principal = SessionRegistryUtils - .obtainPrincipalFromAuthentication(request); - String sessionId = SessionRegistryUtils - .obtainSessionIdFromAuthentication(request); + Object principal = SessionRegistryUtils.obtainPrincipalFromAuthentication(request); + String sessionId = SessionRegistryUtils.obtainSessionIdFromAuthentication(request); - SessionInformation[] sessions = sessionRegistry.getAllSessions(principal, - false); + SessionInformation[] sessions = sessionRegistry.getAllSessions(principal, false); int sessionCount = 0; @@ -121,11 +102,11 @@ public class ConcurrentSessionControllerImpl "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum"); if (sessionCount < allowableSessions) { - // They haven't got too many login sessions running at present + // They haven't got too many login sessions running at present return; } else if (allowableSessions == -1) { - // We permit unlimited logins - return; + // We permit unlimited logins + return; } else if (sessionCount == allowableSessions) { // Only permit it though if this request is associated with one of the sessions for (int i = 0; i < sessionCount; i++) { @@ -135,40 +116,33 @@ public class ConcurrentSessionControllerImpl } } - allowableSessionsExceeded(sessionId, sessions, allowableSessions, - sessionRegistry); + allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry); } /** - * Method intended for use by subclasses to override the maximum number of - * sessions that are permitted for a particular authentication. The - * default implementation simply returns the maximumSessions - * value for the bean. + * Method intended for use by subclasses to override the maximum number of sessions that are permitted for + * a particular authentication. The default implementation simply returns the maximumSessions value + * for the bean. * * @param authentication to determine the maximum sessions for * - * @return either -1 meaning unlimited, or a positive integer to limit - * (never zero) + * @return either -1 meaning unlimited, or a positive integer to limit (never zero) */ protected int getMaximumSessionsForThisUser(Authentication authentication) { return maximumSessions; } public void registerSuccessfulAuthentication(Authentication authentication) { - Assert.notNull(authentication, - "Authentication cannot be null (violation of interface contract)"); + Assert.notNull(authentication, "Authentication cannot be null (violation of interface contract)"); - Object principal = SessionRegistryUtils - .obtainPrincipalFromAuthentication(authentication); - String sessionId = SessionRegistryUtils - .obtainSessionIdFromAuthentication(authentication); + Object principal = SessionRegistryUtils.obtainPrincipalFromAuthentication(authentication); + String sessionId = SessionRegistryUtils.obtainSessionIdFromAuthentication(authentication); sessionRegistry.removeSessionInformation(sessionId); sessionRegistry.registerNewSession(sessionId, principal); } - public void setExceptionIfMaximumExceeded( - boolean exceptionIfMaximumExceeded) { + public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) { this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded; } diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionFilter.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionFilter.java index 3f75dfe415..2b14ec5434 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionFilter.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,42 +33,25 @@ import javax.servlet.http.HttpSession; /** - * Filter required by concurrent session handling package. - * - *

- * This filter performs two functions. First, it calls {@link - * org.acegisecurity.concurrent.SessionRegistry#refreshLastRequest(String)} - * for each request. That way, registered sessions always have a correct "last - * update" date/time. Second, it retrieves {@link - * org.acegisecurity.concurrent.SessionInformation} from the - * SessionRegistry for each request and checks if the session has - * been marked as expired. If it has been marked as expired, the session is - * invalidated. The invalidation of the session will also cause the request to - * redirect to the URL specified, and a {@link - * org.acegisecurity.ui.session.HttpSessionDestroyedEvent} to be published - * via the {@link org.acegisecurity.ui.session.HttpSessionEventPublisher} - * registered in web.xml. - *

+ * Filter required by concurrent session handling package.

This filter performs two functions. First, it calls + * {@link org.acegisecurity.concurrent.SessionRegistry#refreshLastRequest(String)} for each request. That way, + * registered sessions always have a correct "last update" date/time. Second, it retrieves {@link + * org.acegisecurity.concurrent.SessionInformation} from the SessionRegistry for each request and checks + * if the session has been marked as expired. If it has been marked as expired, the session is invalidated. The + * invalidation of the session will also cause the request to redirect to the URL specified, and a {@link + * org.acegisecurity.ui.session.HttpSessionDestroyedEvent} to be published via the {@link + * org.acegisecurity.ui.session.HttpSessionEventPublisher} registered in web.xml.

* * @author Ben Alex * @version $Id$ */ -public class ConcurrentSessionFilter implements Filter, - InitializingBean { - //~ Instance fields ======================================================== +public class ConcurrentSessionFilter implements Filter, InitializingBean { + //~ Instance fields ================================================================================================ private SessionRegistry sessionRegistry; private String expiredUrl; - //~ Methods ================================================================ - - public void setExpiredUrl(String expiredUrl) { - this.expiredUrl = expiredUrl; - } - - public void setSessionRegistry(SessionRegistry sessionRegistry) { - this.sessionRegistry = sessionRegistry; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(sessionRegistry, "SessionRegistry required"); @@ -80,12 +63,10 @@ public class ConcurrentSessionFilter implements Filter, */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - Assert.isInstanceOf(HttpServletRequest.class, request, - "Can only process HttpServletRequest"); - Assert.isInstanceOf(HttpServletResponse.class, response, - "Can only process HttpServletResponse"); + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + Assert.isInstanceOf(HttpServletRequest.class, request, "Can only process HttpServletRequest"); + Assert.isInstanceOf(HttpServletResponse.class, response, "Can only process HttpServletResponse"); HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; @@ -93,18 +74,15 @@ public class ConcurrentSessionFilter implements Filter, HttpSession session = httpRequest.getSession(false); if (session != null) { - SessionInformation info = sessionRegistry.getSessionInformation(session - .getId()); + SessionInformation info = sessionRegistry.getSessionInformation(session.getId()); if (info != null) { if (info.isExpired()) { // Expired - abort processing session.invalidate(); - String targetUrl = httpRequest.getContextPath() - + expiredUrl; - httpResponse.sendRedirect(httpResponse.encodeRedirectURL( - targetUrl)); + String targetUrl = httpRequest.getContextPath() + expiredUrl; + httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl)); return; } else { @@ -125,4 +103,12 @@ public class ConcurrentSessionFilter implements Filter, * @throws ServletException ignored */ public void init(FilterConfig arg0) throws ServletException {} + + public void setExpiredUrl(String expiredUrl) { + this.expiredUrl = expiredUrl; + } + + public void setSessionRegistry(SessionRegistry sessionRegistry) { + this.sessionRegistry = sessionRegistry; + } } diff --git a/core/src/main/java/org/acegisecurity/concurrent/NullConcurrentSessionController.java b/core/src/main/java/org/acegisecurity/concurrent/NullConcurrentSessionController.java index b5b88d80ea..89fed013b3 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/NullConcurrentSessionController.java +++ b/core/src/main/java/org/acegisecurity/concurrent/NullConcurrentSessionController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,15 +20,13 @@ import org.acegisecurity.AuthenticationException; /** - * No-op implementation of {@link - * org.acegisecurity.concurrent.ConcurrentSessionController}. + * No-op implementation of {@link org.acegisecurity.concurrent.ConcurrentSessionController}. * * @author Ben Alex * @version $Id$ */ -public class NullConcurrentSessionController - implements ConcurrentSessionController { - //~ Methods ================================================================ +public class NullConcurrentSessionController implements ConcurrentSessionController { + //~ Methods ======================================================================================================== public void checkAuthenticationAllowed(Authentication request) throws AuthenticationException {} diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionAlreadyUsedException.java b/core/src/main/java/org/acegisecurity/concurrent/SessionAlreadyUsedException.java index 09fe896693..7da9c6fd15 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionAlreadyUsedException.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionAlreadyUsedException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,20 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.concurrent; import org.acegisecurity.AuthenticationException; /** - * Thrown by a SessionRegistry implementation if - * an attempt is made to create new session information for an existing - * sessionId. The user should firstly clear the existing session from the + * Thrown by a SessionRegistry implementation if an attempt is made to create new session information + * for an existing sessionId. The user should firstly clear the existing session from the * ConcurrentSessionRegistry. * * @author Ben Alex */ public class SessionAlreadyUsedException extends AuthenticationException { + //~ Constructors =================================================================================================== + public SessionAlreadyUsedException(String msg) { super(msg); } diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionIdentifierAware.java b/core/src/main/java/org/acegisecurity/concurrent/SessionIdentifierAware.java index 9b46a34573..a075eefa1b 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionIdentifierAware.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionIdentifierAware.java @@ -33,7 +33,7 @@ package org.acegisecurity.concurrent; * @version $Id$ */ public interface SessionIdentifierAware { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains the session ID. diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionInformation.java b/core/src/main/java/org/acegisecurity/concurrent/SessionInformation.java index 1d274ddb6a..f171f534aa 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionInformation.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionInformation.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,38 +21,28 @@ import java.util.Date; /** - * Represents a record of a session within the Acegi Security framework. - * - *

- * This is primarily used for concurrent session support. - *

- * - *

- * Sessions have three states: active, expired, and destroyed. A session can - * that is invalidated by session.invalidate() or via Servlet - * Container management is considered "destroyed". An "expired" session, on - * the other hand, is a session that Acegi Security wants to end because it - * was selected for removal for some reason (generally as it was the least - * recently used session and the maximum sessions for the user were reached). - * An "expired" session is removed as soon as possible by a - * Filter. - *

+ * Represents a record of a session within the Acegi Security framework.

This is primarily used for concurrent + * session support.

+ *

Sessions have three states: active, expired, and destroyed. A session can that is invalidated by + * session.invalidate() or via Servlet Container management is considered "destroyed". An "expired" + * session, on the other hand, is a session that Acegi Security wants to end because it was selected for removal for + * some reason (generally as it was the least recently used session and the maximum sessions for the user were + * reached). An "expired" session is removed as soon as possible by a Filter.

* * @author Ben Alex * @version $Id$ */ public class SessionInformation { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Date lastRequest; private Object principal; private String sessionId; private boolean expired = false; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public SessionInformation(Object principal, String sessionId, - Date lastRequest) { + public SessionInformation(Object principal, String sessionId, Date lastRequest) { Assert.notNull(principal, "Principal required"); Assert.hasText(sessionId, "SessionId required"); Assert.notNull(lastRequest, "LastRequest required"); @@ -63,10 +53,10 @@ public class SessionInformation { private SessionInformation() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public boolean isExpired() { - return expired; + public void expireNow() { + this.expired = true; } public Date getLastRequest() { @@ -81,8 +71,8 @@ public class SessionInformation { return sessionId; } - public void expireNow() { - this.expired = true; + public boolean isExpired() { + return expired; } /** diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java index 2eccd0d8f9..27c01d485d 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java @@ -22,37 +22,30 @@ package org.acegisecurity.concurrent; * @version $Id$ */ public interface SessionRegistry { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains all the known principals in the SessionRegistry. * - * @return each of the unique principals, which can then be presented to - * {@link #getAllSessions(Object)}. + * @return each of the unique principals, which can then be presented to {@link #getAllSessions(Object)}. */ public Object[] getAllPrincipals(); /** - * Obtains all the known sessions for the specified principal. Sessions - * that have been destroyed are not returned. Sessions that have expired - * may be returned, depending on the passed argument. + * Obtains all the known sessions for the specified principal. Sessions that have been destroyed are not + * returned. Sessions that have expired may be returned, depending on the passed argument. * - * @param principal to locate sessions for (should never be - * null) - * @param includeExpiredSessions if true, the returned - * sessions will also include those that have expired for the - * principal + * @param principal to locate sessions for (should never be null) + * @param includeExpiredSessions if true, the returned sessions will also include those that have + * expired for the principal * - * @return the matching sessions for this principal, or null - * if none were found + * @return the matching sessions for this principal, or null if none were found */ - public SessionInformation[] getAllSessions(Object principal, - boolean includeExpiredSessions); + public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions); /** - * Obtains the session information for the specified - * sessionId. Even expired sessions are returned (although - * destroyed sessions are never returned). + * Obtains the session information for the specified sessionId. Even expired sessions are + * returned (although destroyed sessions are never returned). * * @param sessionId to lookup (should never be null) * @@ -61,24 +54,19 @@ public interface SessionRegistry { public SessionInformation getSessionInformation(String sessionId); /** - * Updates the given sessionId so its last request time is - * equal to the present date and time. Silently returns if the given - * sessionId cannot be found or the session is marked to - * expire. + * Updates the given sessionId so its last request time is equal to the present date and time. + * Silently returns if the given sessionId cannot be found or the session is marked to expire. * - * @param sessionId for which to update the date and time of the last - * request (should never be null) + * @param sessionId for which to update the date and time of the last request (should never be null) */ public void refreshLastRequest(String sessionId); /** - * Registers a new session for the specified principal. The newly - * registered session will not be marked for expiration. + * Registers a new session for the specified principal. The newly registered session will not be marked for + * expiration. * - * @param sessionId to associate with the principal (should never be - * null) - * @param principal to associate with the session (should never be - * null) + * @param sessionId to associate with the principal (should never be null) + * @param principal to associate with the session (should never be null) * * @throws SessionAlreadyUsedException DOCUMENT ME! */ @@ -86,12 +74,10 @@ public interface SessionRegistry { throws SessionAlreadyUsedException; /** - * Deletes all the session information being maintained for the specified - * sessionId. If the sessionId is not found, the - * method gracefully returns. + * Deletes all the session information being maintained for the specified sessionId. If the + * sessionId is not found, the method gracefully returns. * - * @param sessionId to delete information for (should never be - * null) + * @param sessionId to delete information for (should never be null) */ public void removeSessionInformation(String sessionId); } diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryUtils.java b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryUtils.java index 671f17f6b2..e4bb621235 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryUtils.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryUtils.java @@ -29,12 +29,11 @@ import org.springframework.util.Assert; * @version $Id$ */ public class SessionRegistryUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static Object obtainPrincipalFromAuthentication(Authentication auth) { Assert.notNull(auth, "Authentication required"); - Assert.notNull(auth.getPrincipal(), - "Authentication.getPrincipal() required"); + Assert.notNull(auth.getPrincipal(), "Authentication.getPrincipal() required"); if (auth.getPrincipal() instanceof UserDetails) { return ((UserDetails) auth.getPrincipal()).getUsername(); @@ -48,11 +47,8 @@ public class SessionRegistryUtils { Assert.notNull(auth.getDetails(), "Authentication.getDetails() required"); Assert.isInstanceOf(SessionIdentifierAware.class, auth.getDetails()); - String sessionId = ((SessionIdentifierAware) auth.getDetails()) - .getSessionId(); - Assert.hasText(sessionId, - "SessionIdentifierAware did not return a Session ID (" - + auth.getDetails() + ")"); + String sessionId = ((SessionIdentifierAware) auth.getDetails()).getSessionId(); + Assert.hasText(sessionId, "SessionIdentifierAware did not return a Session ID (" + auth.getDetails() + ")"); return sessionId; } diff --git a/core/src/main/java/org/acegisecurity/context/GlobalSecurityContextHolderStrategy.java b/core/src/main/java/org/acegisecurity/context/GlobalSecurityContextHolderStrategy.java index 11f7f79b00..788867a8fb 100644 --- a/core/src/main/java/org/acegisecurity/context/GlobalSecurityContextHolderStrategy.java +++ b/core/src/main/java/org/acegisecurity/context/GlobalSecurityContextHolderStrategy.java @@ -20,24 +20,18 @@ import org.springframework.util.Assert; /** * A static field-based implementation of {@link - * org.acegisecurity.context.SecurityContextHolderStrategy}. - * - *

- * This means that all instances in the JVM share the same - * SecurityContext. This is generally useful with rich clients, - * such as Swing. - *

+ * org.acegisecurity.context.SecurityContextHolderStrategy}.

This means that all instances in the JVM share the + * same SecurityContext. This is generally useful with rich clients, such as Swing.

* * @author Ben Alex * @version $Id: SecurityContextHolder.java 1324 2006-02-12 06:29:53Z benalex $ */ -public class GlobalSecurityContextHolderStrategy - implements SecurityContextHolderStrategy { - //~ Static fields/initializers ============================================= +public class GlobalSecurityContextHolderStrategy implements SecurityContextHolderStrategy { + //~ Static fields/initializers ===================================================================================== private static SecurityContext contextHolder; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void clearContext() { contextHolder = null; @@ -52,8 +46,7 @@ public class GlobalSecurityContextHolderStrategy } public void setContext(SecurityContext context) { - Assert.notNull(context, - "Only non-null SecurityContext instances are permitted"); + Assert.notNull(context, "Only non-null SecurityContext instances are permitted"); contextHolder = context; } } diff --git a/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java b/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java index c7e1ea2fb4..a2d470e784 100644 --- a/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java @@ -33,78 +33,43 @@ import javax.servlet.http.HttpSession; /** - *

- * Populates the {@link SecurityContextHolder} with information obtained from - * the HttpSession. - *

- * - *

- * The HttpSession will be queried to retrieve the - * SecurityContext that should be stored against the - * SecurityContextHolder for the duration of the web request. At - * the end of the web request, any updates made to the - * SecurityContextHolder will be persisted back to the - * HttpSession by this filter. - *

- * - *

- * If a valid SecurityContext cannot be obtained from the - * HttpSession for whatever reason, a fresh - * SecurityContext will be created and used instead. The created - * object will be of the instance defined by the {@link #setContext(Class)} - * method (which defaults to {@link - * org.acegisecurity.context.SecurityContextImpl}. - *

- * - *

- * No HttpSession will be created by this filter if one does not - * already exist. If at the end of the web request the - * HttpSession does not exist, a HttpSession will - * only be created if the current contents of the - * SecurityContextHolder are not {@link - * java.lang.Object#equals(java.lang.Object)} to a new instance - * of {@link #setContext(Class)}. This avoids needless - * HttpSession creation, but automates the storage of changes - * made to the SecurityContextHolder. There is one exception to - * this rule, that is if the {@link #forceEagerSessionCreation} property is - * true, in which case sessions will always be created - * irrespective of normal session-minimisation logic (the default is - * false, as this is resource intensive and not recommended). - *

- * - *

- * This filter will only execute once per request, to resolve servlet container - * (specifically Weblogic) incompatibilities. - *

- * - *

- * If for whatever reason no HttpSession should ever be - * created (eg this filter is only being used with Basic authentication or - * similar clients that will never present the same jsessionid - * etc), the {@link #setAllowSessionCreation(boolean)} should be set to - * false. Only do this if you really need to conserve server - * memory and ensure all classes using the SecurityContextHolder - * are designed to have no persistence of the SecurityContext - * between web requests. Please note that if {@link - * #forceEagerSessionCreation} is true, the - * allowSessionCreation must also be true (setting - * it to false will cause a startup time error). - *

- * - *

- * This filter MUST be executed BEFORE any authentication processing - * mechanisms. Authentication processing mechanisms (eg BASIC, CAS processing - * filters etc) expect the SecurityContextHolder to contain a - * valid SecurityContext by the time they execute. - *

+ *

Populates the {@link SecurityContextHolder} with information obtained from the HttpSession.

+ *

The HttpSession will be queried to retrieve the SecurityContext that should be + * stored against the SecurityContextHolder for the duration of the web request. At the end of the web + * request, any updates made to the SecurityContextHolder will be persisted back to the + * HttpSession by this filter.

+ *

If a valid SecurityContext cannot be obtained from the HttpSession for whatever + * reason, a fresh SecurityContext will be created and used instead. The created object will be of the + * instance defined by the {@link #setContext(Class)} method (which defaults to {@link + * org.acegisecurity.context.SecurityContextImpl}.

+ *

No HttpSession will be created by this filter if one does not already exist. If at the end of + * the web request the HttpSession does not exist, a HttpSession will only be created + * if the current contents of the SecurityContextHolder are not {@link + * java.lang.Object#equals(java.lang.Object)} to a new instance of {@link #setContext(Class)}. This + * avoids needless HttpSession creation, but automates the storage of changes made to the + * SecurityContextHolder. There is one exception to this rule, that is if the {@link + * #forceEagerSessionCreation} property is true, in which case sessions will always be created + * irrespective of normal session-minimisation logic (the default is false, as this is resource intensive + * and not recommended).

+ *

This filter will only execute once per request, to resolve servlet container (specifically Weblogic) + * incompatibilities.

+ *

If for whatever reason no HttpSession should ever be created (eg this filter is only + * being used with Basic authentication or similar clients that will never present the same jsessionid + * etc), the {@link #setAllowSessionCreation(boolean)} should be set to false. Only do this if you really + * need to conserve server memory and ensure all classes using the SecurityContextHolder are designed to + * have no persistence of the SecurityContext between web requests. Please note that if {@link + * #forceEagerSessionCreation} is true, the allowSessionCreation must also be + * true (setting it to false will cause a startup time error).

+ *

This filter MUST be executed BEFORE any authentication processing mechanisms. Authentication processing + * mechanisms (eg BASIC, CAS processing filters etc) expect the SecurityContextHolder to contain a valid + * SecurityContext by the time they execute.

* * @author Ben Alex * @author Patrick Burleson * @version $Id$ */ -public class HttpSessionContextIntegrationFilter implements InitializingBean, - Filter { - //~ Static fields/initializers ============================================= +public class HttpSessionContextIntegrationFilter implements InitializingBean, Filter { + //~ Static fields/initializers ===================================================================================== // ~ Static fields/initializers // ============================================= @@ -112,7 +77,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, private static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied"; public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ // ~ Instance fields // ======================================================== @@ -120,43 +85,35 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, private Object contextObject; /** - * Indicates if this filter can create a HttpSession if needed - * (sessions are always created sparingly, but setting this value to - * false will prohibit sessions from ever being created). - * Defaults to true. Do not set to false if you - * are have set {@link #forceEagerSessionCreation} to true, - * as the properties would be in conflict. + * Indicates if this filter can create a HttpSession if needed (sessions are always created + * sparingly, but setting this value to false will prohibit sessions from ever being created). + * Defaults to true. Do not set to false if you are have set {@link + * #forceEagerSessionCreation} to true, as the properties would be in conflict. */ private boolean allowSessionCreation = true; /** - * Indicates if this filter is required to create a - * HttpSession for every request before proceeding through - * the filter chain, even if the HttpSession would not - * ordinarily have been created. By default this is false, - * which is entirely appropriate for most circumstances as you do not want - * a HttpSession created unless the filter actually needs - * one. It is envisaged the main situation in which this property would be - * set to true is if using other filters that depend on a - * HttpSession already existing, such as those which need to - * obtain a session ID. This is only required in specialised cases, so - * leave it set to false unless you have an actual - * requirement and are conscious of the session creation overhead. + * Indicates if this filter is required to create a HttpSession for every request before + * proceeding through the filter chain, even if the HttpSession would not ordinarily have been + * created. By default this is false, which is entirely appropriate for most circumstances as you do + * not want a HttpSession created unless the filter actually needs one. It is envisaged the main + * situation in which this property would be set to true is if using other filters that depend on a + * HttpSession already existing, such as those which need to obtain a session ID. This is only + * required in specialised cases, so leave it set to false unless you have an actual requirement and + * are conscious of the session creation overhead. */ private boolean forceEagerSessionCreation = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - if ((this.context == null) - || (!SecurityContext.class.isAssignableFrom(this.context))) { + if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) { throw new IllegalArgumentException( "context must be defined and implement SecurityContext (typically use org.acegisecurity.context.SecurityContextImpl; existing class is " + this.context + ")"); } - if ((forceEagerSessionCreation == true) - && (allowSessionCreation == false)) { + if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) { throw new IllegalArgumentException( "If using forceEagerSessionCreation, you must set allowSessionCreation to also be true"); } @@ -169,8 +126,8 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) { // ensure that filter is only applied once per request chain.doFilter(request, response); @@ -202,8 +159,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject); } else { if (logger.isWarnEnabled()) { - logger.warn( - "ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '" + logger.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '" + contextFromSessionObject + "'; are you improperly modifying the HttpSession directly (you should always use SecurityContextHolder) or using the HttpSession attribute reserved for this class? - new SecurityContext instance associated with SecurityContextHolder"); } @@ -233,8 +189,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, httpSession = null; // Proceed with chain - int contextWhenChainProceeded = SecurityContextHolder.getContext() - .hashCode(); + int contextWhenChainProceeded = SecurityContextHolder.getContext().hashCode(); try { chain.doFilter(request, response); @@ -257,23 +212,19 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, } // Generate a HttpSession only if we need to - if ((httpSession == null) - && !httpSessionExistedAtStartOfRequest) { + if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) { if (!allowSessionCreation) { if (logger.isDebugEnabled()) { logger.debug( "The HttpSession is currently null, and the HttpSessionContextIntegrationFilter is prohibited from creating a HttpSession (because the allowSessionCreation property is false) - SecurityContext thus not stored for next request"); } - } else if (!contextObject.equals( - SecurityContextHolder.getContext())) { + } else if (!contextObject.equals(SecurityContextHolder.getContext())) { if (logger.isDebugEnabled()) { - logger.debug( - "HttpSession being created as SecurityContextHolder contents are non-default"); + logger.debug("HttpSession being created as SecurityContextHolder contents are non-default"); } try { - httpSession = ((HttpServletRequest) request) - .getSession(true); + httpSession = ((HttpServletRequest) request).getSession(true); } catch (IllegalStateException ignored) {} } else { if (logger.isDebugEnabled()) { @@ -291,12 +242,11 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, // SEC-37) if ((httpSession != null) && (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) { - httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, - SecurityContextHolder.getContext()); + httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); if (logger.isDebugEnabled()) { - logger.debug("SecurityContext stored to HttpSession: '" - + SecurityContextHolder.getContext() + "'"); + logger.debug("SecurityContext stored to HttpSession: '" + SecurityContextHolder.getContext() + + "'"); } } @@ -304,8 +254,7 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, SecurityContextHolder.clearContext(); if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder set to new context, as request processing completed"); + logger.debug("SecurityContextHolder set to new context, as request processing completed"); } } } diff --git a/core/src/main/java/org/acegisecurity/context/InheritableThreadLocalSecurityContextHolderStrategy.java b/core/src/main/java/org/acegisecurity/context/InheritableThreadLocalSecurityContextHolderStrategy.java index 138fdd029b..e8fc352786 100644 --- a/core/src/main/java/org/acegisecurity/context/InheritableThreadLocalSecurityContextHolderStrategy.java +++ b/core/src/main/java/org/acegisecurity/context/InheritableThreadLocalSecurityContextHolderStrategy.java @@ -29,11 +29,11 @@ import org.springframework.util.Assert; * @see org.acegisecurity.context.HttpSessionContextIntegrationFilter */ public class InheritableThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static ThreadLocal contextHolder = new InheritableThreadLocal(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void clearContext() { contextHolder.set(null); @@ -48,8 +48,7 @@ public class InheritableThreadLocalSecurityContextHolderStrategy implements Secu } public void setContext(SecurityContext context) { - Assert.notNull(context, - "Only non-null SecurityContext instances are permitted"); + Assert.notNull(context, "Only non-null SecurityContext instances are permitted"); contextHolder.set(context); } } diff --git a/core/src/main/java/org/acegisecurity/context/SecurityContext.java b/core/src/main/java/org/acegisecurity/context/SecurityContext.java index 8fa0b8b5a9..1c7a114dd4 100644 --- a/core/src/main/java/org/acegisecurity/context/SecurityContext.java +++ b/core/src/main/java/org/acegisecurity/context/SecurityContext.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,24 +32,20 @@ import java.io.Serializable; * @version $Id$ */ public interface SecurityContext extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Changes the currently authenticated principal, or removes the - * authentication information. + * Obtains the currently authenticated principal, or an authentication request token. * - * @param authentication the new Authentication token, or - * null if no further authentication information - * should be stored - */ - public void setAuthentication(Authentication authentication); - - /** - * Obtains the currently authenticated principal, or an authentication - * request token. - * - * @return the Authentication or null if no - * authentication information is available + * @return the Authentication or null if no authentication information is available */ public Authentication getAuthentication(); + + /** + * Changes the currently authenticated principal, or removes the authentication information. + * + * @param authentication the new Authentication token, or null if no further + * authentication information should be stored + */ + public void setAuthentication(Authentication authentication); } diff --git a/core/src/main/java/org/acegisecurity/context/SecurityContextHolder.java b/core/src/main/java/org/acegisecurity/context/SecurityContextHolder.java index 5042f57a00..599e898bf7 100644 --- a/core/src/main/java/org/acegisecurity/context/SecurityContextHolder.java +++ b/core/src/main/java/org/acegisecurity/context/SecurityContextHolder.java @@ -21,36 +21,20 @@ import java.lang.reflect.Constructor; /** - * Associates a given {@link SecurityContext} with the current execution - * thread. - * - *

- * This class provides a series of static methods that delegate to an instance - * of {@link org.acegisecurity.context.SecurityContextHolderStrategy}. The - * purpose of the class is to provide a convenient way to specify the strategy - * that should be used for a given JVM. This is a JVM-wide setting, since - * everything in this class is static to facilitate ease of use - * in calling code. - *

- * - *

- * To specify which strategy should be used, you must provide a mode setting. A - * mode setting is one of the three valid MODE_ settings defined - * as static final fields, or a fully qualified classname to a - * concrete implementation of {@link - * org.acegisecurity.context.SecurityContextHolderStrategy} that provides a - * public no-argument constructor. - *

- * - *

- * There are two ways to specify the desired mode String. The - * first is to specify it via the system property keyed on {@link - * #SYSTEM_PROPERTY}. The second is to call {@link #setStrategyName(String)} - * before using the class. If neither approach is used, the class will default - * to using {@link #MODE_THREADLOCAL}, which is backwards compatible, has - * fewer JVM incompatibilities and is appropriate on servers (whereas {@link - * #MODE_GLOBAL} is not). - *

+ * Associates a given {@link SecurityContext} with the current execution thread.

This class provides a series of + * static methods that delegate to an instance of {@link org.acegisecurity.context.SecurityContextHolderStrategy}. The + * purpose of the class is to provide a convenient way to specify the strategy that should be used for a given JVM. + * This is a JVM-wide setting, since everything in this class is static to facilitate ease of use in + * calling code.

+ *

To specify which strategy should be used, you must provide a mode setting. A mode setting is one of the + * three valid MODE_ settings defined as static final fields, or a fully qualified classname + * to a concrete implementation of {@link org.acegisecurity.context.SecurityContextHolderStrategy} that provides a + * public no-argument constructor.

+ *

There are two ways to specify the desired mode String. The first is to specify it via the + * system property keyed on {@link #SYSTEM_PROPERTY}. The second is to call {@link #setStrategyName(String)} before + * using the class. If neither approach is used, the class will default to using {@link #MODE_THREADLOCAL}, which is + * backwards compatible, has fewer JVM incompatibilities and is appropriate on servers (whereas {@link #MODE_GLOBAL} + * is not).

* * @author Ben Alex * @version $Id$ @@ -58,7 +42,7 @@ import java.lang.reflect.Constructor; * @see org.acegisecurity.context.HttpSessionContextIntegrationFilter */ public class SecurityContextHolder { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL"; public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL"; @@ -68,7 +52,7 @@ public class SecurityContextHolder { private static Constructor customStrategy; private static SecurityContextHolderStrategy strategy; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Explicitly clears the context value from the current thread. @@ -109,8 +93,7 @@ public class SecurityContextHolder { customStrategy = clazz.getConstructor(new Class[] {}); } - strategy = (SecurityContextHolderStrategy) customStrategy - .newInstance(new Object[] {}); + strategy = (SecurityContextHolderStrategy) customStrategy.newInstance(new Object[] {}); } catch (Exception ex) { ReflectionUtils.handleReflectionException(ex); } @@ -118,11 +101,9 @@ public class SecurityContextHolder { } /** - * Associates a new SecurityContext with the current thread of - * execution. + * Associates a new SecurityContext with the current thread of execution. * - * @param context the new SecurityContext (may not be - * null) + * @param context the new SecurityContext (may not be null) */ public static void setContext(SecurityContext context) { initialize(); @@ -130,12 +111,10 @@ public class SecurityContextHolder { } /** - * Changes the preferred strategy. Do NOT call this method more - * than once for a given JVM, as it will reinitialize the strategy and - * adversely affect any existing threads using the old strategy. + * Changes the preferred strategy. Do NOT call this method more than once for a given JVM, as it + * will reinitialize the strategy and adversely affect any existing threads using the old strategy. * - * @param strategyName the fully qualified classname of the strategy that - * should be used. + * @param strategyName the fully qualified classname of the strategy that should be used. */ public static void setStrategyName(String strategyName) { SecurityContextHolder.strategyName = strategyName; diff --git a/core/src/main/java/org/acegisecurity/context/SecurityContextHolderStrategy.java b/core/src/main/java/org/acegisecurity/context/SecurityContextHolderStrategy.java index 319ad94633..14d70e9ba7 100644 --- a/core/src/main/java/org/acegisecurity/context/SecurityContextHolderStrategy.java +++ b/core/src/main/java/org/acegisecurity/context/SecurityContextHolderStrategy.java @@ -27,7 +27,7 @@ package org.acegisecurity.context; * @version $Id$ */ public interface SecurityContextHolderStrategy { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Clears the current context. @@ -37,18 +37,15 @@ public interface SecurityContextHolderStrategy { /** * Obtains the current context. * - * @return a context (never null - create a default - * implementation if necessary) + * @return a context (never null - create a default implementation if necessary) */ public SecurityContext getContext(); /** * Sets the current context. * - * @param context to the new argument (should never be null, - * although implementations must check if null has - * been passed and throw an IllegalArgumentException - * in such cases) + * @param context to the new argument (should never be null, although implementations must check if + * null has been passed and throw an IllegalArgumentException in such cases) */ public void setContext(SecurityContext context); } diff --git a/core/src/main/java/org/acegisecurity/context/SecurityContextImpl.java b/core/src/main/java/org/acegisecurity/context/SecurityContextImpl.java index 85fb55744a..0d034cda5d 100644 --- a/core/src/main/java/org/acegisecurity/context/SecurityContextImpl.java +++ b/core/src/main/java/org/acegisecurity/context/SecurityContextImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,49 +12,57 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.context; import org.acegisecurity.Authentication; /** - * Base implementation of {@link SecurityContext}. - * - *

- * Used by default by {@link SecurityContextHolder} and {@link HttpSessionContextIntegrationFilter}. - *

+ * Base implementation of {@link SecurityContext}.

Used by default by {@link SecurityContextHolder} and {@link + * HttpSessionContextIntegrationFilter}.

* * @author Ben Alex * @version $Id$ */ public class SecurityContextImpl implements SecurityContext { + //~ Instance fields ================================================================================================ + private Authentication authentication; - public void setAuthentication(Authentication authentication) { - this.authentication = authentication; + //~ Methods ======================================================================================================== + + public boolean equals(Object obj) { + if (obj instanceof SecurityContextImpl) { + SecurityContextImpl test = (SecurityContextImpl) obj; + + if ((this.getAuthentication() == null) && (test.getAuthentication() == null)) { + return true; + } + + if ((this.getAuthentication() != null) && (test.getAuthentication() != null) + && this.getAuthentication().equals(test.getAuthentication())) { + return true; + } + } + + return false; } public Authentication getAuthentication() { return authentication; } - public boolean equals(Object obj) { - if (obj instanceof SecurityContextImpl) { - SecurityContextImpl test = (SecurityContextImpl) obj; - - if ((this.getAuthentication() == null) && - (test.getAuthentication() == null)) { - return true; - } - - if ((this.getAuthentication() != null) && - (test.getAuthentication() != null) && - this.getAuthentication().equals(test.getAuthentication())) { - return true; - } + public int hashCode() { + if (this.authentication == null) { + return -1; + } else { + return this.authentication.hashCode(); } + } - return false; + public void setAuthentication(Authentication authentication) { + this.authentication = authentication; } public String toString() { @@ -69,12 +77,4 @@ public class SecurityContextImpl implements SecurityContext { return sb.toString(); } - - public int hashCode() { - if (this.authentication == null) { - return -1; - } else { - return this.authentication.hashCode(); - } - } } diff --git a/core/src/main/java/org/acegisecurity/context/ThreadLocalSecurityContextHolderStrategy.java b/core/src/main/java/org/acegisecurity/context/ThreadLocalSecurityContextHolderStrategy.java index bb0cdc38e8..9793b9dc0e 100644 --- a/core/src/main/java/org/acegisecurity/context/ThreadLocalSecurityContextHolderStrategy.java +++ b/core/src/main/java/org/acegisecurity/context/ThreadLocalSecurityContextHolderStrategy.java @@ -29,11 +29,11 @@ import org.springframework.util.Assert; * @see org.acegisecurity.context.HttpSessionContextIntegrationFilter */ public class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static ThreadLocal contextHolder = new ThreadLocal(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void clearContext() { contextHolder.set(null); @@ -48,8 +48,7 @@ public class ThreadLocalSecurityContextHolderStrategy implements SecurityContext } public void setContext(SecurityContext context) { - Assert.notNull(context, - "Only non-null SecurityContext instances are permitted"); + Assert.notNull(context, "Only non-null SecurityContext instances are permitted"); contextHolder.set(context); } } diff --git a/core/src/main/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutor.java b/core/src/main/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutor.java index 06b982f541..a2899c1003 100644 --- a/core/src/main/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutor.java +++ b/core/src/main/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutor.java @@ -32,24 +32,21 @@ import java.net.HttpURLConnection; /** - * Adds BASIC authentication support to - * SimpleHttpInvokerRequestExecutor. + * Adds BASIC authentication support to SimpleHttpInvokerRequestExecutor. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationSimpleHttpInvokerRequestExecutor - extends SimpleHttpInvokerRequestExecutor { - //~ Static fields/initializers ============================================= +public class AuthenticationSimpleHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AuthenticationSimpleHttpInvokerRequestExecutor.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Provided so subclasses can perform additional configuration if required - * (eg set additional request headers for non-security related information - * etc). + * Provided so subclasses can perform additional configuration if required (eg set additional request + * headers for non-security related information etc). * * @param con the HTTP connection to prepare * @param contentLength the length of the content to send @@ -60,46 +57,30 @@ public class AuthenticationSimpleHttpInvokerRequestExecutor throws IOException {} /** - * Called every time a HTTP invocation is made. - * - *

- * Simply allows the parent to setup the connection, and then adds an - * Authorization HTTP header property that will be used for - * BASIC authentication. - *

- * - *

- * The SecurityContextHolder is used to obtain the relevant - * principal and credentials. - *

+ * Called every time a HTTP invocation is made.

Simply allows the parent to setup the connection, and + * then adds an Authorization HTTP header property that will be used for BASIC authentication.

+ *

The SecurityContextHolder is used to obtain the relevant principal and credentials.

* * @param con the HTTP connection to prepare * @param contentLength the length of the content to send * * @throws IOException if thrown by HttpURLConnection methods - * @throws AuthenticationCredentialsNotFoundException if the - * SecurityContextHolder does not contain a valid - * Authentication with both its - * principal and credentials not + * @throws AuthenticationCredentialsNotFoundException if the SecurityContextHolder does not contain a + * valid Authentication with both its principal and credentials not * null */ protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException, AuthenticationCredentialsNotFoundException { super.prepareConnection(con, contentLength); - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if ((auth != null) && (auth.getName() != null) - && (auth.getCredentials() != null)) { - String base64 = auth.getName() + ":" - + auth.getCredentials().toString(); - con.setRequestProperty("Authorization", - "Basic " + new String(Base64.encodeBase64(base64.getBytes()))); + if ((auth != null) && (auth.getName() != null) && (auth.getCredentials() != null)) { + String base64 = auth.getName() + ":" + auth.getCredentials().toString(); + con.setRequestProperty("Authorization", "Basic " + new String(Base64.encodeBase64(base64.getBytes()))); if (logger.isDebugEnabled()) { - logger.debug( - "HttpInvocation now presenting via BASIC authentication SecurityContextHolder-derived: " + logger.debug("HttpInvocation now presenting via BASIC authentication SecurityContextHolder-derived: " + auth.toString()); } } else { diff --git a/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocation.java b/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocation.java index 978e239368..2371428976 100644 --- a/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocation.java +++ b/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocation.java @@ -29,39 +29,32 @@ import java.lang.reflect.InvocationTargetException; /** - * The actual RemoteInvocation that is passed from the client to - * the server, which contains the contents of {@link SecurityContextHolder}, - * being a {@link SecurityContext} object. - * - *

- * When constructed on the client via {@link - * org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory}, - * the contents of the SecurityContext are stored inside the - * object. The object is then passed to the server that is processing the - * remote invocation. Upon the server invoking the remote invocation, it will - * retrieve the passed contents of the SecurityContextHolder and - * set them to the server-side SecurityContextHolder whilst the - * target object is invoked. When the target invocation has been completed, - * the server-side SecurityContextHolder will be reset to a new - * instance of SecurityContextImpl. - *

+ * The actual RemoteInvocation that is passed from the client to the server, which contains the + * contents of {@link SecurityContextHolder}, being a {@link SecurityContext} object.

When constructed on the + * client via {@link org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory}, the contents of the + * SecurityContext are stored inside the object. The object is then passed to the server that is + * processing the remote invocation. Upon the server invoking the remote invocation, it will retrieve the passed + * contents of the SecurityContextHolder and set them to the server-side + * SecurityContextHolder whilst the target object is invoked. When the target invocation has been + * completed, the server-side SecurityContextHolder will be reset to a new instance of + * SecurityContextImpl.

* * @author James Monaghan * @author Ben Alex * @version $Id$ */ public class ContextPropagatingRemoteInvocation extends RemoteInvocation { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(ContextPropagatingRemoteInvocation.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private SecurityContext securityContext; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs the object, storing the value of the client-side * SecurityContextHolder inside the object. * @@ -72,24 +65,18 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation { securityContext = SecurityContextHolder.getContext(); if (logger.isDebugEnabled()) { - logger.debug("RemoteInvocation now has SecurityContext: " - + securityContext); + logger.debug("RemoteInvocation now has SecurityContext: " + securityContext); } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Invoked on the server-side as described in the class JavaDocs. - * - *

- * Invocations will always have their {@link - * org.acegisecurity.Authentication#setAuthenticated(boolean)} set to - * false, which is guaranteed to always be accepted by - * Authentication implementations. This ensures that even - * remotely authenticated Authentications will be untrusted - * by the server-side, which is an appropriate security measure. - *

+ * Invoked on the server-side as described in the class JavaDocs.

Invocations will always have their + * {@link org.acegisecurity.Authentication#setAuthenticated(boolean)} set to false, which is + * guaranteed to always be accepted by Authentication implementations. This ensures that even + * remotely authenticated Authentications will be untrusted by the server-side, which is an + * appropriate security measure.

* * @param targetObject the target object to apply the invocation to * @@ -97,23 +84,19 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation { * * @throws NoSuchMethodException if the method name could not be resolved * @throws IllegalAccessException if the method could not be accessed - * @throws InvocationTargetException if the method invocation resulted in - * an exception + * @throws InvocationTargetException if the method invocation resulted in an exception */ public Object invoke(Object targetObject) - throws NoSuchMethodException, IllegalAccessException, - InvocationTargetException { + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { SecurityContextHolder.setContext(securityContext); if ((SecurityContextHolder.getContext() != null) && (SecurityContextHolder.getContext().getAuthentication() != null)) { - SecurityContextHolder.getContext().getAuthentication() - .setAuthenticated(false); + SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); } if (logger.isDebugEnabled()) { - logger.debug("Set SecurityContextHolder to contain: " - + securityContext); + logger.debug("Set SecurityContextHolder to contain: " + securityContext); } try { @@ -122,8 +105,7 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation { SecurityContextHolder.clearContext(); if (logger.isDebugEnabled()) { - logger.debug( - "Set SecurityContext to new instance of SecurityContextImpl"); + logger.debug("Set SecurityContext to new instance of SecurityContextImpl"); } } } diff --git a/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationFactory.java b/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationFactory.java index ec1b92c65c..fafad056ec 100644 --- a/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationFactory.java +++ b/core/src/main/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationFactory.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,25 +22,18 @@ import org.springframework.remoting.support.RemoteInvocationFactory; /** - * Called by a client-side instance of - * org.springframework.remoting.rmi.RmiProxyFactoryBean when it - * wishes to create a remote invocation. - * - *

- * Set an instance of this bean against the above class' - * remoteInvocationFactory property. - *

+ * Called by a client-side instance of org.springframework.remoting.rmi.RmiProxyFactoryBean when it + * wishes to create a remote invocation.

Set an instance of this bean against the above class' + * remoteInvocationFactory property.

* * @author James Monaghan * @author Ben Alex * @version $Id$ */ -public class ContextPropagatingRemoteInvocationFactory - implements RemoteInvocationFactory { - //~ Methods ================================================================ +public class ContextPropagatingRemoteInvocationFactory implements RemoteInvocationFactory { + //~ Methods ======================================================================================================== - public RemoteInvocation createRemoteInvocation( - MethodInvocation methodInvocation) { + public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { return new ContextPropagatingRemoteInvocation(methodInvocation); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java index 775dfaf9eb..1c4f67aec4 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,28 +21,24 @@ import org.springframework.context.ApplicationEvent; /** - * Represents an application authentication event. - * - *

- * The ApplicationEvent's source will be the - * Authentication object. - *

+ * Represents an application authentication event.

The ApplicationEvent's source will + * be the Authentication object.

* * @author Ben Alex * @version $Id$ */ public abstract class AbstractAuthenticationEvent extends ApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractAuthenticationEvent(Authentication authentication) { super(authentication); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Getters for the Authentication request that caused the - * event. Also available from super.getSource(). + * Getters for the Authentication request that caused the event. Also available from + * super.getSource(). * * @return the authentication request */ diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java index 173ede5d0d..951599be1d 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,28 +22,25 @@ import org.springframework.util.Assert; /** - * Abstract application event which indicates authentication failure for some - * reason. + * Abstract application event which indicates authentication failure for some reason. * * @author Ben Alex * @version $Id$ */ -public abstract class AbstractAuthenticationFailureEvent - extends AbstractAuthenticationEvent { - //~ Instance fields ======================================================== +public abstract class AbstractAuthenticationFailureEvent extends AbstractAuthenticationEvent { + //~ Instance fields ================================================================================================ private AuthenticationException exception; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public AbstractAuthenticationFailureEvent(Authentication authentication, - AuthenticationException exception) { + public AbstractAuthenticationFailureEvent(Authentication authentication, AuthenticationException exception) { super(authentication); Assert.notNull(exception, "AuthenticationException is required"); this.exception = exception; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public AuthenticationException getException() { return exception; diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java index a03f8a9b0f..2bc873bf4a 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to invalid - * credentials being presented. + * Application event which indicates authentication failure due to invalid credentials being presented. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureBadCredentialsEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureBadCredentialsEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureBadCredentialsEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureBadCredentialsEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java index a130b00151..1de06361e3 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the user - * attempting to login to too many concurrent sessions. + * Application event which indicates authentication failure due to the user attempting to login to too many + * concurrent sessions. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureConcurrentLoginEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureConcurrentLoginEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureConcurrentLoginEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureConcurrentLoginEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java index b889fd239f..0a4e86ee32 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the user's - * credentials having expired. + * Application event which indicates authentication failure due to the user's credentials having expired. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureCredentialsExpiredEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureCredentialsExpiredEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureCredentialsExpiredEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureCredentialsExpiredEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java index 793d9593e6..c98cbc7865 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the user's - * account being disabled. + * Application event which indicates authentication failure due to the user's account being disabled. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureDisabledEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureDisabledEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureDisabledEvent(Authentication authentication, - AuthenticationException exception) { + public AuthenticationFailureDisabledEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java index d467ee3afc..5313d82a6a 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the user's - * account having expired. + * Application event which indicates authentication failure due to the user's account having expired. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureExpiredEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureExpiredEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureExpiredEvent(Authentication authentication, - AuthenticationException exception) { + public AuthenticationFailureExpiredEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java index 6e5486fedb..5cf9b46460 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,15 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the user's - * account having been locked. + * Application event which indicates authentication failure due to the user's account having been locked. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureLockedEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureLockedEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureLockedEvent(Authentication authentication, - AuthenticationException exception) { + public AuthenticationFailureLockedEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java index 18bba14526..87525fbe75 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,19 +20,16 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to there being - * no registered AuthenticationProvider that can process the - * request. + * Application event which indicates authentication failure due to there being no registered + * AuthenticationProvider that can process the request. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureProviderNotFoundEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureProviderNotFoundEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureProviderNotFoundEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureProviderNotFoundEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java index e2f174a3b7..ec058e242c 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to the CAS - * user's ticket being generated by an untrusted proxy. + * Application event which indicates authentication failure due to the CAS user's ticket being generated by an + * untrusted proxy. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureProxyUntrustedEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureProxyUntrustedEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureProxyUntrustedEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureProxyUntrustedEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java index 3538860603..2e00db3608 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,16 @@ import org.acegisecurity.AuthenticationException; /** - * Application event which indicates authentication failure due to there being - * a problem internal to the AuthenticationManager. + * Application event which indicates authentication failure due to there being a problem internal to the + * AuthenticationManager. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationFailureServiceExceptionEvent - extends AbstractAuthenticationFailureEvent { - //~ Constructors =========================================================== +public class AuthenticationFailureServiceExceptionEvent extends AbstractAuthenticationFailureEvent { + //~ Constructors =================================================================================================== - public AuthenticationFailureServiceExceptionEvent( - Authentication authentication, AuthenticationException exception) { + public AuthenticationFailureServiceExceptionEvent(Authentication authentication, AuthenticationException exception) { super(authentication, exception); } } diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java index 93b6e00095..ee44c8eca6 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import org.acegisecurity.Authentication; * @version $Id$ */ public class AuthenticationSuccessEvent extends AbstractAuthenticationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthenticationSuccessEvent(Authentication authentication) { super(authentication); diff --git a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java index 444294f319..5f004cf34e 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.event.authentication; import org.acegisecurity.Authentication; + import org.acegisecurity.userdetails.UserDetails; @@ -26,25 +27,24 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class AuthenticationSwitchUserEvent extends AbstractAuthenticationEvent { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private UserDetails targetUser; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Switch user context event constructor * * @param authentication The current Authentication object * @param targetUser The target user */ - public AuthenticationSwitchUserEvent(Authentication authentication, - UserDetails targetUser) { + public AuthenticationSwitchUserEvent(Authentication authentication, UserDetails targetUser) { super(authentication); this.targetUser = targetUser; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public UserDetails getTargetUser() { return targetUser; diff --git a/core/src/main/java/org/acegisecurity/event/authentication/InteractiveAuthenticationSuccessEvent.java b/core/src/main/java/org/acegisecurity/event/authentication/InteractiveAuthenticationSuccessEvent.java index fa5780f909..340ca82f9a 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/InteractiveAuthenticationSuccessEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/InteractiveAuthenticationSuccessEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,36 +21,30 @@ import org.springframework.util.Assert; /** - * Indicates an interactive authentication was successful. - * - *

- * The ApplicationEvent's source will be the - * Authentication object. - *

+ * Indicates an interactive authentication was successful.

The ApplicationEvent's + * source will be the Authentication object.

* * @author Ben Alex * @version $Id$ */ -public class InteractiveAuthenticationSuccessEvent - extends AbstractAuthenticationEvent { - //~ Instance fields ======================================================== +public class InteractiveAuthenticationSuccessEvent extends AbstractAuthenticationEvent { + //~ Instance fields ================================================================================================ private Class generatedBy; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public InteractiveAuthenticationSuccessEvent( - Authentication authentication, Class generatedBy) { + public InteractiveAuthenticationSuccessEvent(Authentication authentication, Class generatedBy) { super(authentication); Assert.notNull(generatedBy); this.generatedBy = generatedBy; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Getter for the Class that generated this event. This can be - * useful for generating additional logging information. + * Getter for the Class that generated this event. This can be useful for generating + * additional logging information. * * @return */ diff --git a/core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java b/core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java index e73da3290f..8d14b9491e 100644 --- a/core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java +++ b/core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,36 +25,31 @@ import org.springframework.util.ClassUtils; /** - * Outputs authentication-related application events to Commons Logging. - * - *

- * All authentication events are logged at the warning level. - *

+ * Outputs authentication-related application events to Commons Logging.

All authentication events are logged at + * the warning level.

* * @author Ben Alex * @version $Id$ */ public class LoggerListener implements ApplicationListener { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(LoggerListener.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void onApplicationEvent(ApplicationEvent event) { if (event instanceof AbstractAuthenticationEvent) { AbstractAuthenticationEvent authEvent = (AbstractAuthenticationEvent) event; if (logger.isWarnEnabled()) { - String message = "Authentication event " - + ClassUtils.getShortName(authEvent.getClass()) + ": " + String message = "Authentication event " + ClassUtils.getShortName(authEvent.getClass()) + ": " + authEvent.getAuthentication().getName() + "; details: " + authEvent.getAuthentication().getDetails(); if (event instanceof AbstractAuthenticationFailureEvent) { message = message + "; exception: " - + ((AbstractAuthenticationFailureEvent) event).getException() - .getMessage(); + + ((AbstractAuthenticationFailureEvent) event).getException().getMessage(); } logger.warn(message); diff --git a/core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java b/core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java index 70ea9f90e3..94564cf8a5 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,9 @@ import org.springframework.context.ApplicationEvent; * @version $Id$ */ public abstract class AbstractAuthorizationEvent extends ApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the event, passing in the secure object being intercepted. * * @param secureObject the secure object diff --git a/core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java b/core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java index 83b89597f6..1bcc980fd3 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,23 +20,21 @@ import org.acegisecurity.ConfigAttributeDefinition; /** - * Indicates a secure object invocation failed because the - * Authentication could not be obtained from the - * SecurityContextHolder. + * Indicates a secure object invocation failed because the Authentication could not be obtained from + * the SecurityContextHolder. * * @author Ben Alex * @version $Id$ */ -public class AuthenticationCredentialsNotFoundEvent - extends AbstractAuthorizationEvent { - //~ Instance fields ======================================================== +public class AuthenticationCredentialsNotFoundEvent extends AbstractAuthorizationEvent { + //~ Instance fields ================================================================================================ private AuthenticationCredentialsNotFoundException credentialsNotFoundException; private ConfigAttributeDefinition configAttributeDefinition; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the event. * * @param secureObject the secure object @@ -46,21 +44,19 @@ public class AuthenticationCredentialsNotFoundEvent * * @throws IllegalArgumentException DOCUMENT ME! */ - public AuthenticationCredentialsNotFoundEvent(Object secureObject, - ConfigAttributeDefinition configAttribs, + public AuthenticationCredentialsNotFoundEvent(Object secureObject, ConfigAttributeDefinition configAttribs, AuthenticationCredentialsNotFoundException credentialsNotFoundException) { super(secureObject); if ((configAttribs == null) || (credentialsNotFoundException == null)) { - throw new IllegalArgumentException( - "All parameters are required and cannot be null"); + throw new IllegalArgumentException("All parameters are required and cannot be null"); } this.configAttributeDefinition = configAttribs; this.credentialsNotFoundException = credentialsNotFoundException; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public ConfigAttributeDefinition getConfigAttributeDefinition() { return configAttributeDefinition; diff --git a/core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java b/core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java index d296c0d144..b872e477ab 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,22 +21,21 @@ import org.acegisecurity.ConfigAttributeDefinition; /** - * Indicates a secure object invocation failed because the principal could not - * be authorized for the request. + * Indicates a secure object invocation failed because the principal could not be authorized for the request. * * @author Ben Alex * @version $Id$ */ public class AuthorizationFailureEvent extends AbstractAuthorizationEvent { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AccessDeniedException accessDeniedException; private Authentication authentication; private ConfigAttributeDefinition configAttributeDefinition; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the event. * * @param secureObject the secure object @@ -47,15 +46,12 @@ public class AuthorizationFailureEvent extends AbstractAuthorizationEvent { * * @throws IllegalArgumentException if any null arguments are presented. */ - public AuthorizationFailureEvent(Object secureObject, - ConfigAttributeDefinition configAttribs, Authentication authentication, - AccessDeniedException accessDeniedException) { + public AuthorizationFailureEvent(Object secureObject, ConfigAttributeDefinition configAttribs, + Authentication authentication, AccessDeniedException accessDeniedException) { super(secureObject); - if ((configAttribs == null) || (authentication == null) - || (accessDeniedException == null)) { - throw new IllegalArgumentException( - "All parameters are required and cannot be null"); + if ((configAttribs == null) || (authentication == null) || (accessDeniedException == null)) { + throw new IllegalArgumentException("All parameters are required and cannot be null"); } this.configAttributeDefinition = configAttribs; @@ -63,7 +59,7 @@ public class AuthorizationFailureEvent extends AbstractAuthorizationEvent { this.accessDeniedException = accessDeniedException; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public AccessDeniedException getAccessDeniedException() { return accessDeniedException; diff --git a/core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java b/core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java index ddf6e082ec..e675d5cd0a 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,24 +20,21 @@ import org.acegisecurity.ConfigAttributeDefinition; /** - * Event indicating a secure object was invoked successfully. - * - *

- * Published just before the secure object attempts to proceed. - *

+ * Event indicating a secure object was invoked successfully.

Published just before the secure object attempts to + * proceed.

* * @author Ben Alex * @version $Id$ */ public class AuthorizedEvent extends AbstractAuthorizationEvent { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authentication authentication; private ConfigAttributeDefinition configAttributeDefinition; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the event. * * @param secureObject the secure object @@ -46,20 +43,18 @@ public class AuthorizedEvent extends AbstractAuthorizationEvent { * * @throws IllegalArgumentException DOCUMENT ME! */ - public AuthorizedEvent(Object secureObject, - ConfigAttributeDefinition configAttribs, Authentication authentication) { + public AuthorizedEvent(Object secureObject, ConfigAttributeDefinition configAttribs, Authentication authentication) { super(secureObject); if ((configAttribs == null) || (authentication == null)) { - throw new IllegalArgumentException( - "All parameters are required and cannot be null"); + throw new IllegalArgumentException("All parameters are required and cannot be null"); } this.configAttributeDefinition = configAttribs; this.authentication = authentication; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Authentication getAuthentication() { return authentication; diff --git a/core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java b/core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java index 8af4b2fa59..42d7b1d668 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,33 +23,26 @@ import org.springframework.context.ApplicationListener; /** - * Outputs interceptor-related application events to Commons Logging. - * - *

- * All failures are logged at the warning level, with success events logged at - * the information level, and public invocation events logged at the debug - * level. - *

+ * Outputs interceptor-related application events to Commons Logging.

All failures are logged at the warning + * level, with success events logged at the information level, and public invocation events logged at the debug level.

* * @author Ben Alex * @version $Id$ */ public class LoggerListener implements ApplicationListener { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(LoggerListener.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void onApplicationEvent(ApplicationEvent event) { if (event instanceof AuthenticationCredentialsNotFoundEvent) { AuthenticationCredentialsNotFoundEvent authEvent = (AuthenticationCredentialsNotFoundEvent) event; if (logger.isWarnEnabled()) { - logger.warn("Security interception failed due to: " - + authEvent.getCredentialsNotFoundException() - + "; secure object: " + authEvent.getSource() - + "; configuration attributes: " + logger.warn("Security interception failed due to: " + authEvent.getCredentialsNotFoundException() + + "; secure object: " + authEvent.getSource() + "; configuration attributes: " + authEvent.getConfigAttributeDefinition()); } } @@ -58,12 +51,9 @@ public class LoggerListener implements ApplicationListener { AuthorizationFailureEvent authEvent = (AuthorizationFailureEvent) event; if (logger.isWarnEnabled()) { - logger.warn("Security authorization failed due to: " - + authEvent.getAccessDeniedException() - + "; authenticated principal: " - + authEvent.getAuthentication() + "; secure object: " - + authEvent.getSource() + "; configuration attributes: " - + authEvent.getConfigAttributeDefinition()); + logger.warn("Security authorization failed due to: " + authEvent.getAccessDeniedException() + + "; authenticated principal: " + authEvent.getAuthentication() + "; secure object: " + + authEvent.getSource() + "; configuration attributes: " + authEvent.getConfigAttributeDefinition()); } } @@ -71,9 +61,8 @@ public class LoggerListener implements ApplicationListener { AuthorizedEvent authEvent = (AuthorizedEvent) event; if (logger.isInfoEnabled()) { - logger.info("Security authorized for authenticated principal: " - + authEvent.getAuthentication() + "; secure object: " - + authEvent.getSource() + "; configuration attributes: " + logger.info("Security authorized for authenticated principal: " + authEvent.getAuthentication() + + "; secure object: " + authEvent.getSource() + "; configuration attributes: " + authEvent.getConfigAttributeDefinition()); } } @@ -82,9 +71,7 @@ public class LoggerListener implements ApplicationListener { PublicInvocationEvent authEvent = (PublicInvocationEvent) event; if (logger.isInfoEnabled()) { - logger.info( - "Security interception not required for public secure object: " - + authEvent.getSource()); + logger.info("Security interception not required for public secure object: " + authEvent.getSource()); } } } diff --git a/core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java b/core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java index ad651780e7..06cc66e3b7 100644 --- a/core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java +++ b/core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,18 @@ package org.acegisecurity.event.authorization; /** - * Event that is generated whenever a public secure object is invoked. - * - *

- * A public secure object is a secure object that has no - * ConfigAttributeDefinition defined. A public secure object will - * not cause the SecurityContextHolder to be inspected or authenticated, - * and no authorization will take place. - *

- * - *

- * Published just before the secure object attempts to proceed. - *

+ * Event that is generated whenever a public secure object is invoked.

A public secure object is a secure object + * that has no ConfigAttributeDefinition defined. A public secure object will not cause the + * SecurityContextHolder to be inspected or authenticated, and no authorization will take place.

+ *

Published just before the secure object attempts to proceed.

* * @author Ben Alex * @version $Id$ */ public class PublicInvocationEvent extends AbstractAuthorizationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the event, passing in the public secure object. * * @param secureObject the public secure object diff --git a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java index 79311d1f90..fa6e48e5b7 100644 --- a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java +++ b/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,6 @@ package org.acegisecurity.intercept; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - import org.acegisecurity.AccessDecisionManager; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.AcegiMessageSource; @@ -30,119 +26,89 @@ import org.acegisecurity.AuthenticationManager; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.RunAsManager; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.event.authorization.AuthenticationCredentialsNotFoundEvent; import org.acegisecurity.event.authorization.AuthorizationFailureEvent; import org.acegisecurity.event.authorization.AuthorizedEvent; import org.acegisecurity.event.authorization.PublicInvocationEvent; + import org.acegisecurity.runas.NullRunAsManager; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + /** - * Abstract class that implements security interception for secure objects. - * - *

- * The AbstractSecurityInterceptor will ensure the proper startup - * configuration of the security interceptor. It will also implement the - * proper handling of secure object invocations, being: - * - *

    - *
  1. - * Obtain the {@link Authentication} object from the {@link - * SecurityContextHolder}. - *
  2. - *
  3. - * Determine if the request relates to a secured or public invocation by - * looking up the secure object request against the {@link - * ObjectDefinitionSource}. - *
  4. - *
  5. - * For an invocation that is secured (there is a - * ConfigAttributeDefinition for the secure object invocation): - * - *
      - *
    1. - * If either the {@link org.acegisecurity.Authentication#isAuthenticated()} - * returns false, or the {@link #alwaysReauthenticate} is - * true, authenticate the request against the configured {@link - * AuthenticationManager}. When authenticated, replace the - * Authentication object on the - * SecurityContextHolder with the returned value. - *
    2. - *
    3. - * Authorize the request against the configured {@link AccessDecisionManager}. - *
    4. - *
    5. - * Perform any run-as replacement via the configured {@link RunAsManager}. - *
    6. - *
    7. - * Pass control back to the concrete subclass, which will actually proceed with - * executing the object. A {@link InterceptorStatusToken} is returned so that - * after the subclass has finished proceeding with execution of the object, - * its finally clause can ensure the AbstractSecurityInterceptor - * is re-called and tidies up correctly. - *
    8. - *
    9. - * The concrete subclass will re-call the - * AbstractSecurityInterceptor via the {@link - * #afterInvocation(InterceptorStatusToken, Object)} method. - *
    10. - *
    11. - * If the RunAsManager replaced the Authentication - * object, return the SecurityContextHolder to the object that - * existed after the call to AuthenticationManager. - *
    12. - *
    13. - * If an AfterInvocationManager is defined, invoke the invocation - * manager and allow it to replace the object due to be returned to the - * caller. - *
    14. - *
    - * - *
  6. - *
  7. - * For an invocation that is public (there is no - * ConfigAttributeDefinition for the secure object invocation): - * - *
      - *
    1. - * As described above, the concrete subclass will be returned an - * InterceptorStatusToken which is subsequently re-presented to - * the AbstractSecurityInterceptor after the secure object has - * been executed. The AbstractSecurityInterceptor will take no - * further action when its {@link #afterInvocation(InterceptorStatusToken, - * Object)} is called. - *
    2. - *
    - * - *
  8. - *
  9. - * Control again returns to the concrete subclass, along with the - * Object that should be returned to the caller. The subclass - * will then return that result or exception to the original caller. - *
  10. - *
- *

+ * Abstract class that implements security interception for secure objects.

The + * AbstractSecurityInterceptor will ensure the proper startup configuration of the security interceptor. + * It will also implement the proper handling of secure object invocations, being: + *

    + *
  1. Obtain the {@link Authentication} object from the {@link SecurityContextHolder}.
  2. + *
  3. Determine if the request relates to a secured or public invocation by looking up the secure object + * request against the {@link ObjectDefinitionSource}.
  4. + *
  5. For an invocation that is secured (there is a ConfigAttributeDefinition for the secure + * object invocation): + *
      + *
    1. If either the {@link org.acegisecurity.Authentication#isAuthenticated()} returns + * false, or the {@link #alwaysReauthenticate} is true, authenticate the request + * against the configured {@link AuthenticationManager}. When authenticated, replace the + * Authentication object on the SecurityContextHolder with the returned value.
    2. + *
    3. Authorize the request against the configured {@link AccessDecisionManager}.
    4. + *
    5. Perform any run-as replacement via the configured {@link RunAsManager}.
    6. + *
    7. Pass control back to the concrete subclass, which will actually proceed with executing the + * object. A {@link InterceptorStatusToken} is returned so that after the subclass has finished proceeding + * with execution of the object, its finally clause can ensure the AbstractSecurityInterceptor + * is re-called and tidies up correctly.
    8. + *
    9. The concrete subclass will re-call the AbstractSecurityInterceptor via the + * {@link #afterInvocation(InterceptorStatusToken, Object)} method.
    10. + *
    11. If the RunAsManager replaced the Authentication object, return + * the SecurityContextHolder to the object that existed after the call to + * AuthenticationManager.
    12. + *
    13. If an AfterInvocationManager is defined, invoke the invocation manager and + * allow it to replace the object due to be returned to the caller.
    14. + *
    + *
  6. + *
  7. For an invocation that is public (there is no ConfigAttributeDefinition for the secure + * object invocation): + *
      + *
    1. As described above, the concrete subclass will be returned an + * InterceptorStatusToken which is subsequently re-presented to the + * AbstractSecurityInterceptor after the secure object has been executed. The + * AbstractSecurityInterceptor will take no further action when its {@link + * #afterInvocation(InterceptorStatusToken, Object)} is called.
    2. + *
    + *
  8. + *
  9. Control again returns to the concrete subclass, along with the Object that should be + * returned to the caller. The subclass will then return that result or exception to the original caller.
  10. + *
+ *

* * @author Ben Alex * @version $Id$ */ -public abstract class AbstractSecurityInterceptor implements InitializingBean, - ApplicationEventPublisherAware, MessageSourceAware { - //~ Static fields/initializers ============================================= +public abstract class AbstractSecurityInterceptor implements InitializingBean, ApplicationEventPublisherAware, + MessageSourceAware { + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AccessDecisionManager accessDecisionManager; private AfterInvocationManager afterInvocationManager; @@ -154,22 +120,19 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, private boolean rejectPublicInvocations = false; private boolean validateConfigAttributes = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Completes the work of the AbstractSecurityInterceptor after - * the secure object invocation has been complete + * Completes the work of the AbstractSecurityInterceptor after the secure object invocation + * has been complete * - * @param token as returned by the {@link #beforeInvocation(Object)}} - * method - * @param returnedObject any object returned from the secure object - * invocation (may benull) + * @param token as returned by the {@link #beforeInvocation(Object)}} method + * @param returnedObject any object returned from the secure object invocation (may benull) * - * @return the object the secure object invocation should ultimately return - * to its caller (may be null) + * @return the object the secure object invocation should ultimately return to its caller (may be + * null) */ - protected Object afterInvocation(InterceptorStatusToken token, - Object returnedObject) { + protected Object afterInvocation(InterceptorStatusToken token, Object returnedObject) { if (token == null) { // public object return returnedObject; @@ -177,62 +140,48 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, if (token.isContextHolderRefreshRequired()) { if (logger.isDebugEnabled()) { - logger.debug("Reverting to original Authentication: " - + token.getAuthentication().toString()); + logger.debug("Reverting to original Authentication: " + token.getAuthentication().toString()); } - SecurityContextHolder.getContext() - .setAuthentication(token.getAuthentication()); + SecurityContextHolder.getContext().setAuthentication(token.getAuthentication()); } if (afterInvocationManager != null) { - returnedObject = afterInvocationManager.decide(token - .getAuthentication(), token.getSecureObject(), - token.getAttr(), returnedObject); - } + returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(), + token.getAttr(), returnedObject); + } - return returnedObject; + return returnedObject; } public void afterPropertiesSet() throws Exception { - Assert.notNull(getSecureObjectClass(), - "Subclass must provide a non-null response to getSecureObjectClass()"); + Assert.notNull(getSecureObjectClass(), "Subclass must provide a non-null response to getSecureObjectClass()"); Assert.notNull(this.messages, "A message source must be set"); - Assert.notNull(this.authenticationManager, - "An AuthenticationManager is required"); + Assert.notNull(this.authenticationManager, "An AuthenticationManager is required"); - Assert.notNull(this.accessDecisionManager, - "An AccessDecisionManager is required"); + Assert.notNull(this.accessDecisionManager, "An AccessDecisionManager is required"); Assert.notNull(this.runAsManager, "A RunAsManager is required"); - Assert.notNull(this.obtainObjectDefinitionSource(), - "An ObjectDefinitionSource is required"); + Assert.notNull(this.obtainObjectDefinitionSource(), "An ObjectDefinitionSource is required"); - Assert.isTrue(this.obtainObjectDefinitionSource() - .supports(getSecureObjectClass()), - "ObjectDefinitionSource does not support secure object class: " - + getSecureObjectClass() - ); + Assert.isTrue(this.obtainObjectDefinitionSource().supports(getSecureObjectClass()), + "ObjectDefinitionSource does not support secure object class: " + getSecureObjectClass()); Assert.isTrue(this.runAsManager.supports(getSecureObjectClass()), - "RunAsManager does not support secure object class: " - + getSecureObjectClass() ); + "RunAsManager does not support secure object class: " + getSecureObjectClass()); Assert.isTrue(this.accessDecisionManager.supports(getSecureObjectClass()), - "AccessDecisionManager does not support secure object class: " - + getSecureObjectClass()); + "AccessDecisionManager does not support secure object class: " + getSecureObjectClass()); if (this.afterInvocationManager != null) { Assert.isTrue(this.afterInvocationManager.supports(getSecureObjectClass()), - "AfterInvocationManager does not support secure object class: " - + getSecureObjectClass()); + "AfterInvocationManager does not support secure object class: " + getSecureObjectClass()); } if (this.validateConfigAttributes) { - Iterator iter = this.obtainObjectDefinitionSource() - .getConfigAttributeDefinitions(); + Iterator iter = this.obtainObjectDefinitionSource().getConfigAttributeDefinitions(); if (iter == null) { if (logger.isWarnEnabled()) { @@ -243,18 +192,14 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, Set set = new HashSet(); while (iter.hasNext()) { - ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter - .next(); + ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter.next(); Iterator attributes = def.getConfigAttributes(); while (attributes.hasNext()) { - ConfigAttribute attr = (ConfigAttribute) attributes - .next(); + ConfigAttribute attr = (ConfigAttribute) attributes.next(); - if (!this.runAsManager.supports(attr) - && !this.accessDecisionManager.supports(attr) - && ((this.afterInvocationManager == null) - || !this.afterInvocationManager.supports(attr))) { + if (!this.runAsManager.supports(attr) && !this.accessDecisionManager.supports(attr) + && ((this.afterInvocationManager == null) || !this.afterInvocationManager.supports(attr))) { set.add(attr); } } @@ -265,9 +210,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, logger.info("Validated configuration attributes"); } } else { - throw new IllegalArgumentException( - "Unsupported configuration attributes: " - + set.toString()); + throw new IllegalArgumentException("Unsupported configuration attributes: " + set.toString()); } } } @@ -276,15 +219,14 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, protected InterceptorStatusToken beforeInvocation(Object object) { Assert.notNull(object, "Object was null"); - if(!getSecureObjectClass().isAssignableFrom(object.getClass())) { - throw new IllegalArgumentException ("Security invocation attempted for object " - + object.getClass().getName() - + " but AbstractSecurityInterceptor only configured to support secure objects of type: " - + getSecureObjectClass()); + if (!getSecureObjectClass().isAssignableFrom(object.getClass())) { + throw new IllegalArgumentException("Security invocation attempted for object " + + object.getClass().getName() + + " but AbstractSecurityInterceptor only configured to support secure objects of type: " + + getSecureObjectClass()); } - ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource() - .getAttributes(object); + ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource().getAttributes(object); if ((attr == null) && rejectPublicInvocations) { throw new IllegalArgumentException( @@ -293,25 +235,20 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, if (attr != null) { if (logger.isDebugEnabled()) { - logger.debug("Secure object: " + object.toString() - + "; ConfigAttributes: " + attr.toString()); + logger.debug("Secure object: " + object.toString() + "; ConfigAttributes: " + attr.toString()); } // We check for just the property we're interested in (we do // not call Context.validate() like the ContextInterceptor) if (SecurityContextHolder.getContext().getAuthentication() == null) { - credentialsNotFound(messages.getMessage( - "AbstractSecurityInterceptor.authenticationNotFound", - "An Authentication object was not found in the SecurityContext"), - object, attr); + credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound", + "An Authentication object was not found in the SecurityContext"), object, attr); } // Attempt authentication if not already authenticated, or user always wants reauthentication Authentication authenticated; - if (!SecurityContextHolder.getContext().getAuthentication() - .isAuthenticated() - || alwaysReauthenticate) { + if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) { try { authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext() .getAuthentication()); @@ -321,29 +258,24 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, // We don't authenticated.setAuthentication(true), because each provider should do that if (logger.isDebugEnabled()) { - logger.debug("Successfully Authenticated: " - + authenticated.toString()); + logger.debug("Successfully Authenticated: " + authenticated.toString()); } - SecurityContextHolder.getContext() - .setAuthentication(authenticated); + SecurityContextHolder.getContext().setAuthentication(authenticated); } else { - authenticated = SecurityContextHolder.getContext() - .getAuthentication(); + authenticated = SecurityContextHolder.getContext().getAuthentication(); if (logger.isDebugEnabled()) { - logger.debug("Previously Authenticated: " - + authenticated.toString()); + logger.debug("Previously Authenticated: " + authenticated.toString()); } } // Attempt authorization try { - this.accessDecisionManager.decide(authenticated, object, - attr); + this.accessDecisionManager.decide(authenticated, object, attr); } catch (AccessDeniedException accessDeniedException) { - AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, - attr, authenticated, accessDeniedException); + AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated, + accessDeniedException); this.eventPublisher.publishEvent(event); throw accessDeniedException; @@ -353,59 +285,47 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, logger.debug("Authorization successful"); } - AuthorizedEvent event = new AuthorizedEvent(object, attr, - authenticated); + AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated); this.eventPublisher.publishEvent(event); // Attempt to run as a different user - Authentication runAs = this.runAsManager.buildRunAs(authenticated, - object, attr); + Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr); if (runAs == null) { if (logger.isDebugEnabled()) { - logger.debug( - "RunAsManager did not change Authentication object"); + logger.debug("RunAsManager did not change Authentication object"); } - return new InterceptorStatusToken(authenticated, false, - attr, object); // no further work post-invocation + return new InterceptorStatusToken(authenticated, false, attr, object); // no further work post-invocation } else { if (logger.isDebugEnabled()) { - logger.debug("Switching to RunAs Authentication: " - + runAs.toString()); + logger.debug("Switching to RunAs Authentication: " + runAs.toString()); } SecurityContextHolder.getContext().setAuthentication(runAs); - return new InterceptorStatusToken(authenticated, true, - attr, object); // revert to token.Authenticated post-invocation + return new InterceptorStatusToken(authenticated, true, attr, object); // revert to token.Authenticated post-invocation } } else { if (logger.isDebugEnabled()) { logger.debug("Public object - authentication not attempted"); } - this.eventPublisher.publishEvent(new PublicInvocationEvent( - object)); + this.eventPublisher.publishEvent(new PublicInvocationEvent(object)); return null; // no further work post-invocation } } /** - * Helper method which generates an exception containing the passed - * reason, and publishes an event to the application context. - * - *

- * Always throws an exception. - *

+ * Helper method which generates an exception containing the passed reason, and publishes an event to the + * application context.

Always throws an exception.

* * @param reason to be provided in the exception detail * @param secureObject that was being called * @param configAttribs that were defined for the secureObject */ - private void credentialsNotFound(String reason, Object secureObject, - ConfigAttributeDefinition configAttribs) { + private void credentialsNotFound(String reason, Object secureObject, ConfigAttributeDefinition configAttribs) { AuthenticationCredentialsNotFoundException exception = new AuthenticationCredentialsNotFoundException(reason); AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject, @@ -432,10 +352,9 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, } /** - * Indicates the type of secure objects the subclass will be presenting - * to the abstract parent for processing. This is used to ensure - * collaborators wired to the AbstractSecurityInterceptor - * all support the indicated secure object class. + * Indicates the type of secure objects the subclass will be presenting to the abstract parent for + * processing. This is used to ensure collaborators wired to the AbstractSecurityInterceptor all + * support the indicated secure object class. * * @return the type of secure object the subclass provides services for */ @@ -455,36 +374,29 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, public abstract ObjectDefinitionSource obtainObjectDefinitionSource(); - public void setAccessDecisionManager( - AccessDecisionManager accessDecisionManager) { + public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) { this.accessDecisionManager = accessDecisionManager; } - public void setAfterInvocationManager( - AfterInvocationManager afterInvocationManager) { + public void setAfterInvocationManager(AfterInvocationManager afterInvocationManager) { this.afterInvocationManager = afterInvocationManager; } /** - * Indicates whether the AbstractSecurityInterceptor - * should ignore the {@link Authentication#isAuthenticated()} - * property. Defaults to false, meaning by default the - * Authentication.isAuthenticated() property is trusted - * and re-authentication will not occur if the principal has already - * been authenticated. + * Indicates whether the AbstractSecurityInterceptor should ignore the {@link + * Authentication#isAuthenticated()} property. Defaults to false, meaning by default the + * Authentication.isAuthenticated() property is trusted and re-authentication will not occur if the + * principal has already been authenticated. * - * @param alwaysReauthenticate true to force - * AbstractSecurityInterceptor to disregard the - * value of Authentication.isAuthenticated() and - * always re-authenticate the request (defaults to - * false). + * @param alwaysReauthenticate true to force AbstractSecurityInterceptor to disregard the + * value of Authentication.isAuthenticated() and always re-authenticate the request (defaults + * to false). */ public void setAlwaysReauthenticate(boolean alwaysReauthenticate) { this.alwaysReauthenticate = alwaysReauthenticate; } - public void setApplicationEventPublisher( - ApplicationEventPublisher eventPublisher) { + public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } @@ -497,21 +409,16 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, } /** - * By rejecting public invocations (and setting this property to - * true), essentially you are ensuring that every secure - * object invocation advised by - * AbstractSecurityInterceptor has a configuration - * attribute defined. This is useful to ensure a "fail safe" mode - * where undeclared secure objects will be rejected and configuration - * omissions detected early. An IllegalArgumentException - * will be thrown by the AbstractSecurityInterceptor if - * you set this property to true and an attempt is made - * to invoke a secure object that has no configuration attributes. + * By rejecting public invocations (and setting this property to true), essentially you are + * ensuring that every secure object invocation advised by AbstractSecurityInterceptor has a + * configuration attribute defined. This is useful to ensure a "fail safe" mode where undeclared secure objects + * will be rejected and configuration omissions detected early. An IllegalArgumentException will be + * thrown by the AbstractSecurityInterceptor if you set this property to true and an + * attempt is made to invoke a secure object that has no configuration attributes. * - * @param rejectPublicInvocations set to true to reject - * invocations of secure objects that have no configuration - * attributes (by default it is true which treats - * undeclared secure objects as "public" or unauthorized) + * @param rejectPublicInvocations set to true to reject invocations of secure objects that have no + * configuration attributes (by default it is true which treats undeclared secure objects as + * "public" or unauthorized) */ public void setRejectPublicInvocations(boolean rejectPublicInvocations) { this.rejectPublicInvocations = rejectPublicInvocations; @@ -521,8 +428,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, this.runAsManager = runAsManager; } - public void setValidateConfigAttributes( - boolean validateConfigAttributes) { + public void setValidateConfigAttributes(boolean validateConfigAttributes) { this.validateConfigAttributes = validateConfigAttributes; } } diff --git a/core/src/main/java/org/acegisecurity/intercept/InterceptorStatusToken.java b/core/src/main/java/org/acegisecurity/intercept/InterceptorStatusToken.java index 299cc74ace..72e7a2baba 100644 --- a/core/src/main/java/org/acegisecurity/intercept/InterceptorStatusToken.java +++ b/core/src/main/java/org/acegisecurity/intercept/InterceptorStatusToken.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,38 +20,33 @@ import org.acegisecurity.ConfigAttributeDefinition; /** - * A return object received by {@link AbstractSecurityInterceptor} subclasses. - * - *

- * This class reflects the status of the security interception, so that the - * final call to {@link - * org.acegisecurity.intercept.AbstractSecurityInterceptor#afterInvocation(InterceptorStatusToken, - * Object)} can tidy up correctly. - *

+ * A return object received by {@link AbstractSecurityInterceptor} subclasses.

This class reflects the status of + * the security interception, so that the final call to {@link + * org.acegisecurity.intercept.AbstractSecurityInterceptor#afterInvocation(InterceptorStatusToken, Object)} can tidy + * up correctly.

* * @author Ben Alex * @version $Id$ */ public class InterceptorStatusToken { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authentication authentication; private ConfigAttributeDefinition attr; private Object secureObject; private boolean contextHolderRefreshRequired; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public InterceptorStatusToken(Authentication authentication, - boolean contextHolderRefreshRequired, ConfigAttributeDefinition attr, - Object secureObject) { + public InterceptorStatusToken(Authentication authentication, boolean contextHolderRefreshRequired, + ConfigAttributeDefinition attr, Object secureObject) { this.authentication = authentication; this.contextHolderRefreshRequired = contextHolderRefreshRequired; this.attr = attr; this.secureObject = secureObject; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public ConfigAttributeDefinition getAttr() { return attr; @@ -61,11 +56,11 @@ public class InterceptorStatusToken { return authentication; } - public boolean isContextHolderRefreshRequired() { - return contextHolderRefreshRequired; - } - public Object getSecureObject() { return secureObject; } + + public boolean isContextHolderRefreshRequired() { + return contextHolderRefreshRequired; + } } diff --git a/core/src/main/java/org/acegisecurity/intercept/ObjectDefinitionSource.java b/core/src/main/java/org/acegisecurity/intercept/ObjectDefinitionSource.java index b6fa907115..7b575ffa6d 100644 --- a/core/src/main/java/org/acegisecurity/intercept/ObjectDefinitionSource.java +++ b/core/src/main/java/org/acegisecurity/intercept/ObjectDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,48 +29,34 @@ import java.util.Iterator; * @version $Id$ */ public interface ObjectDefinitionSource { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Accesses the ConfigAttributeDefinition that applies to a - * given secure object. - * - *

- * Returns null if no ConfigAttribiteDefinition - * applies. - *

+ * Accesses the ConfigAttributeDefinition that applies to a given secure object.

Returns + * null if no ConfigAttribiteDefinition applies.

* * @param object the object being secured * - * @return the ConfigAttributeDefinition that applies to the - * passed object + * @return the ConfigAttributeDefinition that applies to the passed object * - * @throws IllegalArgumentException if the passed object is not of a type - * supported by the ObjectDefinitionSource - * implementation + * @throws IllegalArgumentException if the passed object is not of a type supported by the + * ObjectDefinitionSource implementation */ public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException; /** - * If available, all of the ConfigAttributeDefinitions defined - * by the implementing class. - * - *

- * This is used by the {@link AbstractSecurityInterceptor} to perform - * startup time validation of each ConfigAttribute configured - * against it. - *

+ * If available, all of the ConfigAttributeDefinitions defined by the implementing class.

This + * is used by the {@link AbstractSecurityInterceptor} to perform startup time validation of each + * ConfigAttribute configured against it.

* - * @return an iterator over all the ConfigAttributeDefinitions - * or null if unsupported + * @return an iterator over all the ConfigAttributeDefinitions or null if unsupported */ public Iterator getConfigAttributeDefinitions(); /** - * Indicates whether the ObjectDefinitionSource implementation - * is able to provide ConfigAttributeDefinitions for the - * indicated secure object type. + * Indicates whether the ObjectDefinitionSource implementation is able to provide + * ConfigAttributeDefinitions for the indicated secure object type. * * @param clazz the class that is being queried * diff --git a/core/src/main/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSource.java b/core/src/main/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSource.java index 7bb6a7282d..f13919b327 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSource.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.CodeSignature; + import org.springframework.util.Assert; import java.lang.reflect.Method; @@ -35,13 +36,12 @@ import java.lang.reflect.Method; * @author Ben Alex * @version $Id$ */ -public abstract class AbstractMethodDefinitionSource - implements MethodDefinitionSource { - //~ Static fields/initializers ============================================= +public abstract class AbstractMethodDefinitionSource implements MethodDefinitionSource { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AbstractMethodDefinitionSource.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException { @@ -55,8 +55,7 @@ public abstract class AbstractMethodDefinitionSource JoinPoint jp = (JoinPoint) object; Class targetClazz = jp.getTarget().getClass(); String targetMethodName = jp.getStaticPart().getSignature().getName(); - Class[] types = ((CodeSignature) jp.getStaticPart().getSignature()) - .getParameterTypes(); + Class[] types = ((CodeSignature) jp.getStaticPart().getSignature()).getParameterTypes(); if (logger.isDebugEnabled()) { logger.debug("Target Class: " + targetClazz); @@ -64,8 +63,7 @@ public abstract class AbstractMethodDefinitionSource for (int i = 0; i < types.length; i++) { if (logger.isDebugEnabled()) { - logger.debug("Target Method Arg #" + i + ": " - + types[i]); + logger.debug("Target Method Arg #" + i + ": " + types[i]); } } } @@ -80,31 +78,19 @@ public abstract class AbstractMethodDefinitionSource throw new IllegalArgumentException("Object must be a MethodInvocation or JoinPoint"); } - public boolean supports(Class clazz) { - return (MethodInvocation.class.isAssignableFrom(clazz) - || JoinPoint.class.isAssignableFrom(clazz)); - } - /** - * Performs the actual lookup of the relevant - * ConfigAttributeDefinition for the specified - * Method which is subject of the method invocation. - * - *

- * Provided so subclasses need only to provide one basic method to properly - * interface with the MethodDefinitionSource. - *

- * - *

- * Returns null if there are no matching attributes for the - * method. - *

+ * Performs the actual lookup of the relevant ConfigAttributeDefinition for the specified + * Method which is subject of the method invocation.

Provided so subclasses need only to + * provide one basic method to properly interface with the MethodDefinitionSource.

+ *

Returns null if there are no matching attributes for the method.

* - * @param method the method being invoked for which configuration - * attributes should be looked up + * @param method the method being invoked for which configuration attributes should be looked up * - * @return the ConfigAttributeDefinition that applies to the - * specified Method + * @return the ConfigAttributeDefinition that applies to the specified Method */ protected abstract ConfigAttributeDefinition lookupAttributes(Method method); + + public boolean supports(Class clazz) { + return (MethodInvocation.class.isAssignableFrom(clazz) || JoinPoint.class.isAssignableFrom(clazz)); + } } diff --git a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionAttributes.java b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionAttributes.java index 87d237cae2..2d30e9906b 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionAttributes.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionAttributes.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,56 +27,78 @@ import java.util.Iterator; /** - * Stores a {@link ConfigAttributeDefinition} for each method signature defined - * by Commons Attributes. - * - *

- * This class will only detect those attributes which are defined for: - * - *

    - *
  • - * The class-wide attributes defined for the intercepted class. - *
  • - *
  • - * The class-wide attributes defined for interfaces explicitly implemented by - * the intercepted class. - *
  • - *
  • - * The method-specific attributes defined for the intercepted method of the - * intercepted class. - *
  • - *
  • - * The method-specific attributes defined by any explicitly implemented - * interface if that interface contains a method signature matching that of - * the intercepted method. - *
  • - *
- *

- * - *

- * Note that attributes defined against parent classes (either for their - * methods or interfaces) are not detected. The attributes must be defined - * against an explicit method or interface on the intercepted class. - *

- * - *

- * Attributes detected that do not implement {@link ConfigAttribute} will be - * ignored. - *

+ * Stores a {@link ConfigAttributeDefinition} for each method signature defined by Commons Attributes.

This class + * will only detect those attributes which are defined for: + *

    + *
  • The class-wide attributes defined for the intercepted class.
  • + *
  • The class-wide attributes defined for interfaces explicitly implemented by the intercepted class.
  • + *
  • The method-specific attributes defined for the intercepted method of the intercepted class.
  • + *
  • The method-specific attributes defined by any explicitly implemented interface if that interface + * contains a method signature matching that of the intercepted method.
  • + *
+ *

+ *

Note that attributes defined against parent classes (either for their methods or interfaces) are not + * detected. The attributes must be defined against an explicit method or interface on the intercepted class.

+ *

Attributes detected that do not implement {@link ConfigAttribute} will be ignored.

* * @author Cameron Braid * @author Ben Alex * @version $Id$ */ public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Attributes attributes; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setAttributes(Attributes attributes) { - this.attributes = attributes; + private void add(ConfigAttributeDefinition definition, Collection attribs) { + for (Iterator iter = attribs.iterator(); iter.hasNext();) { + Object o = (Object) iter.next(); + + if (o instanceof ConfigAttribute) { + definition.addConfigAttribute((ConfigAttribute) o); + } + } + } + + private void addClassAttributes(ConfigAttributeDefinition definition, Class clazz) { + addClassAttributes(definition, new Class[] {clazz}); + } + + private void addClassAttributes(ConfigAttributeDefinition definition, Class[] clazz) { + for (int i = 0; i < clazz.length; i++) { + Collection classAttributes = attributes.getAttributes(clazz[i]); + + if (classAttributes != null) { + add(definition, classAttributes); + } + } + } + + private void addInterfaceMethodAttributes(ConfigAttributeDefinition definition, Method method) { + Class[] interfaces = method.getDeclaringClass().getInterfaces(); + + for (int i = 0; i < interfaces.length; i++) { + Class clazz = interfaces[i]; + + try { + Method m = clazz.getDeclaredMethod(method.getName(), (Class[]) method.getParameterTypes()); + addMethodAttributes(definition, m); + } catch (Exception e) { + // this won't happen since we are getting a method from an interface that + // the declaring class implements + } + } + } + + private void addMethodAttributes(ConfigAttributeDefinition definition, Method method) { + // add the method level attributes + Collection methodAttributes = attributes.getAttributes(method); + + if (methodAttributes != null) { + add(definition, methodAttributes); + } } public Iterator getConfigAttributeDefinitions() { @@ -107,57 +129,7 @@ public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource { } } - private void add(ConfigAttributeDefinition definition, Collection attribs) { - for (Iterator iter = attribs.iterator(); iter.hasNext();) { - Object o = (Object) iter.next(); - - if (o instanceof ConfigAttribute) { - definition.addConfigAttribute((ConfigAttribute) o); - } - } - } - - private void addClassAttributes(ConfigAttributeDefinition definition, - Class clazz) { - addClassAttributes(definition, new Class[] {clazz}); - } - - private void addClassAttributes(ConfigAttributeDefinition definition, - Class[] clazz) { - for (int i = 0; i < clazz.length; i++) { - Collection classAttributes = attributes.getAttributes(clazz[i]); - - if (classAttributes != null) { - add(definition, classAttributes); - } - } - } - - private void addInterfaceMethodAttributes( - ConfigAttributeDefinition definition, Method method) { - Class[] interfaces = method.getDeclaringClass().getInterfaces(); - - for (int i = 0; i < interfaces.length; i++) { - Class clazz = interfaces[i]; - - try { - Method m = clazz.getDeclaredMethod(method.getName(), - (Class[]) method.getParameterTypes()); - addMethodAttributes(definition, m); - } catch (Exception e) { - // this won't happen since we are getting a method from an interface that - // the declaring class implements - } - } - } - - private void addMethodAttributes(ConfigAttributeDefinition definition, - Method method) { - // add the method level attributes - Collection methodAttributes = attributes.getAttributes(method); - - if (methodAttributes != null) { - add(definition, methodAttributes); - } + public void setAttributes(Attributes attributes) { + this.attributes = attributes; } } diff --git a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionMap.java b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionMap.java index 3ad5bf1621..ac667ec003 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionMap.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionMap.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,44 +31,29 @@ import java.util.Map; /** - * Stores a {@link ConfigAttributeDefinition} for each method signature defined - * in a bean context. - * - *

- * For consistency with {@link MethodDefinitionAttributes} as well as support - * for MethodDefinitionSourceAdvisor, this implementation will - * return a ConfigAttributeDefinition containing all - * configuration attributes defined against: - * - *

    - *
  • - * The method-specific attributes defined for the intercepted method of the - * intercepted class. - *
  • - *
  • - * The method-specific attributes defined by any explicitly implemented - * interface if that interface contains a method signature matching that of - * the intercepted method. - *
  • - *
- *

- * - *

- * In general you should therefore define the interface methods of your - * secure objects, not the implementations. For example, define - * com.company.Foo.findAll=ROLE_TEST but not - * com.company.FooImpl.findAll=ROLE_TEST. - *

+ * Stores a {@link ConfigAttributeDefinition} for each method signature defined in a bean context.

For + * consistency with {@link MethodDefinitionAttributes} as well as support for + * MethodDefinitionSourceAdvisor, this implementation will return a + * ConfigAttributeDefinition containing all configuration attributes defined against: + *

    + *
  • The method-specific attributes defined for the intercepted method of the intercepted class.
  • + *
  • The method-specific attributes defined by any explicitly implemented interface if that interface + * contains a method signature matching that of the intercepted method.
  • + *
+ *

+ *

In general you should therefore define the interface methods of your secure objects, not the + * implementations. For example, define com.company.Foo.findAll=ROLE_TEST but not + * com.company.FooImpl.findAll=ROLE_TEST.

* * @author Ben Alex * @version $Id$ */ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(MethodDefinitionMap.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ /** Map from Method to ApplicationDefinition */ protected Map methodMap = new HashMap(); @@ -76,49 +61,23 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { /** Map from Method to name pattern used for registration */ private Map nameMap = new HashMap(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the configuration attributes explicitly defined against this - * bean. This method will not return implicit configuration attributes - * that may be returned by {@link #lookupAttributes(Method)} as it does - * not have access to a method invocation at this time. - * - * @return the attributes explicitly defined against this bean - */ - public Iterator getConfigAttributeDefinitions() { - return methodMap.values().iterator(); - } - - /** - * Obtains the number of configuration attributes explicitly defined - * against this bean. This method will not return implicit configuration - * attributes that may be returned by {@link #lookupAttributes(Method)} as - * it does not have access to a method invocation at this time. - * - * @return the number of configuration attributes explicitly defined - * against this bean - */ - public int getMethodMapSize() { - return this.methodMap.size(); - } - - /** - * Add configuration attributes for a secure method. Method names can end - * or start with * for matching multiple methods. + * Add configuration attributes for a secure method. Method names can end or start with * + * for matching multiple methods. * * @param method the method to be secured * @param attr required authorities associated with the method */ public void addSecureMethod(Method method, ConfigAttributeDefinition attr) { - logger.info("Adding secure method [" + method + "] with attributes [" - + attr + "]"); + logger.info("Adding secure method [" + method + "] with attributes [" + attr + "]"); this.methodMap.put(method, attr); } /** - * Add configuration attributes for a secure method. Method names can end - * or start with * for matching multiple methods. + * Add configuration attributes for a secure method. Method names can end or start with * + * for matching multiple methods. * * @param name class and method name, separated by a dot * @param attr required authorities associated with the method @@ -129,26 +88,23 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { int lastDotIndex = name.lastIndexOf("."); if (lastDotIndex == -1) { - throw new IllegalArgumentException("'" + name - + "' is not a valid method name: format is FQN.methodName"); + throw new IllegalArgumentException("'" + name + "' is not a valid method name: format is FQN.methodName"); } String className = name.substring(0, lastDotIndex); String methodName = name.substring(lastDotIndex + 1); try { - Class clazz = Class.forName(className, true, - Thread.currentThread().getContextClassLoader()); + Class clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader()); addSecureMethod(clazz, methodName, attr); } catch (ClassNotFoundException ex) { - throw new IllegalArgumentException("Class '" + className - + "' not found"); + throw new IllegalArgumentException("Class '" + className + "' not found"); } } /** - * Add configuration attributes for a secure method. Method names can end - * or start with * for matching multiple methods. + * Add configuration attributes for a secure method. Method names can end or start with * + * for matching multiple methods. * * @param clazz target interface or class * @param mappedName mapped method name @@ -156,28 +112,24 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { * * @throws IllegalArgumentException DOCUMENT ME! */ - public void addSecureMethod(Class clazz, String mappedName, - ConfigAttributeDefinition attr) { + public void addSecureMethod(Class clazz, String mappedName, ConfigAttributeDefinition attr) { String name = clazz.getName() + '.' + mappedName; if (logger.isDebugEnabled()) { - logger.debug("Adding secure method [" + name - + "] with attributes [" + attr + "]"); + logger.debug("Adding secure method [" + name + "] with attributes [" + attr + "]"); } Method[] methods = clazz.getDeclaredMethods(); List matchingMethods = new ArrayList(); for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().equals(mappedName) - || isMatch(methods[i].getName(), mappedName)) { + if (methods[i].getName().equals(mappedName) || isMatch(methods[i].getName(), mappedName)) { matchingMethods.add(methods[i]); } } if (matchingMethods.isEmpty()) { - throw new IllegalArgumentException("Couldn't find method '" - + mappedName + "' on " + clazz); + throw new IllegalArgumentException("Couldn't find method '" + mappedName + "' on " + clazz); } // register all matching methods @@ -185,33 +137,64 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { Method method = (Method) it.next(); String regMethodName = (String) this.nameMap.get(method); - if ((regMethodName == null) - || (!regMethodName.equals(name) - && (regMethodName.length() <= name.length()))) { + if ((regMethodName == null) || (!regMethodName.equals(name) && (regMethodName.length() <= name.length()))) { // no already registered method name, or more specific // method name specification now -> (re-)register method if (regMethodName != null) { - logger.debug("Replacing attributes for secure method [" - + method + "]: current name [" + name + logger.debug("Replacing attributes for secure method [" + method + "]: current name [" + name + "] is more specific than [" + regMethodName + "]"); } this.nameMap.put(method, name); addSecureMethod(method, attr); } else { - logger.debug("Keeping attributes for secure method [" + method - + "]: current name [" + name + logger.debug("Keeping attributes for secure method [" + method + "]: current name [" + name + "] is not more specific than [" + regMethodName + "]"); } } } + /** + * Obtains the configuration attributes explicitly defined against this bean. This method will not return + * implicit configuration attributes that may be returned by {@link #lookupAttributes(Method)} as it does not have + * access to a method invocation at this time. + * + * @return the attributes explicitly defined against this bean + */ + public Iterator getConfigAttributeDefinitions() { + return methodMap.values().iterator(); + } + + /** + * Obtains the number of configuration attributes explicitly defined against this bean. This method will + * not return implicit configuration attributes that may be returned by {@link #lookupAttributes(Method)} as it + * does not have access to a method invocation at this time. + * + * @return the number of configuration attributes explicitly defined against this bean + */ + public int getMethodMapSize() { + return this.methodMap.size(); + } + + /** + * Return if the given method name matches the mapped name. The default implementation checks for "xxx" and + * "xxx" matches. + * + * @param methodName the method name of the class + * @param mappedName the name in the descriptor + * + * @return if the names match + */ + private boolean isMatch(String methodName, String mappedName) { + return (mappedName.endsWith("*") && methodName.startsWith(mappedName.substring(0, mappedName.length() - 1))) + || (mappedName.startsWith("*") && methodName.endsWith(mappedName.substring(1, mappedName.length()))); + } + protected ConfigAttributeDefinition lookupAttributes(Method method) { ConfigAttributeDefinition definition = new ConfigAttributeDefinition(); // Add attributes explictly defined for this method invocation - ConfigAttributeDefinition directlyAssigned = (ConfigAttributeDefinition) this.methodMap - .get(method); + ConfigAttributeDefinition directlyAssigned = (ConfigAttributeDefinition) this.methodMap.get(method); merge(definition, directlyAssigned); // Add attributes explicitly defined for this method invocation's interfaces @@ -222,10 +205,8 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { try { // Look for the method on the current interface - Method interfaceMethod = clazz.getDeclaredMethod(method.getName(), - (Class[]) method.getParameterTypes()); - ConfigAttributeDefinition interfaceAssigned = (ConfigAttributeDefinition) this.methodMap - .get(interfaceMethod); + Method interfaceMethod = clazz.getDeclaredMethod(method.getName(), (Class[]) method.getParameterTypes()); + ConfigAttributeDefinition interfaceAssigned = (ConfigAttributeDefinition) this.methodMap.get(interfaceMethod); merge(definition, interfaceAssigned); } catch (Exception e) { // skip this interface @@ -240,25 +221,7 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource { } } - /** - * Return if the given method name matches the mapped name. The default - * implementation checks for "xxx" and "xxx" matches. - * - * @param methodName the method name of the class - * @param mappedName the name in the descriptor - * - * @return if the names match - */ - private boolean isMatch(String methodName, String mappedName) { - return (mappedName.endsWith("*") - && methodName.startsWith(mappedName.substring(0, mappedName.length() - - 1))) - || (mappedName.startsWith("*") - && methodName.endsWith(mappedName.substring(1, mappedName.length()))); - } - - private void merge(ConfigAttributeDefinition definition, - ConfigAttributeDefinition toMerge) { + private void merge(ConfigAttributeDefinition definition, ConfigAttributeDefinition toMerge) { if (toMerge == null) { return; } diff --git a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSource.java b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSource.java index 05c71e6623..97f538d465 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSource.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditor.java b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditor.java index a0a1e9e57c..090a064f52 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditor.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,22 +30,18 @@ import java.util.Properties; /** - * Property editor to assist with the setup of a {@link - * MethodDefinitionSource}. - * - *

- * The class creates and populates a {@link MethodDefinitionMap}. - *

+ * Property editor to assist with the setup of a {@link MethodDefinitionSource}.

The class creates and populates + * a {@link MethodDefinitionMap}.

* * @author Ben Alex * @version $Id$ */ public class MethodDefinitionSourceEditor extends PropertyEditorSupport { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(MethodDefinitionSourceEditor.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void setAsText(String s) throws IllegalArgumentException { MethodDefinitionMap source = new MethodDefinitionMap(); @@ -69,8 +65,7 @@ public class MethodDefinitionSourceEditor extends PropertyEditorSupport { // Convert value to series of security configuration attributes configAttribEd.setAsText(value); - ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd - .getValue(); + ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd.getValue(); // Register name and attribute source.addSecureMethod(name, attr); diff --git a/core/src/main/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluator.java b/core/src/main/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluator.java index e459f48bd8..e4b00cd085 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluator.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluator.java @@ -32,32 +32,25 @@ import org.springframework.util.Assert; /** - * Allows users to determine whether they have "before invocation" privileges - * for a given method invocation. - * - *

- * Of course, if an {@link org.acegisecurity.AfterInvocationManager} is used to - * authorize the result of a method invocation, this class cannot - * assist determine whether or not the AfterInvocationManager - * will enable access. Instead this class aims to allow applications to - * determine whether or not the current principal would be allowed to at least - * attempt to invoke the method, irrespective of the "after" invocation - * handling. - *

+ * Allows users to determine whether they have "before invocation" privileges for a given method invocation.

Of + * course, if an {@link org.acegisecurity.AfterInvocationManager} is used to authorize the result of a method + * invocation, this class cannot assist determine whether or not the AfterInvocationManager will enable + * access. Instead this class aims to allow applications to determine whether or not the current principal would be + * allowed to at least attempt to invoke the method, irrespective of the "after" invocation handling.

* * @author Ben Alex * @version $Id$ */ public class MethodInvocationPrivilegeEvaluator implements InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(MethodInvocationPrivilegeEvaluator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AbstractSecurityInterceptor securityInterceptor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(securityInterceptor, "SecurityInterceptor required"); @@ -65,11 +58,9 @@ public class MethodInvocationPrivilegeEvaluator implements InitializingBean { public boolean isAllowed(MethodInvocation mi, Authentication authentication) { Assert.notNull(mi, "MethodInvocation required"); - Assert.notNull(mi.getMethod(), - "MethodInvocation must provide a non-null getMethod()"); + Assert.notNull(mi.getMethod(), "MethodInvocation must provide a non-null getMethod()"); - ConfigAttributeDefinition attrs = securityInterceptor.obtainObjectDefinitionSource() - .getAttributes(mi); + ConfigAttributeDefinition attrs = securityInterceptor.obtainObjectDefinitionSource().getAttributes(mi); if (attrs == null) { if (securityInterceptor.isRejectPublicInvocations()) { @@ -79,17 +70,16 @@ public class MethodInvocationPrivilegeEvaluator implements InitializingBean { return true; } - if (authentication == null || authentication.getAuthorities() == null || authentication.getAuthorities().length == 0) { + if ((authentication == null) || (authentication.getAuthorities() == null) + || (authentication.getAuthorities().length == 0)) { return false; } try { - securityInterceptor.getAccessDecisionManager() - .decide(authentication, mi, attrs); + securityInterceptor.getAccessDecisionManager().decide(authentication, mi, attrs); } catch (AccessDeniedException unauthorized) { if (logger.isDebugEnabled()) { - logger.debug(mi.toString() + " denied for " - + authentication.toString(), unauthorized); + logger.debug(mi.toString() + " denied for " + authentication.toString(), unauthorized); } return false; @@ -98,12 +88,9 @@ public class MethodInvocationPrivilegeEvaluator implements InitializingBean { return true; } - public void setSecurityInterceptor( - AbstractSecurityInterceptor securityInterceptor) { - Assert.notNull(securityInterceptor, - "AbstractSecurityInterceptor cannot be null"); - Assert.isTrue(MethodInvocation.class.equals( - securityInterceptor.getSecureObjectClass()), + public void setSecurityInterceptor(AbstractSecurityInterceptor securityInterceptor) { + Assert.notNull(securityInterceptor, "AbstractSecurityInterceptor cannot be null"); + Assert.isTrue(MethodInvocation.class.equals(securityInterceptor.getSecureObjectClass()), "AbstractSecurityInterceptor does not support MethodInvocations"); Assert.notNull(securityInterceptor.getAccessDecisionManager(), "AbstractSecurityInterceptor must provide a non-null AccessDecisionManager"); diff --git a/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisor.java b/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisor.java index bf4e406017..9cfdf3ab0b 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisor.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,52 +27,37 @@ import java.lang.reflect.Method; /** - * Advisor driven by a {@link MethodDefinitionSource}, used to exclude a {@link - * MethodSecurityInterceptor} from public (ie non-secure) methods. - * - *

- * Because the AOP framework caches advice calculations, this is normally - * faster than just letting the MethodSecurityInterceptor run and - * find out itself that it has no work to do. - *

- * - *

- * This class also allows the use of Spring's - * DefaultAdvisorAutoProxyCreator, which makes configuration - * easier than setup a ProxyFactoryBean for each object requiring - * security. Note that autoproxying is not supported for BeanFactory - * implementations, as post-processing is automatic only for application - * contexts. - *

- * - *

- * Based on Spring's TransactionAttributeSourceAdvisor. - *

+ * Advisor driven by a {@link MethodDefinitionSource}, used to exclude a {@link MethodSecurityInterceptor} from + * public (ie non-secure) methods.

Because the AOP framework caches advice calculations, this is normally faster + * than just letting the MethodSecurityInterceptor run and find out itself that it has no work to do.

+ *

This class also allows the use of Spring's DefaultAdvisorAutoProxyCreator, which makes + * configuration easier than setup a ProxyFactoryBean for each object requiring security. Note that + * autoproxying is not supported for BeanFactory implementations, as post-processing is automatic only for application + * contexts.

+ *

Based on Spring's TransactionAttributeSourceAdvisor.

* * @author Ben Alex * @version $Id$ */ -public class MethodDefinitionSourceAdvisor - extends StaticMethodMatcherPointcutAdvisor { - //~ Instance fields ======================================================== +public class MethodDefinitionSourceAdvisor extends StaticMethodMatcherPointcutAdvisor { + //~ Instance fields ================================================================================================ private MethodDefinitionSource transactionAttributeSource; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodDefinitionSourceAdvisor(MethodSecurityInterceptor advice) { super(advice); if (advice.getObjectDefinitionSource() == null) { - throw new AopConfigException( - "Cannot construct a MethodDefinitionSourceAdvisor using a " + throw new AopConfigException("Cannot construct a MethodDefinitionSourceAdvisor using a " + "MethodSecurityInterceptor that has no ObjectDefinitionSource configured"); } this.transactionAttributeSource = advice.getObjectDefinitionSource(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean matches(Method m, Class targetClass) { MethodInvocation methodInvocation = new InternalMethodInvocation(m); @@ -80,15 +65,11 @@ public class MethodDefinitionSourceAdvisor return (this.transactionAttributeSource.getAttributes(methodInvocation) != null); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** - * Represents a MethodInvocation. - * - *

- * Required as MethodDefinitionSource only supports lookup of - * configuration attributes for MethodInvocations. - *

+ * Represents a MethodInvocation.

Required as MethodDefinitionSource only + * supports lookup of configuration attributes for MethodInvocations.

*/ class InternalMethodInvocation implements MethodInvocation { Method method; diff --git a/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptor.java index 8561876f24..c710a40d75 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptor.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,34 +25,21 @@ import org.aopalliance.intercept.MethodInvocation; /** - * Provides security interception of AOP Alliance based method invocations. - * - *

- * The ObjectDefinitionSource required by this security - * interceptor is of type {@link MethodDefinitionSource}. This is shared with - * the AspectJ based security interceptor - * (AspectJSecurityInterceptor), since both work with Java - * Methods. - *

- * - *

- * Refer to {@link AbstractSecurityInterceptor} for details on the workflow. - *

+ * Provides security interception of AOP Alliance based method invocations.

The + * ObjectDefinitionSource required by this security interceptor is of type {@link + * MethodDefinitionSource}. This is shared with the AspectJ based security interceptor + * (AspectJSecurityInterceptor), since both work with Java Methods.

+ *

Refer to {@link AbstractSecurityInterceptor} for details on the workflow.

* * @author Ben Alex * @version $Id$ */ -public class MethodSecurityInterceptor extends AbstractSecurityInterceptor - implements MethodInterceptor { - //~ Instance fields ======================================================== +public class MethodSecurityInterceptor extends AbstractSecurityInterceptor implements MethodInterceptor { + //~ Instance fields ================================================================================================ private MethodDefinitionSource objectDefinitionSource; - //~ Methods ================================================================ - - public void setObjectDefinitionSource(MethodDefinitionSource newSource) { - this.objectDefinitionSource = newSource; - } + //~ Methods ======================================================================================================== public MethodDefinitionSource getObjectDefinitionSource() { return this.objectDefinitionSource; @@ -63,8 +50,7 @@ public class MethodSecurityInterceptor extends AbstractSecurityInterceptor } /** - * This method should be used to enforce security on a - * MethodInvocation. + * This method should be used to enforce security on a MethodInvocation. * * @param mi The method being invoked which requires a security decision * @@ -88,4 +74,8 @@ public class MethodSecurityInterceptor extends AbstractSecurityInterceptor public ObjectDefinitionSource obtainObjectDefinitionSource() { return this.objectDefinitionSource; } + + public void setObjectDefinitionSource(MethodDefinitionSource newSource) { + this.objectDefinitionSource = newSource; + } } diff --git a/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJCallback.java b/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJCallback.java index 1a3086eb0e..b1e4b0583b 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJCallback.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJCallback.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ package org.acegisecurity.intercept.method.aspectj; * @version $Id$ */ public interface AspectJCallback { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object proceedWithObject(); } diff --git a/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptor.java index 8c88e89a91..8e650b9cd6 100644 --- a/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptor.java +++ b/core/src/main/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,41 +24,23 @@ import org.aspectj.lang.JoinPoint; /** - * Provides security interception of AspectJ method invocations. - * - *

- * The ObjectDefinitionSource required by this security - * interceptor is of type {@link MethodDefinitionSource}. This is shared with - * the AOP Alliance based security interceptor - * (MethodSecurityInterceptor), since both work with Java - * Methods. - *

- * - *

- * The secure object type is org.aspectj.lang.JoinPoint, which is - * passed from the relevant around() advice. The - * around() advice also passes an anonymous implementation of - * {@link AspectJCallback} which contains the call for AspectJ to continue - * processing: return proceed();. - *

- * - *

- * Refer to {@link AbstractSecurityInterceptor} for details on the workflow. - *

+ * Provides security interception of AspectJ method invocations.

The ObjectDefinitionSource required + * by this security interceptor is of type {@link MethodDefinitionSource}. This is shared with the AOP Alliance based + * security interceptor (MethodSecurityInterceptor), since both work with Java Methods.

+ *

The secure object type is org.aspectj.lang.JoinPoint, which is passed from the relevant + * around() advice. The around() advice also passes an anonymous implementation of {@link + * AspectJCallback} which contains the call for AspectJ to continue processing: return proceed();.

+ *

Refer to {@link AbstractSecurityInterceptor} for details on the workflow.

* * @author Ben Alex * @version $Id$ */ public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private MethodDefinitionSource objectDefinitionSource; - //~ Methods ================================================================ - - public void setObjectDefinitionSource(MethodDefinitionSource newSource) { - this.objectDefinitionSource = newSource; - } + //~ Methods ======================================================================================================== public MethodDefinitionSource getObjectDefinitionSource() { return this.objectDefinitionSource; @@ -69,14 +51,11 @@ public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor { } /** - * This method should be used to enforce security on a - * JoinPoint. + * This method should be used to enforce security on a JoinPoint. * - * @param jp The AspectJ joint point being invoked which requires a - * security decision - * @param advisorProceed the advice-defined anonymous class that implements - * AspectJCallback containing a simple return - * proceed(); statement + * @param jp The AspectJ joint point being invoked which requires a security decision + * @param advisorProceed the advice-defined anonymous class that implements AspectJCallback containing + * a simple return proceed(); statement * * @return The returned value from the method invocation */ @@ -96,4 +75,8 @@ public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor { public ObjectDefinitionSource obtainObjectDefinitionSource() { return this.objectDefinitionSource; } + + public void setObjectDefinitionSource(MethodDefinitionSource newSource) { + this.objectDefinitionSource = newSource; + } } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSource.java b/core/src/main/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSource.java index 9233544d93..87e662eeaf 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSource.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,19 +27,17 @@ import org.apache.commons.logging.LogFactory; * @author Ben Alex * @version $Id$ */ -public abstract class AbstractFilterInvocationDefinitionSource - implements FilterInvocationDefinitionSource { - //~ Static fields/initializers ============================================= +public abstract class AbstractFilterInvocationDefinitionSource implements FilterInvocationDefinitionSource { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AbstractFilterInvocationDefinitionSource.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException { if ((object == null) || !this.supports(object.getClass())) { - throw new IllegalArgumentException( - "Object must be a FilterInvocation"); + throw new IllegalArgumentException("Object must be a FilterInvocation"); } String url = ((FilterInvocation) object).getRequestUrl(); @@ -48,27 +46,16 @@ public abstract class AbstractFilterInvocationDefinitionSource } /** - * Performs the actual lookup of the relevant - * ConfigAttributeDefinition for the specified - * FilterInvocation. - * - *

- * Provided so subclasses need only to provide one basic method to properly - * interface with the FilterInvocationDefinitionSource. - *

- * - *

- * Public visiblity so that tablibs or other view helper classes can access - * the ConfigAttributeDefinition applying to a given URI - * pattern without needing to construct a mock - * FilterInvocation and retrieving the attibutes via the - * {@link #getAttributes(Object)} method. - *

+ * Performs the actual lookup of the relevant ConfigAttributeDefinition for the specified + * FilterInvocation.

Provided so subclasses need only to provide one basic method to + * properly interface with the FilterInvocationDefinitionSource.

+ *

Public visiblity so that tablibs or other view helper classes can access the + * ConfigAttributeDefinition applying to a given URI pattern without needing to construct a mock + * FilterInvocation and retrieving the attibutes via the {@link #getAttributes(Object)} method.

* * @param url the URI to retrieve configuration attributes for * - * @return the ConfigAttributeDefinition that applies to the - * specified FilterInvocation + * @return the ConfigAttributeDefinition that applies to the specified FilterInvocation */ public abstract ConfigAttributeDefinition lookupAttributes(String url); diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java index 4334017a42..cdd5f4d804 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java @@ -25,47 +25,36 @@ import javax.servlet.http.HttpServletResponse; /** - * Holds objects associated with a HTTP filter. - * - *

- * Guarantees the request and response are instances of - * HttpServletRequest and HttpServletResponse, and - * that there are no null objects. - *

- * - *

- * Required so that security system classes can obtain access to the filter - * environment, as well as the request and response. - *

+ * Holds objects associated with a HTTP filter.

Guarantees the request and response are instances of + * HttpServletRequest and HttpServletResponse, and that there are no null + * objects.

+ *

Required so that security system classes can obtain access to the filter environment, as well as the request + * and response.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class FilterInvocation { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private FilterChain chain; private ServletRequest request; private ServletResponse response; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public FilterInvocation(ServletRequest request, ServletResponse response, - FilterChain chain) { + public FilterInvocation(ServletRequest request, ServletResponse response, FilterChain chain) { if ((request == null) || (response == null) || (chain == null)) { - throw new IllegalArgumentException( - "Cannot pass null values to constructor"); + throw new IllegalArgumentException("Cannot pass null values to constructor"); } if (!(request instanceof HttpServletRequest)) { - throw new IllegalArgumentException( - "Can only process HttpServletRequest"); + throw new IllegalArgumentException("Can only process HttpServletRequest"); } if (!(response instanceof HttpServletResponse)) { - throw new IllegalArgumentException( - "Can only process HttpServletResponse"); + throw new IllegalArgumentException("Can only process HttpServletResponse"); } this.request = request; @@ -73,19 +62,15 @@ public class FilterInvocation { this.chain = chain; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public FilterChain getChain() { return chain; } /** - * Indicates the URL that the user agent used for this request. - * - *

- * The returned URL does not reflect the port number determined from - * a {@link org.acegisecurity.util.PortResolver}. - *

+ * Indicates the URL that the user agent used for this request.

The returned URL does not reflect + * the port number determined from a {@link org.acegisecurity.util.PortResolver}.

* * @return the full URL of this request */ diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionMap.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionMap.java index 9d409360e8..092dcfef65 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionMap.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionMap.java @@ -26,12 +26,11 @@ import org.acegisecurity.ConfigAttributeDefinition; * @version $Id$ */ public interface FilterInvocationDefinitionMap { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void addSecureUrl(String expression, ConfigAttributeDefinition attr); public boolean isConvertUrlToLowercaseBeforeComparison(); - public void setConvertUrlToLowercaseBeforeComparison( - boolean convertUrlToLowercaseBeforeComparison); + public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison); } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSource.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSource.java index 9f10239619..f2697c2ece 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSource.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditor.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditor.java index abd8d612f4..81d25895b8 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditor.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditor.java @@ -30,36 +30,24 @@ import java.io.StringReader; /** - * Property editor to assist with the setup of a {@link - * FilterInvocationDefinitionSource}. - * - *

- * The class creates and populates a {@link - * RegExpBasedFilterInvocationDefinitionMap} or {@link - * PathBasedFilterInvocationDefinitionMap} (depending on the type of patterns - * presented). - *

- * - *

- * By default the class treats presented patterns as regular expressions. If - * the keyword PATTERN_TYPE_APACHE_ANT is present (case - * sensitive), patterns will be treated as Apache Ant paths rather than - * regular expressions. - *

+ * Property editor to assist with the setup of a {@link FilterInvocationDefinitionSource}.

The class creates and + * populates a {@link RegExpBasedFilterInvocationDefinitionMap} or {@link PathBasedFilterInvocationDefinitionMap} + * (depending on the type of patterns presented).

+ *

By default the class treats presented patterns as regular expressions. If the keyword + * PATTERN_TYPE_APACHE_ANT is present (case sensitive), patterns will be treated as Apache Ant paths + * rather than regular expressions.

* * @author Ben Alex * @version $Id$ */ -public class FilterInvocationDefinitionSourceEditor - extends PropertyEditorSupport { - //~ Static fields/initializers ============================================= +public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSupport { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(FilterInvocationDefinitionSourceEditor.class); - public static final String DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON = - "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON"; + public static final String DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON = "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON"; public static final String DIRECTIVE_PATTERN_TYPE_APACHE_ANT = "PATTERN_TYPE_APACHE_ANT"; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void setAsText(String s) throws IllegalArgumentException { FilterInvocationDefinitionMap source = new RegExpBasedFilterInvocationDefinitionMap(); @@ -72,17 +60,14 @@ public class FilterInvocationDefinitionSourceEditor source = new PathBasedFilterInvocationDefinitionMap(); if (logger.isDebugEnabled()) { - logger.debug(("Detected " - + DIRECTIVE_PATTERN_TYPE_APACHE_ANT + logger.debug(("Detected " + DIRECTIVE_PATTERN_TYPE_APACHE_ANT + " directive; using Apache Ant style path expressions")); } } - if (s.lastIndexOf( - DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) { + if (s.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) { if (logger.isDebugEnabled()) { - logger.debug("Detected " - + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON + logger.debug("Detected " + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON + " directive; Instructing mapper to convert URLs to lowercase before comparison"); } @@ -117,24 +102,19 @@ public class FilterInvocationDefinitionSourceEditor } // Attempt to detect malformed lines (as per SEC-204) - if (line.lastIndexOf( - DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) { + if (line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) { // Directive found; check for second directive or name=value - if ((line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) - || (line.lastIndexOf("=") != -1)) { - throw new IllegalArgumentException( - "Line appears to be malformed: " + line); + if ((line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) || (line.lastIndexOf("=") != -1)) { + throw new IllegalArgumentException("Line appears to be malformed: " + line); } } // Attempt to detect malformed lines (as per SEC-204) if (line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) { // Directive found; check for second directive or name=value - if ((line.lastIndexOf( - DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) + if ((line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) || (line.lastIndexOf("=") != -1)) { - throw new IllegalArgumentException( - "Line appears to be malformed: " + line); + throw new IllegalArgumentException("Line appears to be malformed: " + line); } } @@ -144,8 +124,7 @@ public class FilterInvocationDefinitionSourceEditor } if (line.lastIndexOf("==") != -1) { - throw new IllegalArgumentException( - "Only single equals should be used in line " + line); + throw new IllegalArgumentException("Only single equals should be used in line " + line); } // Tokenize the line into its name/value tokens @@ -154,8 +133,7 @@ public class FilterInvocationDefinitionSourceEditor String value = StringUtils.substringAfterLast(line, "="); if (StringUtils.isBlank(name) || StringUtils.isBlank(value)) { - throw new IllegalArgumentException( - "Failed to parse a valid name/value pair from " + line); + throw new IllegalArgumentException("Failed to parse a valid name/value pair from " + line); } // Attempt to detect malformed lines (as per SEC-204) @@ -167,11 +145,10 @@ public class FilterInvocationDefinitionSourceEditor String character = name.substring(i, i + 1); if (!character.toLowerCase().equals(character)) { - throw new IllegalArgumentException( - "You are using the " + throw new IllegalArgumentException("You are using the " + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON - + " with Ant Paths, yet you have specified an uppercase character in line: " - + line + " (character '" + character + "')"); + + " with Ant Paths, yet you have specified an uppercase character in line: " + line + + " (character '" + character + "')"); } } } @@ -180,8 +157,7 @@ public class FilterInvocationDefinitionSourceEditor ConfigAttributeEditor configAttribEd = new ConfigAttributeEditor(); configAttribEd.setAsText(value); - ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd - .getValue(); + ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd.getValue(); // Register the regular expression and its attribute source.addSecureUrl(name, attr); diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java index b88ad404c0..63e3fd79c6 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java @@ -30,32 +30,25 @@ import javax.servlet.ServletResponse; /** - * Performs security handling of HTTP resources via a filter implementation. - * - *

- * The ObjectDefinitionSource required by this security - * interceptor is of type {@link FilterInvocationDefinitionSource}. - *

- * - *

- * Refer to {@link AbstractSecurityInterceptor} for details on the workflow. - *

+ * Performs security handling of HTTP resources via a filter implementation.

The + * ObjectDefinitionSource required by this security interceptor is of type {@link + * FilterInvocationDefinitionSource}.

+ *

Refer to {@link AbstractSecurityInterceptor} for details on the workflow.

* * @author Ben Alex * @version $Id$ */ -public class FilterSecurityInterceptor extends AbstractSecurityInterceptor - implements Filter { - //~ Static fields/initializers ============================================= +public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { + //~ Static fields/initializers ===================================================================================== private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private FilterInvocationDefinitionSource objectDefinitionSource; private boolean observeOncePerRequest = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Not used (we rely on IoC container lifecycle services instead) @@ -63,8 +56,8 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor public void destroy() {} /** - * Method that is actually called by the filter chain. Simply delegates to - * the {@link #invoke(FilterInvocation)} method. + * Method that is actually called by the filter chain. Simply delegates to the {@link + * #invoke(FilterInvocation)} method. * * @param request the servlet request * @param response the servlet response @@ -73,8 +66,8 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor * @throws IOException if the filter chain fails * @throws ServletException if the filter chain fails */ - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } @@ -96,10 +89,8 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor */ public void init(FilterConfig arg0) throws ServletException {} - public void invoke(FilterInvocation fi) - throws IOException, ServletException { - if ((fi.getRequest() != null) - && (fi.getRequest().getAttribute(FILTER_APPLIED) != null) + public void invoke(FilterInvocation fi) throws IOException, ServletException { + if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null) && observeOncePerRequest) { // filter already applied to this request and user wants us to observce // once-per-request handling, so don't re-do security checking @@ -121,17 +112,14 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor } /** - * Indicates whether once-per-request handling will be observed. By default - * this is true, meaning the - * FilterSecurityInterceptor will only execute - * once-per-request. Sometimes users may wish it to execute more than once - * per request, such as when JSP forwards are being used and filter - * security is desired on each included fragment of the HTTP request. + * Indicates whether once-per-request handling will be observed. By default this is true, + * meaning the FilterSecurityInterceptor will only execute once-per-request. Sometimes users may wish + * it to execute more than once per request, such as when JSP forwards are being used and filter security is + * desired on each included fragment of the HTTP request. * - * @return true (the default) if once-per-request is honoured, - * otherwise false if - * FilterSecurityInterceptor will enforce - * authorizations for each and every fragment of the HTTP request. + * @return true (the default) if once-per-request is honoured, otherwise false if + * FilterSecurityInterceptor will enforce authorizations for each and every fragment of the + * HTTP request. */ public boolean isObserveOncePerRequest() { return observeOncePerRequest; @@ -141,8 +129,7 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor return this.objectDefinitionSource; } - public void setObjectDefinitionSource( - FilterInvocationDefinitionSource newSource) { + public void setObjectDefinitionSource(FilterInvocationDefinitionSource newSource) { this.objectDefinitionSource = newSource; } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/PathBasedFilterInvocationDefinitionMap.java b/core/src/main/java/org/acegisecurity/intercept/web/PathBasedFilterInvocationDefinitionMap.java index 0371a29b20..ef94993c3d 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/PathBasedFilterInvocationDefinitionMap.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/PathBasedFilterInvocationDefinitionMap.java @@ -31,44 +31,31 @@ import java.util.Vector; /** - * Maintains a List of ConfigAttributeDefinitions - * associated with different HTTP request URL Apache Ant path-based patterns. - * - *

- * Apache Ant path expressions are used to match a HTTP request URL against a - * ConfigAttributeDefinition. - *

- * - *

- * The order of registering the Ant paths using the {@link - * #addSecureUrl(String, ConfigAttributeDefinition)} is very important. The - * system will identify the first matching path for a given HTTP URL. - * It will not proceed to evaluate later paths if a match has already been - * found. Accordingly, the most specific paths should be registered first, - * with the most general paths registered last. - *

- * - *

- * If no registered paths match the HTTP URL, null is returned. - *

+ * Maintains a List of ConfigAttributeDefinitions associated with different HTTP request + * URL Apache Ant path-based patterns.

Apache Ant path expressions are used to match a HTTP request URL against a + * ConfigAttributeDefinition.

+ *

The order of registering the Ant paths using the {@link #addSecureUrl(String, ConfigAttributeDefinition)} is + * very important. The system will identify the first matching path for a given HTTP URL. It will not proceed + * to evaluate later paths if a match has already been found. Accordingly, the most specific paths should be + * registered first, with the most general paths registered last.

+ *

If no registered paths match the HTTP URL, null is returned.

* * @author Ben Alex * @version $Id$ */ -public class PathBasedFilterInvocationDefinitionMap - extends AbstractFilterInvocationDefinitionSource +public class PathBasedFilterInvocationDefinitionMap extends AbstractFilterInvocationDefinitionSource implements FilterInvocationDefinitionMap { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(PathBasedFilterInvocationDefinitionMap.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List requestMap = new Vector(); private PathMatcher pathMatcher = new AntPathMatcher(); private boolean convertUrlToLowercaseBeforeComparison = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void addSecureUrl(String antPath, ConfigAttributeDefinition attr) { requestMap.add(new EntryHolder(antPath, attr)); @@ -110,8 +97,7 @@ public class PathBasedFilterInvocationDefinitionMap url = url.toLowerCase(); if (logger.isDebugEnabled()) { - logger.debug("Converted URL to lowercase, from: '" + url - + "'; to: '" + url + "'"); + logger.debug("Converted URL to lowercase, from: '" + url + "'; to: '" + url + "'"); } } @@ -123,8 +109,8 @@ public class PathBasedFilterInvocationDefinitionMap boolean matched = pathMatcher.match(entryHolder.getAntPath(), url); if (logger.isDebugEnabled()) { - logger.debug("Candidate is: '" + url + "'; pattern is " - + entryHolder.getAntPath() + "; matched=" + matched); + logger.debug("Candidate is: '" + url + "'; pattern is " + entryHolder.getAntPath() + "; matched=" + + matched); } if (matched) { @@ -135,12 +121,11 @@ public class PathBasedFilterInvocationDefinitionMap return null; } - public void setConvertUrlToLowercaseBeforeComparison( - boolean convertUrlToLowercaseBeforeComparison) { + public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison) { this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison; } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== protected class EntryHolder { private ConfigAttributeDefinition configAttributeDefinition; diff --git a/core/src/main/java/org/acegisecurity/intercept/web/RegExpBasedFilterInvocationDefinitionMap.java b/core/src/main/java/org/acegisecurity/intercept/web/RegExpBasedFilterInvocationDefinitionMap.java index e44adfffd5..17ffe74918 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/RegExpBasedFilterInvocationDefinitionMap.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/RegExpBasedFilterInvocationDefinitionMap.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,42 +34,46 @@ import java.util.Vector; /** - * Maintains a List of ConfigAttributeDefinitions - * associated with different HTTP request URL regular expression patterns. - * - *

- * Regular expressions are used to match a HTTP request URL against a - * ConfigAttributeDefinition. - *

- * - *

- * The order of registering the regular expressions using the {@link - * #addSecureUrl(String, ConfigAttributeDefinition)} is very important. The - * system will identify the first matching regular expression for a - * given HTTP URL. It will not proceed to evaluate later regular expressions - * if a match has already been found. Accordingly, the most specific regular - * expressions should be registered first, with the most general regular - * expressions registered last. - *

- * - *

- * If no registered regular expressions match the HTTP URL, null - * is returned. - *

+ * Maintains a List of ConfigAttributeDefinitions associated with different HTTP request + * URL regular expression patterns.

Regular expressions are used to match a HTTP request URL against a + * ConfigAttributeDefinition.

+ *

The order of registering the regular expressions using the {@link #addSecureUrl(String, + * ConfigAttributeDefinition)} is very important. The system will identify the first matching regular + * expression for a given HTTP URL. It will not proceed to evaluate later regular expressions if a match has already + * been found. Accordingly, the most specific regular expressions should be registered first, with the most general + * regular expressions registered last.

+ *

If no registered regular expressions match the HTTP URL, null is returned.

*/ -public class RegExpBasedFilterInvocationDefinitionMap - extends AbstractFilterInvocationDefinitionSource +public class RegExpBasedFilterInvocationDefinitionMap extends AbstractFilterInvocationDefinitionSource implements FilterInvocationDefinitionMap { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RegExpBasedFilterInvocationDefinitionMap.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List requestMap = new Vector(); private boolean convertUrlToLowercaseBeforeComparison = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void addSecureUrl(String perl5RegExp, ConfigAttributeDefinition attr) { + Pattern compiledPattern; + Perl5Compiler compiler = new Perl5Compiler(); + + try { + compiledPattern = compiler.compile(perl5RegExp, Perl5Compiler.READ_ONLY_MASK); + } catch (MalformedPatternException mpe) { + throw new IllegalArgumentException("Malformed regular expression: " + perl5RegExp); + } + + requestMap.add(new EntryHolder(compiledPattern, attr)); + + if (logger.isDebugEnabled()) { + logger.debug("Added regular expression: " + compiledPattern.getPattern().toString() + "; attributes: " + + attr); + } + } public Iterator getConfigAttributeDefinitions() { Set set = new HashSet(); @@ -83,38 +87,12 @@ public class RegExpBasedFilterInvocationDefinitionMap return set.iterator(); } - public void setConvertUrlToLowercaseBeforeComparison( - boolean convertUrlToLowercaseBeforeComparison) { - this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison; - } - - public boolean isConvertUrlToLowercaseBeforeComparison() { - return convertUrlToLowercaseBeforeComparison; - } - public int getMapSize() { return this.requestMap.size(); } - public void addSecureUrl(String perl5RegExp, ConfigAttributeDefinition attr) { - Pattern compiledPattern; - Perl5Compiler compiler = new Perl5Compiler(); - - try { - compiledPattern = compiler.compile(perl5RegExp, - Perl5Compiler.READ_ONLY_MASK); - } catch (MalformedPatternException mpe) { - throw new IllegalArgumentException("Malformed regular expression: " - + perl5RegExp); - } - - requestMap.add(new EntryHolder(compiledPattern, attr)); - - if (logger.isDebugEnabled()) { - logger.debug("Added regular expression: " - + compiledPattern.getPattern().toString() + "; attributes: " - + attr); - } + public boolean isConvertUrlToLowercaseBeforeComparison() { + return convertUrlToLowercaseBeforeComparison; } public ConfigAttributeDefinition lookupAttributes(String url) { @@ -126,20 +104,17 @@ public class RegExpBasedFilterInvocationDefinitionMap url = url.toLowerCase(); if (logger.isDebugEnabled()) { - logger.debug("Converted URL to lowercase, from: '" + url - + "'; to: '" + url + "'"); + logger.debug("Converted URL to lowercase, from: '" + url + "'; to: '" + url + "'"); } } while (iter.hasNext()) { EntryHolder entryHolder = (EntryHolder) iter.next(); - boolean matched = matcher.matches(url, - entryHolder.getCompiledPattern()); + boolean matched = matcher.matches(url, entryHolder.getCompiledPattern()); if (logger.isDebugEnabled()) { - logger.debug("Candidate is: '" + url + "'; pattern is " - + entryHolder.getCompiledPattern().getPattern() + logger.debug("Candidate is: '" + url + "'; pattern is " + entryHolder.getCompiledPattern().getPattern() + "; matched=" + matched); } @@ -151,14 +126,17 @@ public class RegExpBasedFilterInvocationDefinitionMap return null; } - //~ Inner Classes ========================================================== + public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison) { + this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison; + } + + //~ Inner Classes ================================================================================================== protected class EntryHolder { private ConfigAttributeDefinition configAttributeDefinition; private Pattern compiledPattern; - public EntryHolder(Pattern compiledPattern, - ConfigAttributeDefinition attr) { + public EntryHolder(Pattern compiledPattern, ConfigAttributeDefinition attr) { this.compiledPattern = compiledPattern; this.configAttributeDefinition = attr; } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluator.java b/core/src/main/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluator.java index f5fea4f24d..ccf6160119 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluator.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluator.java @@ -36,15 +36,15 @@ import org.springframework.util.Assert; * @version $Id$ */ public class WebInvocationPrivilegeEvaluator implements InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(WebInvocationPrivilegeEvaluator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AbstractSecurityInterceptor securityInterceptor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(securityInterceptor, "SecurityInterceptor required"); @@ -53,8 +53,7 @@ public class WebInvocationPrivilegeEvaluator implements InitializingBean { public boolean isAllowed(FilterInvocation fi, Authentication authentication) { Assert.notNull(fi, "FilterInvocation required"); - ConfigAttributeDefinition attrs = securityInterceptor.obtainObjectDefinitionSource() - .getAttributes(fi); + ConfigAttributeDefinition attrs = securityInterceptor.obtainObjectDefinitionSource().getAttributes(fi); if (attrs == null) { if (securityInterceptor.isRejectPublicInvocations()) { @@ -64,19 +63,16 @@ public class WebInvocationPrivilegeEvaluator implements InitializingBean { return true; } - if ((authentication == null) - || (authentication.getAuthorities() == null) + if ((authentication == null) || (authentication.getAuthorities() == null) || (authentication.getAuthorities().length == 0)) { return false; } try { - securityInterceptor.getAccessDecisionManager() - .decide(authentication, fi, attrs); + securityInterceptor.getAccessDecisionManager().decide(authentication, fi, attrs); } catch (AccessDeniedException unauthorized) { if (logger.isDebugEnabled()) { - logger.debug(fi.toString() + " denied for " - + authentication.toString(), unauthorized); + logger.debug(fi.toString() + " denied for " + authentication.toString(), unauthorized); } return false; @@ -85,12 +81,9 @@ public class WebInvocationPrivilegeEvaluator implements InitializingBean { return true; } - public void setSecurityInterceptor( - AbstractSecurityInterceptor securityInterceptor) { - Assert.notNull(securityInterceptor, - "AbstractSecurityInterceptor cannot be null"); - Assert.isTrue(FilterInvocation.class.equals( - securityInterceptor.getSecureObjectClass()), + public void setSecurityInterceptor(AbstractSecurityInterceptor securityInterceptor) { + Assert.notNull(securityInterceptor, "AbstractSecurityInterceptor cannot be null"); + Assert.isTrue(FilterInvocation.class.equals(securityInterceptor.getSecureObjectClass()), "AbstractSecurityInterceptor does not support FilterInvocations"); Assert.notNull(securityInterceptor.getAccessDecisionManager(), "AbstractSecurityInterceptor must provide a non-null AccessDecisionManager"); diff --git a/core/src/main/java/org/acegisecurity/ldap/DefaultInitialDirContextFactory.java b/core/src/main/java/org/acegisecurity/ldap/DefaultInitialDirContextFactory.java index 945a2a2b98..34401d81fe 100644 --- a/core/src/main/java/org/acegisecurity/ldap/DefaultInitialDirContextFactory.java +++ b/core/src/main/java/org/acegisecurity/ldap/DefaultInitialDirContextFactory.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,114 +17,94 @@ package org.acegisecurity.ldap; import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.BadCredentialsException; -import org.springframework.context.MessageSourceAware; -import org.springframework.context.MessageSource; -import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.util.Assert; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; -import javax.naming.Context; -import javax.naming.CommunicationException; -import javax.naming.NamingException; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.support.MessageSourceAccessor; + +import org.springframework.util.Assert; + +import java.util.Hashtable; import java.util.Map; import java.util.StringTokenizer; -import java.util.Hashtable; + +import javax.naming.CommunicationException; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + /** - * Encapsulates the information for connecting to an LDAP server and provides an - * access point for obtaining DirContext references. - *

- * The directory location is configured using by setting the constructor argument - * providerUrl. This should be in the form - * ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org. The Sun JNDI - * provider also supports lists of space-separated URLs, each of which will be tried - * in turn until a connection is obtained. - *

- *

- * To obtain an initial context, the client calls the newInitialDirContext - * method. There are two signatures - one with no arguments and one which allows - * binding with a specific username and password. - *

- *

- * The no-args version will bind anonymously unless a manager login has been configured - * using the properties managerDn and managerPassword, in which case - * it will bind as the manager user. - *

- *

- * Connection pooling is enabled by default for anonymous or manager connections, but - * not when binding as a specific user. - *

- * - * @see The Java - * tutorial's guide to LDAP connection pooling + * Encapsulates the information for connecting to an LDAP server and provides an access point for obtaining + * DirContext references.

The directory location is configured using by setting the constructor argument + * providerUrl. This should be in the form ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org. + * The Sun JNDI provider also supports lists of space-separated URLs, each of which will be tried in turn until a + * connection is obtained.

+ *

To obtain an initial context, the client calls the newInitialDirContext method. There are two + * signatures - one with no arguments and one which allows binding with a specific username and password.

+ *

The no-args version will bind anonymously unless a manager login has been configured using the properties + * managerDn and managerPassword, in which case it will bind as the manager user.

+ *

Connection pooling is enabled by default for anonymous or manager connections, but not when binding as a + * specific user.

* * @author Robert Sanders * @author Luke Taylor * @version $Id$ * + * @see The Java tutorial's guide to LDAP + * connection pooling */ -public class DefaultInitialDirContextFactory implements InitialDirContextFactory, - MessageSourceAware { - - //~ Static fields/initializers ============================================= +public class DefaultInitialDirContextFactory implements InitialDirContextFactory, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(DefaultInitialDirContextFactory.class); - private static final String CONNECTION_POOL_KEY = "com.sun.jndi.ldap.connect.pool"; - private static final String AUTH_TYPE_NONE = "none"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ + /** Allows extra environment variables to be added at config time. */ + private Map extraEnvVars = null; protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); - /** - * The LDAP url of the server (and root context) to connect to. - */ - private String providerUrl; - - /** - * The root DN. This is worked out from the url. - * It is used by client classes when forming a full DN for - * bind authentication (for example). - */ - private String rootDn = null; - - /** - * If your LDAP server does not allow anonymous searches then - * you will need to provide a "manager" user's DN to log in with. - */ - private String managerDn = null; - - /** - * The manager user's password. - */ - private String managerPassword = "manager_password_not_set"; - /** Type of authentication within LDAP; default is simple. */ private String authenticationType = "simple"; /** - * The INITIAL_CONTEXT_FACTORY used to create the JNDI Factory. - * Default is "com.sun.jndi.ldap.LdapCtxFactory"; you should not - * need to set this unless you have unusual needs. + * The INITIAL_CONTEXT_FACTORY used to create the JNDI Factory. Default is + * "com.sun.jndi.ldap.LdapCtxFactory"; you should not need to set this unless you have unusual needs. */ private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory"; - /** Allows extra environment variables to be added at config time. */ - private Map extraEnvVars = null; + /** + * If your LDAP server does not allow anonymous searches then you will need to provide a "manager" user's + * DN to log in with. + */ + private String managerDn = null; + + /** The manager user's password. */ + private String managerPassword = "manager_password_not_set"; + + /** The LDAP url of the server (and root context) to connect to. */ + private String providerUrl; /** - * Use the LDAP Connection pool; if true, then the - * LDAP environment property "com.sun.jndi.ldap.connect.pool" is added - * to any other JNDI properties. + * The root DN. This is worked out from the url. It is used by client classes when forming a full DN for + * bind authentication (for example). + */ + private String rootDn = null; + + /** + * Use the LDAP Connection pool; if true, then the LDAP environment property + * "com.sun.jndi.ldap.connect.pool" is added to any other JNDI properties. */ private boolean useConnectionPool = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public DefaultInitialDirContextFactory(String providerUrl) { this.providerUrl = providerUrl; @@ -134,13 +114,13 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory StringTokenizer st = new StringTokenizer(providerUrl); // Work out rootDn from the first URL and check that the other URLs (if any) match - while(st.hasMoreTokens()) { + while (st.hasMoreTokens()) { String url = st.nextToken(); String urlRootDn = LdapUtils.parseRootDnFromUrl(url); - logger.info(" URL '" + url +"', root DN is '" + urlRootDn + "'"); + logger.info(" URL '" + url + "', root DN is '" + urlRootDn + "'"); - if(rootDn == null) { + if (rootDn == null) { rootDn = urlRootDn; } else if (!rootDn.equals(urlRootDn)) { throw new IllegalArgumentException("Root DNs must be the same when using multiple URLs"); @@ -151,17 +131,75 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory //Assert.isTrue(uri.getScheme().equals("ldap"), "Ldap URL must start with 'ldap://'"); } + //~ Methods ======================================================================================================== - //~ Methods ================================================================ + private InitialDirContext connect(Hashtable env) { + if (logger.isDebugEnabled()) { + Hashtable envClone = (Hashtable) env.clone(); + + if (envClone.containsKey(Context.SECURITY_CREDENTIALS)) { + envClone.put(Context.SECURITY_CREDENTIALS, "******"); + } + + logger.debug("Creating InitialDirContext with environment " + envClone); + } + + try { + return new InitialDirContext(env); + } catch (CommunicationException ce) { + throw new LdapDataAccessException(messages.getMessage( + "DefaultIntitalDirContextFactory.communicationFailure", "Unable to connect to LDAP server"), ce); + } catch (javax.naming.AuthenticationException ae) { + throw new BadCredentialsException(messages.getMessage("DefaultIntitalDirContextFactory.badCredentials", + "Bad credentials"), ae); + } catch (NamingException nx) { + throw new LdapDataAccessException(messages.getMessage( + "DefaultIntitalDirContextFactory.unexpectedException", + "Failed to obtain InitialDirContext due to unexpected exception"), nx); + } + } /** - * Connects anonymously unless a manager user has been specified, in which case - * it will bind as the manager. + * DOCUMENT ME! + * + * @return the Hashtable describing the base DirContext that will be created, minus the username/password if any. + */ + protected Hashtable getEnvironment() { + Hashtable env = new Hashtable(); + + env.put(Context.SECURITY_AUTHENTICATION, authenticationType); + env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); + env.put(Context.PROVIDER_URL, providerUrl); + + if (useConnectionPool) { + env.put(CONNECTION_POOL_KEY, "true"); + } + + if ((extraEnvVars != null) && (extraEnvVars.size() > 0)) { + env.putAll(extraEnvVars); + } + + return env; + } + + /** + * Returns the root DN of the configured provider URL. For example, if the URL is + * ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org the value will be + * dc=acegisecurity,dc=org. + * + * @return the root DN calculated from the path of the LDAP url. + */ + public String getRootDn() { + return rootDn; + } + + /** + * Connects anonymously unless a manager user has been specified, in which case it will bind as the + * manager. * * @return the resulting context object. */ public DirContext newInitialDirContext() { - if (managerDn != null) { return newInitialDirContext(managerDn, managerPassword); } @@ -186,80 +224,29 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory return connect(env); } - /** - * @return the Hashtable describing the base DirContext that will be created, - * minus the username/password if any. - */ - protected Hashtable getEnvironment() { - Hashtable env = new Hashtable(); - - env.put(Context.SECURITY_AUTHENTICATION, authenticationType); - env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); - env.put(Context.PROVIDER_URL, providerUrl); - - if (useConnectionPool) { - env.put(CONNECTION_POOL_KEY, "true"); - } - - if ((extraEnvVars != null) && (extraEnvVars.size() > 0)) { - env.putAll(extraEnvVars); - } - - return env; - } - - private InitialDirContext connect(Hashtable env) { - - if (logger.isDebugEnabled()) { - Hashtable envClone = (Hashtable)env.clone(); - - if (envClone.containsKey(Context.SECURITY_CREDENTIALS)) { - envClone.put(Context.SECURITY_CREDENTIALS, "******"); - } - - logger.debug("Creating InitialDirContext with environment " + envClone); - } - - try { - return new InitialDirContext(env); - - } catch(CommunicationException ce) { - throw new LdapDataAccessException(messages.getMessage( - "DefaultIntitalDirContextFactory.communicationFailure", - "Unable to connect to LDAP server"), ce); - } catch(javax.naming.AuthenticationException ae) { - throw new BadCredentialsException(messages.getMessage( - "DefaultIntitalDirContextFactory.badCredentials", - "Bad credentials"), ae); - } catch (NamingException nx) { - throw new LdapDataAccessException(messages.getMessage( - "DefaultIntitalDirContextFactory.unexpectedException", - "Failed to obtain InitialDirContext due to unexpected exception"), nx); - } - } - - /** - * Returns the root DN of the configured provider URL. For example, - * if the URL is ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org - * the value will be dc=acegisecurity,dc=org. - * - * @return the root DN calculated from the path of the LDAP url. - */ - public String getRootDn() { - return rootDn; - } - public void setAuthenticationType(String authenticationType) { Assert.hasLength(authenticationType, "LDAP Authentication type must not be empty or null"); this.authenticationType = authenticationType; } + /** + * DOCUMENT ME! + * + * @param extraEnvVars extra environment variables to be added at config time. + */ + public void setExtraEnvVars(Map extraEnvVars) { + Assert.notNull(extraEnvVars, "Extra environment map cannot be null."); + this.extraEnvVars = extraEnvVars; + } + public void setInitialContextFactory(String initialContextFactory) { Assert.hasLength(initialContextFactory, "Initial context factory name cannot be empty or null"); this.initialContextFactory = initialContextFactory; } /** + * DOCUMENT ME! + * * @param managerDn The name of the "manager" user for default authentication. */ public void setManagerDn(String managerDn) { @@ -268,6 +255,8 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory } /** + * DOCUMENT ME! + * * @param managerPassword The "manager" user's password. */ public void setManagerPassword(String managerPassword) { @@ -275,22 +264,13 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory this.managerPassword = managerPassword; } - /** - * @param extraEnvVars extra environment variables to be added at config time. - */ - public void setExtraEnvVars(Map extraEnvVars) { - Assert.notNull(extraEnvVars, "Extra environment map cannot be null."); - this.extraEnvVars = extraEnvVars; - } - public void setMessageSource(MessageSource messageSource) { this.messages = new MessageSourceAccessor(messageSource); } /** - * Connection pooling is enabled by default for anonymous or "manager" - * connections when using the default Sun provider. To disable all - * connection pooling, set this property to false. + * Connection pooling is enabled by default for anonymous or "manager" connections when using the default + * Sun provider. To disable all connection pooling, set this property to false. * * @param useConnectionPool whether to pool connections for non-specific users. */ diff --git a/core/src/main/java/org/acegisecurity/ldap/InitialDirContextFactory.java b/core/src/main/java/org/acegisecurity/ldap/InitialDirContextFactory.java index cefb882720..9556203b68 100644 --- a/core/src/main/java/org/acegisecurity/ldap/InitialDirContextFactory.java +++ b/core/src/main/java/org/acegisecurity/ldap/InitialDirContextFactory.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.ldap; import javax.naming.directory.DirContext; + /** * Access point for obtaining LDAP contexts. * @@ -26,19 +27,30 @@ import javax.naming.directory.DirContext; * @version $Id$ */ public interface InitialDirContextFactory { + //~ Methods ======================================================================================================== + + /** + * + DOCUMENT ME! + * + * @return The DN of the contexts returned by this factory. + */ + String getRootDn(); /** * Provides an initial context without specific user information. + * + * @return DOCUMENT ME! */ DirContext newInitialDirContext(); /** * Provides an initial context by binding as a specific user. + * + * @param userDn DOCUMENT ME! + * @param password DOCUMENT ME! + * + * @return DOCUMENT ME! */ DirContext newInitialDirContext(String userDn, String password); - - /** - * @return The DN of the contexts returned by this factory. - */ - String getRootDn(); } diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapCallback.java b/core/src/main/java/org/acegisecurity/ldap/LdapCallback.java index 37768c06f2..868c3ae5ae 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapCallback.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapCallback.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,16 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.ldap; import javax.naming.NamingException; import javax.naming.directory.DirContext; + /** * Callback object for use with LdapTemplate. * * @author Ben Alex */ public interface LdapCallback { - public Object doInDirContext(DirContext dirContext) throws NamingException; + //~ Methods ======================================================================================================== + + public Object doInDirContext(DirContext dirContext) + throws NamingException; } diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapDataAccessException.java b/core/src/main/java/org/acegisecurity/ldap/LdapDataAccessException.java index 132020c9d0..21327550b7 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapDataAccessException.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapDataAccessException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +17,16 @@ package org.acegisecurity.ldap; import org.springframework.dao.DataAccessException; + /** - * Used to wrap unexpected NamingExceptions while accessing the LDAP server - * or for other LDAP-related data problems such as data we can't handle. + * Used to wrap unexpected NamingExceptions while accessing the LDAP server or for other LDAP-related data problems + * such as data we can't handle. * * @author Luke Taylor * @version $Id$ */ public class LdapDataAccessException extends DataAccessException { + //~ Constructors =================================================================================================== public LdapDataAccessException(String msg) { super(msg); diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapEntryMapper.java b/core/src/main/java/org/acegisecurity/ldap/LdapEntryMapper.java index cd658ae905..5a906d4fcc 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapEntryMapper.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapEntryMapper.java @@ -1,31 +1,34 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.acegisecurity.ldap; - -import javax.naming.directory.Attributes; -import javax.naming.NamingException; - +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.ldap; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; + + /** * A mapper for use with {@link LdapTemplate}. Creates a customized object from * a set of attributes retrieved from a directory entry. * * @author Luke Taylor * @version $Id$ - */ -public interface LdapEntryMapper { - - public Object mapAttributes(String dn, Attributes attributes) throws NamingException; -} + */ +public interface LdapEntryMapper { + //~ Methods ======================================================================================================== + + public Object mapAttributes(String dn, Attributes attributes) + throws NamingException; +} diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapTemplate.java b/core/src/main/java/org/acegisecurity/ldap/LdapTemplate.java index 6a4385fbab..3d052a8a96 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapTemplate.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapTemplate.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,45 +15,49 @@ package org.acegisecurity.ldap; -import javax.naming.NamingException; -import javax.naming.NamingEnumeration; -import javax.naming.NameNotFoundException; -import javax.naming.directory.DirContext; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; -import javax.naming.directory.Attributes; -import javax.naming.directory.Attribute; - import org.springframework.dao.DataAccessException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import java.util.Set; import java.util.HashSet; +import java.util.Set; + +import javax.naming.NameNotFoundException; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; + /** - * LDAP equivalent of the Spring JdbcTemplate class. - *

- * This is mainly intended to simplify Ldap access within Acegi Security's - * LDAP-related services. - *

+ * LDAP equivalent of the Spring JdbcTemplate class.

This is mainly intended to simplify Ldap access within Acegi + * Security's LDAP-related services.

* * @author Ben Alex * @author Luke Taylor - * */ public class LdapTemplate { + //~ Static fields/initializers ===================================================================================== + public static final String[] NO_ATTRS = new String[0]; + //~ Instance fields ================================================================================================ + private InitialDirContextFactory dirContextFactory; - private String principalDn = null; - private String password = null; + private NamingExceptionTranslator exceptionTranslator = new LdapExceptionTranslator(); + /** Default search controls */ private SearchControls searchControls = new SearchControls(); + private String password = null; + private String principalDn = null; - private NamingExceptionTranslator exceptionTranslator = new LdapExceptionTranslator(); + //~ Constructors =================================================================================================== public LdapTemplate(InitialDirContextFactory dirContextFactory) { Assert.notNull(dirContextFactory, "An InitialDirContextFactory is required"); @@ -62,7 +66,7 @@ public class LdapTemplate { searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); } - /** +/** * * @param dirContextFactory the source of DirContexts * @param userDn the user name to authenticate as when obtaining new contexts @@ -78,25 +82,48 @@ public class LdapTemplate { this.password = password; } + //~ Methods ======================================================================================================== + /** - * Sets the search controls which will be used for search operations by the template. + * Performs an LDAP compare operation of the value of an attribute for a particular directory entry. * - * @param searchControls the SearchControls instance which will be cached in the template. + * @param dn the entry who's attribute is to be used + * @param attributeName the attribute who's value we want to compare + * @param value the value to be checked against the directory value + * + * @return true if the supplied value matches that in the directory */ - public void setSearchControls(SearchControls searchControls) { - this.searchControls = searchControls; + public boolean compare(final String dn, final String attributeName, final Object value) { + final String comparisonFilter = "(" + attributeName + "={0})"; + + class LdapCompareCallback implements LdapCallback { + public Object doInDirContext(DirContext ctx) + throws NamingException { + SearchControls ctls = new SearchControls(); + ctls.setReturningAttributes(NO_ATTRS); + ctls.setSearchScope(SearchControls.OBJECT_SCOPE); + + String relativeName = LdapUtils.getRelativeName(dn, ctx); + + NamingEnumeration results = ctx.search(relativeName, comparisonFilter, new Object[] {value}, ctls); + + return Boolean.valueOf(results.hasMore()); + } + } + + Boolean matches = (Boolean) execute(new LdapCompareCallback()); + + return matches.booleanValue(); } public Object execute(LdapCallback callback) throws DataAccessException { DirContext ctx = null; try { - ctx = (principalDn == null) ? - dirContextFactory.newInitialDirContext() : - dirContextFactory.newInitialDirContext(principalDn, password); + ctx = (principalDn == null) ? dirContextFactory.newInitialDirContext() + : dirContextFactory.newInitialDirContext(principalDn, password); return callback.doInDirContext(ctx); - } catch (NamingException exception) { throw exceptionTranslator.translate("LdapCallback", exception); } finally { @@ -104,57 +131,59 @@ public class LdapTemplate { } } - /** - * Performs an LDAP compare operation of the value of an attribute for a - * particular directory entry. - * - * @param dn the entry who's attribute is to be used - * @param attributeName the attribute who's value we want to compare - * @param value the value to be checked against the directory value - * @return true if the supplied value matches that in the directory - */ - public boolean compare(final String dn, final String attributeName, final Object value) { - final String comparisonFilter = "(" + attributeName + "={0})"; + public boolean nameExists(final String dn) { + Boolean exists = (Boolean) execute(new LdapCallback() { + public Object doInDirContext(DirContext ctx) + throws NamingException { + try { + ctx.lookup(LdapUtils.getRelativeName(dn, ctx)); + } catch (NameNotFoundException nnfe) { + return Boolean.FALSE; + } - class LdapCompareCallback implements LdapCallback { + return Boolean.TRUE; + } + }); - public Object doInDirContext(DirContext ctx) throws NamingException { - SearchControls ctls = new SearchControls(); - ctls.setReturningAttributes(NO_ATTRS); - ctls.setSearchScope(SearchControls.OBJECT_SCOPE); - - String relativeName = LdapUtils.getRelativeName(dn, ctx); - - NamingEnumeration results = - ctx.search(relativeName, comparisonFilter, new Object[]{value}, ctls); - - return Boolean.valueOf(results.hasMore()); - } - } - - - Boolean matches = (Boolean)execute(new LdapCompareCallback()); - - return matches.booleanValue(); + return exists.booleanValue(); } /** - * Performs a search using the supplied filter and returns the union of the values of the named - * attribute found in all entries matched by the search. Note that one directory entry may have several - * values for the attribute. Intended for role searches and similar scenarios. + * Composes an object from the attributes of the given DN. + * + * @param dn the directory entry which will be read + * @param mapper maps the attributes to the required object + * @param attributesToRetrieve the named attributes which will be retrieved from the directory entry. + * + * @return the object created by the mapper + */ + public Object retrieveEntry(final String dn, final LdapEntryMapper mapper, final String[] attributesToRetrieve) { + return execute(new LdapCallback() { + public Object doInDirContext(DirContext ctx) + throws NamingException { + return mapper.mapAttributes(dn, + ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve)); + } + }); + } + + /** + * Performs a search using the supplied filter and returns the union of the values of the named attribute + * found in all entries matched by the search. Note that one directory entry may have several values for the + * attribute. Intended for role searches and similar scenarios. * * @param base the DN to search in * @param filter search filter to use * @param params the parameters to substitute in the search filter * @param attributeName the attribute who's values are to be retrieved. + * * @return the set of String values for the attribute as a union of the values found in all the matching entries. */ - public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params, final String attributeName) { - - + public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params, + final String attributeName) { class SingleAttributeSearchCallback implements LdapCallback { - - public Object doInDirContext(DirContext ctx) throws NamingException { + public Object doInDirContext(DirContext ctx) + throws NamingException { Set unionOfValues = new HashSet(); // We're only interested in a single attribute for this method, so we make a copy of @@ -166,8 +195,7 @@ public class LdapTemplate { ctls.setDerefLinkFlag(searchControls.getDerefLinkFlag()); ctls.setReturningAttributes(new String[] {attributeName}); - NamingEnumeration matchingEntries = - ctx.search(base, filter, params, ctls); + NamingEnumeration matchingEntries = ctx.search(base, filter, params, ctls); while (matchingEntries.hasMore()) { SearchResult result = (SearchResult) matchingEntries.next(); @@ -176,16 +204,15 @@ public class LdapTemplate { // There should only be one attribute in each matching entry. NamingEnumeration returnedAttributes = attrs.getAll(); - while(returnedAttributes.hasMore()) { + while (returnedAttributes.hasMore()) { Attribute returnedAttribute = (Attribute) returnedAttributes.next(); NamingEnumeration attributeValues = returnedAttribute.getAll(); - while(attributeValues.hasMore()) { + while (attributeValues.hasMore()) { Object value = attributeValues.next(); unionOfValues.add(value.toString()); } - } } @@ -193,103 +220,74 @@ public class LdapTemplate { } } - return (Set)execute(new SingleAttributeSearchCallback()); - } - - public boolean nameExists(final String dn) { - - Boolean exists = (Boolean) execute( new LdapCallback() { - - public Object doInDirContext(DirContext ctx) throws NamingException { - try { - ctx.lookup( LdapUtils.getRelativeName(dn, ctx) ); - } catch(NameNotFoundException nnfe) { - return Boolean.FALSE; - } - - return Boolean.TRUE; - } - } - ); - - return exists.booleanValue(); + return (Set) execute(new SingleAttributeSearchCallback()); } /** - * Composes an object from the attributes of the given DN. - * - * @param dn the directory entry which will be read - * @param mapper maps the attributes to the required object - * @param attributesToRetrieve the named attributes which will be retrieved from the directory entry. - * @return the object created by the mapper - */ - public Object retrieveEntry(final String dn, final LdapEntryMapper mapper, final String[] attributesToRetrieve) { - return execute ( new LdapCallback() { - - public Object doInDirContext(DirContext ctx) throws NamingException { - return mapper.mapAttributes(dn, ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve) ); - - } - } ); - } - - /** - * Performs a search, with the requirement that the search shall return a single directory entry, and - * uses the supplied mapper to create the object from that entry. + * Performs a search, with the requirement that the search shall return a single directory entry, and uses + * the supplied mapper to create the object from that entry. * * @param base * @param filter * @param params * @param mapper + * * @return the object created by the mapper from the matching entry + * * @throws EmptyResultDataAccessException if no results are found. * @throws IncorrectResultSizeDataAccessException if the search returns more than one result. */ - public Object searchForSingleEntry(final String base, final String filter, final Object[] params, final LdapEntryMapper mapper) { - return execute ( new LdapCallback() { + public Object searchForSingleEntry(final String base, final String filter, final Object[] params, + final LdapEntryMapper mapper) { + return execute(new LdapCallback() { + public Object doInDirContext(DirContext ctx) + throws NamingException { + NamingEnumeration results = ctx.search(base, filter, params, searchControls); - public Object doInDirContext(DirContext ctx) throws NamingException { - NamingEnumeration results = ctx.search(base, filter, params, searchControls); + if (!results.hasMore()) { + throw new EmptyResultDataAccessException(1); + } - if (!results.hasMore()) { - throw new EmptyResultDataAccessException(1); + SearchResult searchResult = (SearchResult) results.next(); + + if (results.hasMore()) { + throw new IncorrectResultSizeDataAccessException(1); + } + + // Work out the DN of the matched entry + StringBuffer dn = new StringBuffer(searchResult.getName()); + + if (base.length() > 0) { + dn.append(","); + dn.append(base); + } + + String nameInNamespace = ctx.getNameInNamespace(); + + if (StringUtils.hasLength(nameInNamespace)) { + dn.append(","); + dn.append(nameInNamespace); + } + + return mapper.mapAttributes(dn.toString(), searchResult.getAttributes()); } - - SearchResult searchResult = (SearchResult)results.next(); - - if (results.hasMore()) { - throw new IncorrectResultSizeDataAccessException(1); - } - - // Work out the DN of the matched entry - StringBuffer dn = new StringBuffer(searchResult.getName()); - - if (base.length() > 0) { - dn.append(","); - dn.append(base); - } - - String nameInNamespace = ctx.getNameInNamespace(); - - if(StringUtils.hasLength(nameInNamespace)) { - dn.append(","); - dn.append(nameInNamespace); - } - - return mapper.mapAttributes(dn.toString(), searchResult.getAttributes()); - - } - - } - ); + }); } + /** + * Sets the search controls which will be used for search operations by the template. + * + * @param searchControls the SearchControls instance which will be cached in the template. + */ + public void setSearchControls(SearchControls searchControls) { + this.searchControls = searchControls; + } + + //~ Inner Classes ================================================================================================== private static class LdapExceptionTranslator implements NamingExceptionTranslator { - public DataAccessException translate(String task, NamingException e) { return new LdapDataAccessException(task + ";" + e.getMessage(), e); } } - } diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java b/core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java index c14b5ae508..c6fae2c27a 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.ldap; import org.acegisecurity.userdetails.ldap.LdapUserDetails; + /** * Obtains a user's information from the LDAP directory given a login name. *

@@ -29,14 +30,14 @@ import org.acegisecurity.userdetails.ldap.LdapUserDetails; * @version $Id$ */ public interface LdapUserSearch { + //~ Methods ======================================================================================================== /** - * Locates a single user in the directory and returns the LDAP information - * for that user. + * Locates a single user in the directory and returns the LDAP information for that user. * * @param username the login name supplied to the authentication service. + * * @return an LdapUserDetailsImpl object containing the user's full DN and requested attributes. */ LdapUserDetails searchForUser(String username); - } diff --git a/core/src/main/java/org/acegisecurity/ldap/LdapUtils.java b/core/src/main/java/org/acegisecurity/ldap/LdapUtils.java index 39c0af2ea8..39641477d3 100644 --- a/core/src/main/java/org/acegisecurity/ldap/LdapUtils.java +++ b/core/src/main/java/org/acegisecurity/ldap/LdapUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,14 @@ package org.acegisecurity.ldap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; +import java.io.UnsupportedEncodingException; + import javax.naming.Context; import javax.naming.NamingException; -import java.io.UnsupportedEncodingException; + /** * LDAP Utility methods. @@ -30,11 +33,11 @@ import java.io.UnsupportedEncodingException; * @version $Id$ */ public class LdapUtils { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(LdapUtils.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void closeContext(Context ctx) { try { @@ -46,28 +49,20 @@ public class LdapUtils { } } - public static byte[] getUtf8Bytes(String s) { - try { - return s.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - // Should be impossible since UTF-8 is required by all implementations - throw new IllegalStateException("Failed to convert string to UTF-8 bytes. Shouldn't be possible"); - } - } - /** - * Obtains the part of a DN relative to a supplied base context. - *

- * If the DN is "cn=bob,ou=people,dc=acegisecurity,dc=org" and the base context - * name is "ou=people,dc=acegisecurity,dc=org" it would return "cn=bob". - *

+ * Obtains the part of a DN relative to a supplied base context.

If the DN is + * "cn=bob,ou=people,dc=acegisecurity,dc=org" and the base context name is "ou=people,dc=acegisecurity,dc=org" it + * would return "cn=bob".

* * @param fullDn the DN * @param baseCtx the context to work out the name relative to. + * * @return the + * * @throws NamingException any exceptions thrown by the context are propagated. */ - public static String getRelativeName(String fullDn, Context baseCtx) throws NamingException { + public static String getRelativeName(String fullDn, Context baseCtx) + throws NamingException { String baseDn = baseCtx.getNameInNamespace(); if (baseDn.length() == 0) { @@ -86,14 +81,21 @@ public class LdapUtils { return fullDn.substring(0, index - 1); } + public static byte[] getUtf8Bytes(String s) { + try { + return s.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + // Should be impossible since UTF-8 is required by all implementations + throw new IllegalStateException("Failed to convert string to UTF-8 bytes. Shouldn't be possible"); + } + } + /** - * Works out the root DN for an LDAP URL. - *

- * For example, the URL ldap://monkeymachine:11389/dc=acegisecurity,dc=org - * has the root DN "dc=acegisecurity,dc=org". - * + * Works out the root DN for an LDAP URL.

For example, the URL + * ldap://monkeymachine:11389/dc=acegisecurity,dc=org has the root DN "dc=acegisecurity,dc=org".

* * @param url the LDAP URL + * * @return the root DN */ public static String parseRootDnFromUrl(String url) { @@ -102,7 +104,6 @@ public class LdapUtils { String urlRootDn = ""; if (url.startsWith("ldap:") || url.startsWith("ldaps:")) { - // URI uri = parseLdapUrl(url); // urlRootDn = uri.getPath(); @@ -114,7 +115,7 @@ public class LdapUtils { // Match the slash at the end of the address (if there) int slash = url.indexOf('/'); - if(slash >= 0) { + if (slash >= 0) { urlRootDn = url.substring(slash); } } else { @@ -130,13 +131,13 @@ public class LdapUtils { } // removed for 1.3 compatibility - - /** +/** * Parses the supplied LDAP URL. * @param url the URL (e.g. ldap://monkeymachine:11389/dc=acegisecurity,dc=org). * @return the URI object created from the URL * @throws IllegalArgumentException if the URL is null, empty or the URI syntax is invalid. */ + // private static URI parseLdapUrl(String url) { // Assert.hasLength(url); // @@ -148,5 +149,4 @@ public class LdapUtils { // throw iae; // } // } - } diff --git a/core/src/main/java/org/acegisecurity/ldap/NamingExceptionTranslator.java b/core/src/main/java/org/acegisecurity/ldap/NamingExceptionTranslator.java index 65a460dacb..3a9dae8b53 100644 --- a/core/src/main/java/org/acegisecurity/ldap/NamingExceptionTranslator.java +++ b/core/src/main/java/org/acegisecurity/ldap/NamingExceptionTranslator.java @@ -1,30 +1,31 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.acegisecurity.ldap; - -import org.springframework.dao.DataAccessException; - -import javax.naming.NamingException; - +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.ldap; + +import org.springframework.dao.DataAccessException; + +import javax.naming.NamingException; + + /** * @author Luke Taylor * @version $Id$ - */ -public interface NamingExceptionTranslator { - - DataAccessException translate(String task, NamingException e); - -} + */ +public interface NamingExceptionTranslator { + //~ Methods ======================================================================================================== + + DataAccessException translate(String task, NamingException e); +} diff --git a/core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java b/core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java index 85457a0979..294e4628fe 100644 --- a/core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java +++ b/core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,78 +15,71 @@ package org.acegisecurity.ldap.search; -import org.acegisecurity.userdetails.UsernameNotFoundException; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; -import org.acegisecurity.ldap.LdapUserSearch; import org.acegisecurity.ldap.InitialDirContextFactory; import org.acegisecurity.ldap.LdapTemplate; +import org.acegisecurity.ldap.LdapUserSearch; -import org.springframework.util.Assert; - -import org.springframework.dao.EmptyResultDataAccessException; +import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.acegisecurity.userdetails.ldap.LdapUserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; +import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import javax.naming.directory.SearchControls; +import org.springframework.dao.EmptyResultDataAccessException; + +import org.springframework.util.Assert; + import javax.naming.directory.DirContext; +import javax.naming.directory.SearchControls; + /** * LdapUserSearch implementation which uses an Ldap filter to locate the user. * - * @see SearchControls - * * @author Robert Sanders * @author Luke Taylor * @version $Id$ + * + * @see SearchControls */ public class FilterBasedLdapUserSearch implements LdapUserSearch { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(FilterBasedLdapUserSearch.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ + + private InitialDirContextFactory initialDirContextFactory; + private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); /** - * Context name to search in, relative to the root DN of the configured - * InitialDirContextFactory. - */ - private String searchBase = ""; - - /** - * The LDAP SearchControls object used for the search. Shared between searches - * so shouldn't be modified once the bean has been configured. + * The LDAP SearchControls object used for the search. Shared between searches so shouldn't be modified + * once the bean has been configured. */ private SearchControls searchControls = new SearchControls(); + /** Context name to search in, relative to the root DN of the configured InitialDirContextFactory. */ + private String searchBase = ""; + /** - * The filter expression used in the user search. This is an LDAP - * search filter (as defined in 'RFC 2254') with optional arguments. See the documentation - * for the search methods in {@link javax.naming.directory.DirContext DirContext} - * for more information. - *

- * In this case, the username is the only parameter. - *

- * Possible examples are: - *
    - *
  • (uid={0}) - this would search for a username match on the uid attribute.
  • - *
- * TODO: more examples. - * + * The filter expression used in the user search. This is an LDAP search filter (as defined in 'RFC 2254') + * with optional arguments. See the documentation for the search methods in {@link + * javax.naming.directory.DirContext DirContext} for more information.

In this case, the username is the + * only parameter.

+ * Possible examples are: + *
    + *
  • (uid={0}) - this would search for a username match on the uid attribute.
  • + *
+ * TODO: more examples. */ private String searchFilter; - private InitialDirContextFactory initialDirContextFactory; + //~ Constructors =================================================================================================== - private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); - - //~ Methods ================================================================ - - public FilterBasedLdapUserSearch(String searchBase, - String searchFilter, - InitialDirContextFactory initialDirContextFactory) { + public FilterBasedLdapUserSearch(String searchBase, String searchFilter, + InitialDirContextFactory initialDirContextFactory) { Assert.notNull(initialDirContextFactory, "initialDirContextFactory must not be null"); Assert.notNull(searchFilter, "searchFilter must not be null."); Assert.notNull(searchBase, "searchBase must not be null (an empty string is acceptable)."); @@ -95,26 +88,29 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch { this.initialDirContextFactory = initialDirContextFactory; this.searchBase = searchBase; - if(searchBase.length() == 0) { - logger.info("SearchBase not set. Searches will be performed from the root: " + - initialDirContextFactory.getRootDn()); + if (searchBase.length() == 0) { + logger.info("SearchBase not set. Searches will be performed from the root: " + + initialDirContextFactory.getRootDn()); } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Return the LdapUserDetailsImpl containing the user's information * * @param username the username to search for. + * + * @return DOCUMENT ME! + * * @throws UsernameNotFoundException if no matching entry is found. */ public LdapUserDetails searchForUser(String username) { DirContext ctx = initialDirContextFactory.newInitialDirContext(); if (logger.isDebugEnabled()) { - logger.debug("Searching for user '" + username + "', in context " + ctx + - ", with user search " + this.toString()); + logger.debug("Searching for user '" + username + "', in context " + ctx + ", with user search " + + this.toString()); } LdapTemplate template = new LdapTemplate(initialDirContextFactory); @@ -122,51 +118,51 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch { template.setSearchControls(searchControls); try { - LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) - template.searchForSingleEntry(searchBase, searchFilter, new String[] { username }, userDetailsMapper); + LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) template.searchForSingleEntry(searchBase, + searchFilter, new String[] {username}, userDetailsMapper); user.setUsername(username); return user.createUserDetails(); - - } catch(EmptyResultDataAccessException notFound) { + } catch (EmptyResultDataAccessException notFound) { throw new UsernameNotFoundException("User " + username + " not found in directory."); } - } /** - * If true then searches the entire subtree as identified by context, - * if false (the default) then only searches the level identified by the context. - */ - public void setSearchSubtree(boolean searchSubtree) { - searchControls.setSearchScope(searchSubtree ? - SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE); - } - - /** - * The time (in milliseconds) which to wait before the search fails; - * the default is zero, meaning forever. - */ - public void setSearchTimeLimit(int searchTimeLimit) { - searchControls.setTimeLimit(searchTimeLimit); - } - - /** - * Sets the corresponding property on the SearchControls instance used - * in the search. + * Sets the corresponding property on the SearchControls instance used in the search. * + * @param deref DOCUMENT ME! */ public void setDerefLinkFlag(boolean deref) { searchControls.setDerefLinkFlag(deref); } + /** + * If true then searches the entire subtree as identified by context, if false (the default) then only + * searches the level identified by the context. + * + * @param searchSubtree DOCUMENT ME! + */ + public void setSearchSubtree(boolean searchSubtree) { + searchControls.setSearchScope(searchSubtree ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE); + } + + /** + * The time (in milliseconds) which to wait before the search fails; the default is zero, meaning forever. + * + * @param searchTimeLimit DOCUMENT ME! + */ + public void setSearchTimeLimit(int searchTimeLimit) { + searchControls.setTimeLimit(searchTimeLimit); + } + public String toString() { StringBuffer sb = new StringBuffer(); sb.append("[ searchFilter: '").append(searchFilter).append("', "); sb.append("searchBase: '").append(searchBase).append("'"); - sb.append(", scope: ").append(searchControls.getSearchScope() == - SearchControls.SUBTREE_SCOPE ? "subtree" : "single-level, "); + sb.append(", scope: ") + .append((searchControls.getSearchScope() == SearchControls.SUBTREE_SCOPE) ? "subtree" : "single-level, "); sb.append("searchTimeLimit: ").append(searchControls.getTimeLimit()); sb.append("derefLinkFlag: ").append(searchControls.getDerefLinkFlag()).append(" ]"); diff --git a/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java index 3e934c002c..50e9e42936 100644 --- a/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java @@ -24,26 +24,22 @@ import org.springframework.util.Assert; /** - * Base class for Authentication objects. - * - *

- * Implementations which use this class should be immutable. - *

+ * Base class for Authentication objects.

Implementations which use this class should be immutable.

* * @author Ben Alex * @author Luke Taylor * @version $Id$ */ public abstract class AbstractAuthenticationToken implements Authentication { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object details; private GrantedAuthority[] authorities; private boolean authenticated = false; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Retained for compatibility with subclasses written before the * AbstractAuthenticationToken(GrantedAuthority[]) constructor * was introduced. @@ -53,7 +49,7 @@ public abstract class AbstractAuthenticationToken implements Authentication { */ public AbstractAuthenticationToken() {} - /** +/** * Creates a token with the supplied array of authorities. * * @param authorities the list of GrantedAuthoritys for the @@ -67,24 +63,21 @@ public abstract class AbstractAuthenticationToken implements Authentication { if (authorities != null) { for (int i = 0; i < authorities.length; i++) { Assert.notNull(authorities[i], - "Granted authority element " + i - + " is null - GrantedAuthority[] cannot contain any null elements"); + "Granted authority element " + i + " is null - GrantedAuthority[] cannot contain any null elements"); } } this.authorities = authorities; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (obj instanceof AbstractAuthenticationToken) { AbstractAuthenticationToken test = (AbstractAuthenticationToken) obj; - if (!((this.getAuthorities() == null) - && (test.getAuthorities() == null))) { - if ((this.getAuthorities() == null) - || (test.getAuthorities() == null)) { + if (!((this.getAuthorities() == null) && (test.getAuthorities() == null))) { + if ((this.getAuthorities() == null) || (test.getAuthorities() == null)) { return false; } @@ -93,8 +86,7 @@ public abstract class AbstractAuthenticationToken implements Authentication { } for (int i = 0; i < this.getAuthorities().length; i++) { - if (!this.getAuthorities()[i].equals( - test.getAuthorities()[i])) { + if (!this.getAuthorities()[i].equals(test.getAuthorities()[i])) { return false; } } @@ -108,8 +100,7 @@ public abstract class AbstractAuthenticationToken implements Authentication { return false; } - if ((this.details != null) - && (!this.details.equals(test.getDetails()))) { + if ((this.details != null) && (!this.details.equals(test.getDetails()))) { return false; } @@ -141,8 +132,7 @@ public abstract class AbstractAuthenticationToken implements Authentication { return ((UserDetails) this.getPrincipal()).getUsername(); } - return (this.getPrincipal() == null) ? "" : this.getPrincipal() - .toString(); + return (this.getPrincipal() == null) ? "" : this.getPrincipal().toString(); } public int hashCode() { diff --git a/core/src/main/java/org/acegisecurity/providers/AuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/AuthenticationProvider.java index 52cb6f58a8..9e875bdfca 100644 --- a/core/src/main/java/org/acegisecurity/providers/AuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/AuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import org.acegisecurity.AuthenticationException; * @version $Id$ */ public interface AuthenticationProvider { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Performs authentication with the same contract as {@link @@ -35,12 +35,10 @@ public interface AuthenticationProvider { * * @param authentication the authentication request object. * - * @return a fully authenticated object including credentials. May return - * null if the AuthenticationProvider is - * unable to support authentication of the passed - * Authentication object. In such a case, the next - * AuthenticationProvider that supports the presented - * Authentication class will be tried. + * @return a fully authenticated object including credentials. May return null if the + * AuthenticationProvider is unable to support authentication of the passed + * Authentication object. In such a case, the next AuthenticationProvider that + * supports the presented Authentication class will be tried. * * @throws AuthenticationException if authentication fails. */ @@ -48,27 +46,19 @@ public interface AuthenticationProvider { throws AuthenticationException; /** - * Returns true if this AuthenticationProvider - * supports the indicated Authentication object. - * - *

- * Returning true does not guarantee an - * AuthenticationProvider will be able to authenticate the - * presented instance of the Authentication class. It simply - * indicates it can support closer evaluation of it. An - * AuthenticationProvider can still return null - * from the {@link #authenticate(Authentication)} method to indicate - * another AuthenticationProvider should be tried. - *

- * - *

- * Selection of an AuthenticationProvider capable of - * performing authentication is conducted at runtime the - * ProviderManager. - *

+ * Returns true if this AuthenticationProvider supports the indicated + * Authentication object.

Returning true does not guarantee an + * AuthenticationProvider will be able to authenticate the presented instance of the + * Authentication class. It simply indicates it can support closer evaluation of it. An + * AuthenticationProvider can still return null from the {@link + * #authenticate(Authentication)} method to indicate another AuthenticationProvider should be tried.

+ *

Selection of an AuthenticationProvider capable of performing authentication is + * conducted at runtime the ProviderManager.

* - * @return true if the implementation can more closely - * evaluate the Authentication class presented + * @param authentication DOCUMENT ME! + * + * @return true if the implementation can more closely evaluate the Authentication class + * presented */ public boolean supports(Class authentication); } diff --git a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java index a2ffe02c5c..85d587de8b 100644 --- a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java +++ b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,6 @@ package org.acegisecurity.providers; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - import org.acegisecurity.AbstractAuthenticationManager; import org.acegisecurity.AccountExpiredException; import org.acegisecurity.AcegiMessageSource; @@ -31,9 +25,11 @@ import org.acegisecurity.BadCredentialsException; import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.DisabledException; import org.acegisecurity.LockedException; + import org.acegisecurity.concurrent.ConcurrentLoginException; import org.acegisecurity.concurrent.ConcurrentSessionController; import org.acegisecurity.concurrent.NullConcurrentSessionController; + import org.acegisecurity.event.authentication.AbstractAuthenticationEvent; import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent; import org.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent; @@ -45,68 +41,62 @@ import org.acegisecurity.event.authentication.AuthenticationFailureProviderNotFo import org.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent; import org.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent; import org.acegisecurity.event.authentication.AuthenticationSuccessEvent; + import org.acegisecurity.providers.cas.ProxyUntrustedException; + import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + /** - * Iterates an {@link Authentication} request through a list of {@link - * AuthenticationProvider}s. Can optionally be configured with a {@link - * ConcurrentSessionController} to limit the number of sessions a user can - * have. - * - *

- * AuthenticationProviders are tried in order until one provides a - * non-null response. A non-null response indicates the provider had authority - * to decide on the authentication request and no further providers are tried. - * If an AuthenticationException is thrown by a provider, it is - * retained until subsequent providers are tried. If a subsequent provider - * successfully authenticates the request, the earlier authentication - * exception is disregarded and the successful authentication will be used. If - * no subsequent provider provides a non-null response, or a new - * AuthenticationException, the last - * AuthenticationException received will be used. If no provider - * returns a non-null response, or indicates it can even process an - * Authentication, the ProviderManager will throw a - * ProviderNotFoundException. - *

- * - *

- * If a valid Authentication is returned by an - * AuthenticationProvider, the ProviderManager will - * publish an {@link - * org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If an - * AuthenticationException is detected, the final - * AuthenticationException thrown will be used to publish an - * appropriate failure event. By default ProviderManager maps - * common exceptions to events, but this can be fine-tuned by providing a new - * exceptionMappingsjava.util.Properties object. In - * the properties object, each of the keys represent the fully qualified - * classname of the exception, and each of the values represent the name of an - * event class which subclasses {@link - * org.acegisecurity.event.authentication.AbstractAuthenticationFailureEvent} - * and provides its constructor. - *

+ * Iterates an {@link Authentication} request through a list of {@link AuthenticationProvider}s. Can optionally be + * configured with a {@link ConcurrentSessionController} to limit the number of sessions a user can have.

AuthenticationProviders + * are tried in order until one provides a non-null response. A non-null response indicates the provider had authority + * to decide on the authentication request and no further providers are tried. If an + * AuthenticationException is thrown by a provider, it is retained until subsequent providers are tried. + * If a subsequent provider successfully authenticates the request, the earlier authentication exception is + * disregarded and the successful authentication will be used. If no subsequent provider provides a non-null response, + * or a new AuthenticationException, the last AuthenticationException received will be used. + * If no provider returns a non-null response, or indicates it can even process an Authentication, the + * ProviderManager will throw a ProviderNotFoundException.

+ *

If a valid Authentication is returned by an AuthenticationProvider, the + * ProviderManager will publish an {@link + * org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If an AuthenticationException is + * detected, the final AuthenticationException thrown will be used to publish an appropriate failure + * event. By default ProviderManager maps common exceptions to events, but this can be fine-tuned by + * providing a new exceptionMappingsjava.util.Properties object. In the properties object, + * each of the keys represent the fully qualified classname of the exception, and each of the values represent the + * name of an event class which subclasses {@link + * org.acegisecurity.event.authentication.AbstractAuthenticationFailureEvent} and provides its constructor.

* * @see ConcurrentSessionController */ -public class ProviderManager extends AbstractAuthenticationManager - implements InitializingBean, ApplicationEventPublisherAware, - MessageSourceAware { - //~ Static fields/initializers ============================================= +public class ProviderManager extends AbstractAuthenticationManager implements InitializingBean, + ApplicationEventPublisherAware, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(ProviderManager.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationEventPublisher applicationEventPublisher; private ConcurrentSessionController sessionController = new NullConcurrentSessionController(); @@ -114,7 +104,7 @@ public class ProviderManager extends AbstractAuthenticationManager protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private Properties exceptionMappings; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { checkIfValidList(this.providers); @@ -126,12 +116,10 @@ public class ProviderManager extends AbstractAuthenticationManager AuthenticationFailureExpiredEvent.class.getName()); exceptionMappings.put(AuthenticationServiceException.class.getName(), AuthenticationFailureServiceExceptionEvent.class.getName()); - exceptionMappings.put(LockedException.class.getName(), - AuthenticationFailureLockedEvent.class.getName()); + exceptionMappings.put(LockedException.class.getName(), AuthenticationFailureLockedEvent.class.getName()); exceptionMappings.put(CredentialsExpiredException.class.getName(), AuthenticationFailureCredentialsExpiredEvent.class.getName()); - exceptionMappings.put(DisabledException.class.getName(), - AuthenticationFailureDisabledEvent.class.getName()); + exceptionMappings.put(DisabledException.class.getName(), AuthenticationFailureDisabledEvent.class.getName()); exceptionMappings.put(BadCredentialsException.class.getName(), AuthenticationFailureBadCredentialsEvent.class.getName()); exceptionMappings.put(UsernameNotFoundException.class.getName(), @@ -148,38 +136,26 @@ public class ProviderManager extends AbstractAuthenticationManager private void checkIfValidList(List listToCheck) { if ((listToCheck == null) || (listToCheck.size() == 0)) { - throw new IllegalArgumentException( - "A list of AuthenticationManagers is required"); + throw new IllegalArgumentException("A list of AuthenticationManagers is required"); } } /** - * Provided so subclasses can add extra exception mappings during startup - * if no exception mappings are injected by the IoC container. + * Provided so subclasses can add extra exception mappings during startup if no exception mappings are + * injected by the IoC container. * - * @param exceptionMappings the properties object, which already has - * entries in it + * @param exceptionMappings the properties object, which already has entries in it */ - protected void doAddExtraDefaultExceptionMappings( - Properties exceptionMappings) {} + protected void doAddExtraDefaultExceptionMappings(Properties exceptionMappings) {} /** - * Attempts to authenticate the passed {@link Authentication} object. - * - *

- * The list of {@link AuthenticationProvider}s will be successively tried - * until an AuthenticationProvider indicates it is capable - * of authenticating the type of Authentication object - * passed. Authentication will then be attempted with that - * AuthenticationProvider. - *

- * - *

- * If more than one AuthenticationProvider supports the passed - * Authentication object, only the first - * AuthenticationProvider tried will determine the result. No - * subsequent AuthenticationProviders will be tried. - *

+ * Attempts to authenticate the passed {@link Authentication} object.

The list of {@link + * AuthenticationProvider}s will be successively tried until an AuthenticationProvider indicates it + * is capable of authenticating the type of Authentication object passed. Authentication will then + * be attempted with that AuthenticationProvider.

+ *

If more than one AuthenticationProvider supports the passed Authentication + * object, only the first AuthenticationProvider tried will determine the result. No subsequent + * AuthenticationProviders will be tried.

* * @param authentication the authentication request object. * @@ -199,8 +175,7 @@ public class ProviderManager extends AbstractAuthenticationManager AuthenticationProvider provider = (AuthenticationProvider) iter.next(); if (provider.supports(toTest)) { - logger.debug("Authentication attempt using " - + provider.getClass().getName()); + logger.debug("Authentication attempt using " + provider.getClass().getName()); Authentication result = null; @@ -214,8 +189,7 @@ public class ProviderManager extends AbstractAuthenticationManager if (result != null) { sessionController.registerSuccessfulAuthentication(result); - applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent( - result)); + applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent(result)); return result; } @@ -223,24 +197,22 @@ public class ProviderManager extends AbstractAuthenticationManager } if (lastException == null) { - lastException = new ProviderNotFoundException(messages.getMessage( - "ProviderManager.providerNotFound", - new Object[] {toTest.getName()}, - "No AuthenticationProvider found for {0}")); + lastException = new ProviderNotFoundException(messages.getMessage("ProviderManager.providerNotFound", + new Object[] {toTest.getName()}, "No AuthenticationProvider found for {0}")); } // Publish the event - String className = exceptionMappings.getProperty(lastException.getClass() - .getName()); + String className = exceptionMappings.getProperty(lastException.getClass().getName()); AbstractAuthenticationEvent event = null; if (className != null) { try { Class clazz = getClass().getClassLoader().loadClass(className); - Constructor constructor = clazz.getConstructor(new Class[] {Authentication.class, AuthenticationException.class}); + Constructor constructor = clazz.getConstructor(new Class[] { + Authentication.class, AuthenticationException.class + }); Object obj = constructor.newInstance(new Object[] {authentication, lastException}); - Assert.isInstanceOf(AbstractAuthenticationEvent.class, obj, - "Must be an AbstractAuthenticationEvent"); + Assert.isInstanceOf(AbstractAuthenticationEvent.class, obj, "Must be an AbstractAuthenticationEvent"); event = (AbstractAuthenticationEvent) obj; } catch (ClassNotFoundException ignored) {} catch (NoSuchMethodException ignored) {} @@ -253,8 +225,7 @@ public class ProviderManager extends AbstractAuthenticationManager applicationEventPublisher.publishEvent(event); } else { if (logger.isDebugEnabled()) { - logger.debug("No event was found for the exception " - + lastException.getClass().getName()); + logger.debug("No event was found for the exception " + lastException.getClass().getName()); } } @@ -267,9 +238,8 @@ public class ProviderManager extends AbstractAuthenticationManager } /** - * The configured {@link ConcurrentSessionController} is returned or the - * {@link NullConcurrentSessionController} if a specific one has not been - * set. + * The configured {@link ConcurrentSessionController} is returned or the {@link + * NullConcurrentSessionController} if a specific one has not been set. * * @return {@link ConcurrentSessionController} instance */ @@ -277,8 +247,7 @@ public class ProviderManager extends AbstractAuthenticationManager return sessionController; } - public void setApplicationEventPublisher( - ApplicationEventPublisher applicationEventPublisher) { + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } @@ -287,8 +256,7 @@ public class ProviderManager extends AbstractAuthenticationManager } /** - * Sets the {@link AuthenticationProvider} objects to be used for - * authentication. + * Sets the {@link AuthenticationProvider} objects to be used for authentication. * * @param newList * @@ -307,8 +275,7 @@ public class ProviderManager extends AbstractAuthenticationManager AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject; } catch (ClassCastException cce) { - throw new IllegalArgumentException("AuthenticationProvider " - + currentObject.getClass().getName() + throw new IllegalArgumentException("AuthenticationProvider " + currentObject.getClass().getName() + " must implement AuthenticationProvider"); } } @@ -317,14 +284,12 @@ public class ProviderManager extends AbstractAuthenticationManager } /** - * Set the {@link ConcurrentSessionController} to be used for limiting - * user's sessions. The {@link NullConcurrentSessionController} is used - * by default + * Set the {@link ConcurrentSessionController} to be used for limiting user's sessions. The {@link + * NullConcurrentSessionController} is used by default * * @param sessionController {@link ConcurrentSessionController} */ - public void setSessionController( - ConcurrentSessionController sessionController) { + public void setSessionController(ConcurrentSessionController sessionController) { this.sessionController = sessionController; } } diff --git a/core/src/main/java/org/acegisecurity/providers/ProviderNotFoundException.java b/core/src/main/java/org/acegisecurity/providers/ProviderNotFoundException.java index 4d81022d39..71e59d69e2 100644 --- a/core/src/main/java/org/acegisecurity/providers/ProviderNotFoundException.java +++ b/core/src/main/java/org/acegisecurity/providers/ProviderNotFoundException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,16 @@ import org.acegisecurity.AuthenticationException; /** - * Thrown by {@link ProviderManager} if no {@link AuthenticationProvider} - * could be found that supports the presented {@link - * org.acegisecurity.Authentication} object. + * Thrown by {@link ProviderManager} if no {@link AuthenticationProvider} could be found that supports the + * presented {@link org.acegisecurity.Authentication} object. * * @author Ben Alex * @version $Id$ */ public class ProviderNotFoundException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a ProviderNotFoundException with the specified * message. * @@ -39,7 +38,7 @@ public class ProviderNotFoundException extends AuthenticationException { super(msg); } - /** +/** * Constructs a ProviderNotFoundException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationProvider.java index 7330325243..30b7f055d2 100644 --- a/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,24 +20,16 @@ import org.acegisecurity.AuthenticationException; /** - * An {@link AuthenticationProvider} implementation for the {@link - * TestingAuthenticationToken}. - * - *

- * It simply accepts as valid whatever is contained within the - * TestingAuthenticationToken. - *

- * - *

- * The purpose of this implementation is to facilitate unit testing. This - * provider should never be enabled on a production system. - *

+ * An {@link AuthenticationProvider} implementation for the {@link TestingAuthenticationToken}.

It simply + * accepts as valid whatever is contained within the TestingAuthenticationToken.

+ *

The purpose of this implementation is to facilitate unit testing. This provider should never be enabled + * on a production system.

* * @author Ben Alex * @version $Id$ */ public class TestingAuthenticationProvider implements AuthenticationProvider { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Authentication authenticate(Authentication authentication) throws AuthenticationException { diff --git a/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationToken.java index e4c2affd44..b50a2c9a25 100644 --- a/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/TestingAuthenticationToken.java @@ -19,33 +19,27 @@ import org.acegisecurity.GrantedAuthority; /** - * An {@link org.acegisecurity.Authentication} implementation that is designed - * for use whilst unit testing. - * - *

- * The corresponding authentication provider is {@link - * TestingAuthenticationProvider}. - *

+ * An {@link org.acegisecurity.Authentication} implementation that is designed for use whilst unit testing.

The + * corresponding authentication provider is {@link TestingAuthenticationProvider}.

* * @author Ben Alex * @version $Id$ */ public class TestingAuthenticationToken extends AbstractAuthenticationToken { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object credentials; private Object principal; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public TestingAuthenticationToken(Object principal, Object credentials, - GrantedAuthority[] authorities) { + public TestingAuthenticationToken(Object principal, Object credentials, GrantedAuthority[] authorities) { super(authorities); this.principal = principal; this.credentials = credentials; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return this.credentials; diff --git a/core/src/main/java/org/acegisecurity/providers/UsernamePasswordAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/UsernamePasswordAuthenticationToken.java index 5742b0d016..366ad0dfdb 100644 --- a/core/src/main/java/org/acegisecurity/providers/UsernamePasswordAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/UsernamePasswordAuthenticationToken.java @@ -19,29 +19,23 @@ import org.acegisecurity.GrantedAuthority; /** - * An {@link org.acegisecurity.Authentication} implementation that is designed - * for simple presentation of a username and password. - * - *

- * The principal and credentials should be set with - * an Object that provides the respective property via its - * Object.toString() method. The simplest such - * Object to use is String. - *

+ * An {@link org.acegisecurity.Authentication} implementation that is designed for simple presentation of a + * username and password.

The principal and credentials should be set with an + * Object that provides the respective property via its Object.toString() method. The + * simplest such Object to use is String.

* * @author Ben Alex * @version $Id$ */ -public class UsernamePasswordAuthenticationToken - extends AbstractAuthenticationToken { - //~ Instance fields ======================================================== +public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken { + //~ Instance fields ================================================================================================ private Object credentials; private Object principal; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * This constructor can be safely used by any code that wishes to create a * UsernamePasswordAuthenticationToken, as the {@link * #isAuthenticated()} will return false. @@ -49,15 +43,14 @@ public class UsernamePasswordAuthenticationToken * @param principal DOCUMENT ME! * @param credentials DOCUMENT ME! */ - public UsernamePasswordAuthenticationToken(Object principal, - Object credentials) { + public UsernamePasswordAuthenticationToken(Object principal, Object credentials) { super(null); this.principal = principal; this.credentials = credentials; setAuthenticated(false); } - /** +/** * This constructor should only be used by * AuthenticationManager or * AuthenticationProvider implementations that are satisfied @@ -68,15 +61,14 @@ public class UsernamePasswordAuthenticationToken * @param credentials * @param authorities */ - public UsernamePasswordAuthenticationToken(Object principal, - Object credentials, GrantedAuthority[] authorities) { + public UsernamePasswordAuthenticationToken(Object principal, Object credentials, GrantedAuthority[] authorities) { super(authorities); this.principal = principal; this.credentials = credentials; super.setAuthenticated(true); // must use super, as we override } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return this.credentials; diff --git a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java index 65bf2ff47e..80ce3e5ec2 100644 --- a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,38 +19,38 @@ import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; /** * An {@link AuthenticationProvider} implementation that validates {@link - * org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken}s. - * - *

- * To be successfully validated, the {@link - * org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()} - * must match this class' {@link #getKey()}. - *

+ * org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken}s.

To be successfully validated, the + * {@link org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()} must match this class' + * {@link #getKey()}.

*/ -public class AnonymousAuthenticationProvider implements AuthenticationProvider, - InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class AnonymousAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private String key; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(key, "A Key is required"); @@ -63,10 +63,8 @@ public class AnonymousAuthenticationProvider implements AuthenticationProvider, return null; } - if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication) - .getKeyHash()) { - throw new BadCredentialsException(messages.getMessage( - "AnonymousAuthenticationProvider.incorrectKey", + if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication).getKeyHash()) { + throw new BadCredentialsException(messages.getMessage("AnonymousAuthenticationProvider.incorrectKey", "The presented AnonymousAuthenticationToken does not contain the expected key")); } diff --git a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationToken.java index 7687fe8afe..00f7fe2dd7 100644 --- a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationToken.java @@ -28,16 +28,15 @@ import java.io.Serializable; * @author Ben Alex * @version $Id$ */ -public class AnonymousAuthenticationToken extends AbstractAuthenticationToken - implements Serializable { - //~ Instance fields ======================================================== +public class AnonymousAuthenticationToken extends AbstractAuthenticationToken implements Serializable { + //~ Instance fields ================================================================================================ private Object principal; private int keyHash; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor. * * @param key to identify if this object made by an authorised client @@ -46,15 +45,12 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken * * @throws IllegalArgumentException if a null was passed */ - public AnonymousAuthenticationToken(String key, Object principal, - GrantedAuthority[] authorities) { + public AnonymousAuthenticationToken(String key, Object principal, GrantedAuthority[] authorities) { super(authorities); - if ((key == null) || ("".equals(key)) || (principal == null) - || "".equals(principal) || (authorities == null) + if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (authorities == null) || (authorities.length == 0)) { - throw new IllegalArgumentException( - "Cannot pass null or empty values to constructor"); + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); } this.keyHash = key.hashCode(); @@ -62,7 +58,7 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken setAuthenticated(true); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (!super.equals(obj)) { @@ -75,7 +71,7 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken if (this.getKeyHash() != test.getKeyHash()) { return false; } - + return true; } diff --git a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilter.java b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilter.java index fda73d1c54..000fe24c96 100644 --- a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilter.java @@ -43,31 +43,26 @@ import javax.servlet.http.HttpServletRequest; /** - * Detects if there is no Authentication object in the - * SecurityContextHolder, and populates it with one if needed. - * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Detects if there is no Authentication object in the SecurityContextHolder, and + * populates it with one if needed.

Do not use this class directly. Instead configure web.xml + * to use the {@link org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ public class AnonymousProcessingFilter implements Filter, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AnonymousProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); private String key; private UserAttribute userAttribute; private boolean removeAfterRequest = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(userAttribute); @@ -75,18 +70,15 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { } /** - * Enables subclasses to determine whether or not an anonymous - * authentication token should be setup for this request. This is useful - * if anonymous authentication should be allowed only for specific IP - * subnet ranges etc. + * Enables subclasses to determine whether or not an anonymous authentication token should be setup for + * this request. This is useful if anonymous authentication should be allowed only for specific IP subnet ranges + * etc. * * @param request to assist the method determine request details * - * @return true if the anonymous token should be setup for - * this request (provided that the request doesn't already have - * some other Authentication inside it), or - * false if no anonymous token should be setup for - * this request + * @return true if the anonymous token should be setup for this request (provided that the request + * doesn't already have some other Authentication inside it), or false if no + * anonymous token should be setup for this request */ protected boolean applyAnonymousForThisRequest(ServletRequest request) { return true; @@ -96,10 +88,9 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { Assert.isInstanceOf(HttpServletRequest.class, request, "ServletRequest must be an instance of HttpServletRequest"); - AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, - userAttribute.getPassword(), userAttribute.getAuthorities()); - auth.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, userAttribute.getPassword(), + userAttribute.getAuthorities()); + auth.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); return auth; } @@ -109,29 +100,23 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { boolean addedToken = false; if (applyAnonymousForThisRequest(request)) { if (SecurityContextHolder.getContext().getAuthentication() == null) { - SecurityContextHolder.getContext() - .setAuthentication(createAuthentication( - request)); + SecurityContextHolder.getContext().setAuthentication(createAuthentication(request)); addedToken = true; if (logger.isDebugEnabled()) { - logger.debug( - "Populated SecurityContextHolder with anonymous token: '" - + SecurityContextHolder.getContext().getAuthentication() - + "'"); + logger.debug("Populated SecurityContextHolder with anonymous token: '" + + SecurityContextHolder.getContext().getAuthentication() + "'"); } } else { if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder not populated with anonymous token, as it already contained: '" - + SecurityContextHolder.getContext().getAuthentication() - + "'"); + logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '" + + SecurityContextHolder.getContext().getAuthentication() + "'"); } } } @@ -140,9 +125,7 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { chain.doFilter(request, response); } finally { if (addedToken && removeAfterRequest - && createAuthentication(request) - .equals(SecurityContextHolder.getContext() - .getAuthentication())) { + && createAuthentication(request).equals(SecurityContextHolder.getContext().getAuthentication())) { SecurityContextHolder.getContext().setAuthentication(null); } } @@ -169,10 +152,8 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { return removeAfterRequest; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } @@ -181,19 +162,12 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean { } /** - * Controls whether the filter will remove the Anonymous token after the - * request is complete. Generally this is desired to avoid the expense of - * a session being created by {@link - * org.acegisecurity.context.HttpSessionContextIntegrationFilter - * HttpSessionContextIntegrationFilter} simply to store the Anonymous - * authentication token. - * - *

- * Defaults to true, being the most optimal and appropriate - * option (ie AnonymousProcessingFilter will clear the token - * at the end of each request, thus avoiding the session creation overhead - * in a typical configuration. - *

+ * Controls whether the filter will remove the Anonymous token after the request is complete. Generally + * this is desired to avoid the expense of a session being created by {@link + * org.acegisecurity.context.HttpSessionContextIntegrationFilter HttpSessionContextIntegrationFilter} simply to + * store the Anonymous authentication token.

Defaults to true, being the most optimal and + * appropriate option (ie AnonymousProcessingFilter will clear the token at the end of each request, + * thus avoiding the session creation overhead in a typical configuration.

* * @param removeAfterRequest DOCUMENT ME! */ diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java index 4dbdd5d9c2..7bbdb1085a 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,42 +19,42 @@ import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.ui.cas.CasProcessingFilter; + import org.acegisecurity.userdetails.UserDetails; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; /** - * An {@link AuthenticationProvider} implementation that integrates with JA-SIG - * Central Authentication Service (CAS). - * - *

- * This AuthenticationProvider is capable of validating {@link - * UsernamePasswordAuthenticationToken} requests which contain a - * principal name equal to either {@link - * CasProcessingFilter#CAS_STATEFUL_IDENTIFIER} or {@link - * CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a - * previously created {@link CasAuthenticationToken}. - *

+ * An {@link AuthenticationProvider} implementation that integrates with JA-SIG Central Authentication Service + * (CAS).

This AuthenticationProvider is capable of validating {@link + * UsernamePasswordAuthenticationToken} requests which contain a principal name equal to either {@link + * CasProcessingFilter#CAS_STATEFUL_IDENTIFIER} or {@link CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also + * validate a previously created {@link CasAuthenticationToken}.

* * @author Ben Alex * @version $Id$ */ -public class CasAuthenticationProvider implements AuthenticationProvider, - InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class CasAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private CasAuthoritiesPopulator casAuthoritiesPopulator; private CasProxyDecider casProxyDecider; @@ -63,15 +63,13 @@ public class CasAuthenticationProvider implements AuthenticationProvider, private String key; private TicketValidator ticketValidator; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(this.casAuthoritiesPopulator, - "A casAuthoritiesPopulator must be set"); + Assert.notNull(this.casAuthoritiesPopulator, "A casAuthoritiesPopulator must be set"); Assert.notNull(this.ticketValidator, "A ticketValidator must be set"); Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set"); - Assert.notNull(this.statelessTicketCache, - "A statelessTicketCache must be set"); + Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set"); Assert.notNull(key, "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated"); Assert.notNull(this.messages, "A message source must be set"); @@ -84,39 +82,32 @@ public class CasAuthenticationProvider implements AuthenticationProvider, } if (authentication instanceof UsernamePasswordAuthenticationToken - && (!CasProcessingFilter.CAS_STATEFUL_IDENTIFIER.equals( - authentication.getPrincipal().toString()) - && !CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals( - authentication.getPrincipal().toString()))) { + && (!CasProcessingFilter.CAS_STATEFUL_IDENTIFIER.equals(authentication.getPrincipal().toString()) + && !CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal().toString()))) { // UsernamePasswordAuthenticationToken not CAS related return null; } // If an existing CasAuthenticationToken, just check we created it if (authentication instanceof CasAuthenticationToken) { - if (this.key.hashCode() == ((CasAuthenticationToken) authentication) - .getKeyHash()) { + if (this.key.hashCode() == ((CasAuthenticationToken) authentication).getKeyHash()) { return authentication; } else { - throw new BadCredentialsException(messages.getMessage( - "CasAuthenticationProvider.incorrectKey", + throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.incorrectKey", "The presented CasAuthenticationToken does not contain the expected key")); } } // Ensure credentials are presented - if ((authentication.getCredentials() == null) - || "".equals(authentication.getCredentials())) { - throw new BadCredentialsException(messages.getMessage( - "CasAuthenticationProvider.noServiceTicket", + if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) { + throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.noServiceTicket", "Failed to provide a CAS service ticket to validate")); } boolean stateless = false; if (authentication instanceof UsernamePasswordAuthenticationToken - && CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals( - authentication.getPrincipal())) { + && CasProcessingFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal())) { stateless = true; } @@ -124,8 +115,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider, if (stateless) { // Try to obtain from cache - result = statelessTicketCache.getByTicketId(authentication.getCredentials() - .toString()); + result = statelessTicketCache.getByTicketId(authentication.getCredentials().toString()); } if (result == null) { @@ -140,24 +130,20 @@ public class CasAuthenticationProvider implements AuthenticationProvider, return result; } - private CasAuthenticationToken authenticateNow( - Authentication authentication) throws AuthenticationException { + private CasAuthenticationToken authenticateNow(Authentication authentication) + throws AuthenticationException { // Validate - TicketResponse response = ticketValidator.confirmTicketValid(authentication.getCredentials() - .toString()); + TicketResponse response = ticketValidator.confirmTicketValid(authentication.getCredentials().toString()); // Check proxy list is trusted this.casProxyDecider.confirmProxyListTrusted(response.getProxyList()); // Lookup user details - UserDetails userDetails = this.casAuthoritiesPopulator.getUserDetails(response - .getUser()); + UserDetails userDetails = this.casAuthoritiesPopulator.getUserDetails(response.getUser()); // Construct CasAuthenticationToken - return new CasAuthenticationToken(this.key, userDetails, - authentication.getCredentials(), userDetails.getAuthorities(), - userDetails, response.getProxyList(), - response.getProxyGrantingTicketIou()); + return new CasAuthenticationToken(this.key, userDetails, authentication.getCredentials(), + userDetails.getAuthorities(), userDetails, response.getProxyList(), response.getProxyGrantingTicketIou()); } public CasAuthoritiesPopulator getCasAuthoritiesPopulator() { @@ -180,8 +166,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider, return ticketValidator; } - public void setCasAuthoritiesPopulator( - CasAuthoritiesPopulator casAuthoritiesPopulator) { + public void setCasAuthoritiesPopulator(CasAuthoritiesPopulator casAuthoritiesPopulator) { this.casAuthoritiesPopulator = casAuthoritiesPopulator; } @@ -197,8 +182,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider, this.messages = new MessageSourceAccessor(messageSource); } - public void setStatelessTicketCache( - StatelessTicketCache statelessTicketCache) { + public void setStatelessTicketCache(StatelessTicketCache statelessTicketCache) { this.statelessTicketCache = statelessTicketCache; } @@ -207,8 +191,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider, } public boolean supports(Class authentication) { - if (UsernamePasswordAuthenticationToken.class.isAssignableFrom( - authentication)) { + if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)) { return true; } else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) { return true; diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java index 0ae8ad00de..3e00dc543c 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java @@ -32,9 +32,8 @@ import java.util.List; * @author Ben Alex * @version $Id$ */ -public class CasAuthenticationToken extends AbstractAuthenticationToken - implements Serializable { - //~ Instance fields ======================================================== +public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable { + //~ Instance fields ================================================================================================ private final List proxyList; private final Object credentials; @@ -43,9 +42,9 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken private final UserDetails userDetails; private final int keyHash; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor. * * @param key to identify if this object made by a given {@link @@ -65,18 +64,15 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken * * @throws IllegalArgumentException if a null was passed */ - public CasAuthenticationToken(final String key, final Object principal, - final Object credentials, final GrantedAuthority[] authorities, - final UserDetails userDetails, final List proxyList, final String proxyGrantingTicketIou) { + public CasAuthenticationToken(final String key, final Object principal, final Object credentials, + final GrantedAuthority[] authorities, final UserDetails userDetails, final List proxyList, + final String proxyGrantingTicketIou) { super(authorities); - if ((key == null) || ("".equals(key)) || (principal == null) - || "".equals(principal) || (credentials == null) - || "".equals(credentials) || (authorities == null) - || (userDetails == null) || (proxyList == null) + if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (credentials == null) + || "".equals(credentials) || (authorities == null) || (userDetails == null) || (proxyList == null) || (proxyGrantingTicketIou == null)) { - throw new IllegalArgumentException( - "Cannot pass null or empty values to constructor"); + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); } this.keyHash = key.hashCode(); @@ -88,7 +84,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken setAuthenticated(true); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(final Object obj) { if (!super.equals(obj)) { @@ -99,8 +95,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken CasAuthenticationToken test = (CasAuthenticationToken) obj; // proxyGrantingTicketIou is never null due to constructor - if (!this.getProxyGrantingTicketIou() - .equals(test.getProxyGrantingTicketIou())) { + if (!this.getProxyGrantingTicketIou().equals(test.getProxyGrantingTicketIou())) { return false; } @@ -134,8 +129,8 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken /** * Obtains the proxy granting ticket IOU. * - * @return the PGT IOU-ID or an empty String if no proxy - * callback was requested when validating the service ticket + * @return the PGT IOU-ID or an empty String if no proxy callback was requested when validating the + * service ticket */ public String getProxyGrantingTicketIou() { return proxyGrantingTicketIou; @@ -152,10 +147,8 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken public String toString() { StringBuffer sb = new StringBuffer(); sb.append(super.toString()); - sb.append("; Credentials (Service/Proxy Ticket): ") - .append(this.credentials); - sb.append("; Proxy-Granting Ticket IOU: ") - .append(this.proxyGrantingTicketIou); + sb.append("; Credentials (Service/Proxy Ticket): ").append(this.credentials); + sb.append("; Proxy-Granting Ticket IOU: ").append(this.proxyGrantingTicketIou); sb.append("; Proxy List: ").append(this.proxyList); return (sb.toString()); diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthoritiesPopulator.java index 67a1ab989c..05506320fd 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.providers.cas; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.userdetails.UserDetails; @@ -52,20 +53,15 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public interface CasAuthoritiesPopulator { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the granted authorities for the specified user. - * - *

- * May throw any AuthenticationException or return - * null if the authorities are unavailable. - *

+ * Obtains the granted authorities for the specified user.

May throw any + * AuthenticationException or return null if the authorities are unavailable.

* * @param casUserId as obtained from the CAS validation service * - * @return the details of the indicated user (at minimum the granted - * authorities and the username) + * @return the details of the indicated user (at minimum the granted authorities and the username) * * @throws AuthenticationException DOCUMENT ME! */ diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasProxyDecider.java b/core/src/main/java/org/acegisecurity/providers/cas/CasProxyDecider.java index ec239027ee..eb893a932b 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasProxyDecider.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/CasProxyDecider.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,15 +57,15 @@ import java.util.List; * @version $Id$ */ public interface CasProxyDecider { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Decides whether the proxy list is trusted. - * - *

- * Must throw any ProxyUntrustedException if the proxy list is - * untrusted. - *

+ * Decides whether the proxy list is trusted.

Must throw any ProxyUntrustedException if the + * proxy list is untrusted.

+ * + * @param proxyList DOCUMENT ME! + * + * @throws ProxyUntrustedException DOCUMENT ME! */ public void confirmProxyListTrusted(List proxyList) throws ProxyUntrustedException; diff --git a/core/src/main/java/org/acegisecurity/providers/cas/ProxyUntrustedException.java b/core/src/main/java/org/acegisecurity/providers/cas/ProxyUntrustedException.java index 20b581be49..7c3a4a98de 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/ProxyUntrustedException.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/ProxyUntrustedException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,9 @@ import org.acegisecurity.AuthenticationException; * @version $Id$ */ public class ProxyUntrustedException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a ProxyUntrustedException with the specified * message. * @@ -37,7 +37,7 @@ public class ProxyUntrustedException extends AuthenticationException { super(msg); } - /** +/** * Constructs a ProxyUntrustedException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/providers/cas/TicketResponse.java b/core/src/main/java/org/acegisecurity/providers/cas/TicketResponse.java index 4673290479..955c1a272c 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/TicketResponse.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/TicketResponse.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,15 +26,15 @@ import java.util.Vector; * @version $Id$ */ public class TicketResponse { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List proxyList; private String proxyGrantingTicketIou; private String user; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor. * *

@@ -52,8 +52,7 @@ public class TicketResponse { * * @throws IllegalArgumentException DOCUMENT ME! */ - public TicketResponse(String user, List proxyList, - String proxyGrantingTicketIou) { + public TicketResponse(String user, List proxyList, String proxyGrantingTicketIou) { if (proxyList == null) { proxyList = new Vector(); } @@ -63,8 +62,7 @@ public class TicketResponse { } if ((user == null) || "".equals(user)) { - throw new IllegalArgumentException( - "Cannot pass null or empty String for User"); + throw new IllegalArgumentException("Cannot pass null or empty String for User"); } this.user = user; @@ -72,7 +70,7 @@ public class TicketResponse { this.proxyGrantingTicketIou = proxyGrantingTicketIou; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public String getProxyGrantingTicketIou() { return proxyGrantingTicketIou; diff --git a/core/src/main/java/org/acegisecurity/providers/cas/TicketValidator.java b/core/src/main/java/org/acegisecurity/providers/cas/TicketValidator.java index 3c1d10cfbc..8363c2cb97 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/TicketValidator.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/TicketValidator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,17 +36,17 @@ import org.acegisecurity.AuthenticationException; * @version $Id$ */ public interface TicketValidator { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Returns information about the ticket, if it is valid for this service. - * - *

- * Must throw an AuthenticationException if the ticket is not - * valid for this service. - *

+ * Returns information about the ticket, if it is valid for this service.

Must throw an + * AuthenticationException if the ticket is not valid for this service.

+ * + * @param serviceTicket DOCUMENT ME! * * @return details of the CAS service ticket + * + * @throws AuthenticationException DOCUMENT ME! */ public TicketResponse confirmTicketValid(String serviceTicket) throws AuthenticationException; diff --git a/core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java b/core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java index 1828187b89..d5487a1f3b 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,40 +15,43 @@ package org.acegisecurity.providers.cas.cache; -import org.acegisecurity.providers.cas.CasAuthenticationToken; -import org.acegisecurity.providers.cas.StatelessTicketCache; - import net.sf.ehcache.Cache; import net.sf.ehcache.CacheException; import net.sf.ehcache.Element; +import org.acegisecurity.providers.cas.CasAuthenticationToken; +import org.acegisecurity.providers.cas.StatelessTicketCache; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataRetrievalFailureException; + import org.springframework.util.Assert; /** - * Caches tickets using a Spring IoC defined EHCACHE. + * Caches tickets using a Spring IoC defined EHCACHE. * * @author Ben Alex * @version $Id$ */ -public class EhCacheBasedTicketCache implements StatelessTicketCache, - InitializingBean { - //~ Static fields/initializers ============================================= +public class EhCacheBasedTicketCache implements StatelessTicketCache, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Cache cache; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() throws Exception { + Assert.notNull(cache, "cache mandatory"); + } public CasAuthenticationToken getByTicketId(String serviceTicket) { Element element = null; @@ -56,13 +59,11 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, try { element = cache.get(serviceTicket); } catch (CacheException cacheException) { - throw new DataRetrievalFailureException("Cache failure: " - + cacheException.getMessage()); + throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage()); } if (logger.isDebugEnabled()) { - logger.debug("Cache hit: " + (element != null) - + "; service ticket: " + serviceTicket); + logger.debug("Cache hit: " + (element != null) + "; service ticket: " + serviceTicket); } if (element == null) { @@ -72,18 +73,10 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, } } - public void setCache(Cache cache) { - this.cache = cache; - } - public Cache getCache() { return cache; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(cache, "cache mandatory"); - } - public void putTicketInCache(CasAuthenticationToken token) { Element element = new Element(token.getCredentials().toString(), token); @@ -105,4 +98,8 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, public void removeTicketFromCache(String serviceTicket) { cache.remove(serviceTicket); } + + public void setCache(Cache cache) { + this.cache = cache; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulator.java index ff1e863971..cab83d371f 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,41 +16,34 @@ package org.acegisecurity.providers.cas.populator; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.providers.cas.CasAuthoritiesPopulator; -import org.acegisecurity.userdetails.UserDetailsService; + import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.UserDetailsService; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; /** - * Populates the CAS authorities via an {@link UserDetailsService}. - * - *

- * The additional information (username, password, enabled status etc) an - * AuthenticationDao implementation provides about a - * User is ignored. Only the GrantedAuthoritys are - * relevant to this class. - *

+ * Populates the CAS authorities via an {@link UserDetailsService}.

The additional information (username, + * password, enabled status etc) an AuthenticationDao implementation provides about a User + * is ignored. Only the GrantedAuthoritys are relevant to this class.

* * @author Ben Alex * @version $Id$ */ -public class DaoCasAuthoritiesPopulator implements CasAuthoritiesPopulator, - InitializingBean { - //~ Instance fields ======================================================== +public class DaoCasAuthoritiesPopulator implements CasAuthoritiesPopulator, InitializingBean { + //~ Instance fields ================================================================================================ private UserDetailsService userDetailsService; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setUserDetailsService(UserDetailsService authenticationDao) { - this.userDetailsService = authenticationDao; - } - - public UserDetailsService getUserDetailsService() { - return userDetailsService; + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.userDetailsService, "An authenticationDao must be set"); } public UserDetails getUserDetails(String casUserId) @@ -58,7 +51,11 @@ public class DaoCasAuthoritiesPopulator implements CasAuthoritiesPopulator, return this.userDetailsService.loadUserByUsername(casUserId); } - public void afterPropertiesSet() throws Exception { - Assert.notNull(this.userDetailsService, "An authenticationDao must be set"); + public UserDetailsService getUserDetailsService() { + return userDetailsService; + } + + public void setUserDetailsService(UserDetailsService authenticationDao) { + this.userDetailsService = authenticationDao; } } diff --git a/core/src/main/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxy.java b/core/src/main/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxy.java index 9bcb4b6424..659a410770 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxy.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxy.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,28 +20,25 @@ import org.acegisecurity.providers.cas.ProxyUntrustedException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; import java.util.List; /** - * Accepts a proxied request from any other service. - * - *

- * Also accepts the request if there was no proxy (ie the user directly - * authenticated against this service). - *

+ * Accepts a proxied request from any other service.

Also accepts the request if there was no proxy (ie the user + * directly authenticated against this service).

* * @author Ben Alex * @version $Id$ */ public class AcceptAnyCasProxy implements CasProxyDecider { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AcceptAnyCasProxy.class); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void confirmProxyListTrusted(List proxyList) throws ProxyUntrustedException { diff --git a/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java b/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java index 74f26f0001..aa290371e6 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,41 +15,40 @@ package org.acegisecurity.providers.cas.proxy; -import java.util.List; - import org.acegisecurity.AcegiMessageSource; + import org.acegisecurity.providers.cas.CasProxyDecider; import org.acegisecurity.providers.cas.ProxyUntrustedException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.util.List; + /** - * Accepts proxied requests if the closest proxy is named in the - * validProxies list. - * - *

- * Also accepts the request if there was no proxy (ie the user directly - * authenticated against this service). - *

+ * Accepts proxied requests if the closest proxy is named in the validProxies list.

Also accepts the + * request if there was no proxy (ie the user directly authenticated against this service).

*/ -public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean, - MessageSourceAware { - //~ Static fields/initializers ============================================= +public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List validProxies; protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(this.validProxies, "A validProxies list must be set"); @@ -70,10 +69,8 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean, } if (!validProxies.contains(proxyList.get(0))) { - throw new ProxyUntrustedException(messages.getMessage( - "NamedCasProxyDecider.untrusted", - new Object[] {proxyList.get(0)}, - "Nearest proxy {0} is untrusted")); + throw new ProxyUntrustedException(messages.getMessage("NamedCasProxyDecider.untrusted", + new Object[] {proxyList.get(0)}, "Nearest proxy {0} is untrusted")); } } diff --git a/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java b/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java index e9fa3f5dc2..aa97e2a0c8 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,39 +15,39 @@ package org.acegisecurity.providers.cas.proxy; -import java.util.List; - import org.acegisecurity.AcegiMessageSource; + import org.acegisecurity.providers.cas.CasProxyDecider; import org.acegisecurity.providers.cas.ProxyUntrustedException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.util.List; + /** - * Accepts no proxied requests. - * - *

- * This class should be used if only service tickets wish to be accepted (ie no - * proxy tickets at all). - *

+ * Accepts no proxied requests.

This class should be used if only service tickets wish to be accepted (ie no + * proxy tickets at all).

*/ -public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware, - InitializingBean { - //~ Static fields/initializers ============================================= +public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RejectProxyTickets.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(this.messages, "A message source must be set"); @@ -63,12 +63,10 @@ public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware, } if (logger.isDebugEnabled()) { - logger.debug("Proxies are unacceptable; proxy list provided: " - + proxyList.toString()); + logger.debug("Proxies are unacceptable; proxy list provided: " + proxyList.toString()); } - throw new ProxyUntrustedException(messages.getMessage( - "RejectProxyTickets.reject", "Proxy tickets are rejected")); + throw new ProxyUntrustedException(messages.getMessage("RejectProxyTickets.reject", "Proxy tickets are rejected")); } public void setMessageSource(MessageSource messageSource) { diff --git a/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidator.java b/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidator.java index 3a8f5997c4..2f532bef0d 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidator.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,14 @@ package org.acegisecurity.providers.cas.ticketvalidator; import org.acegisecurity.providers.cas.TicketValidator; + import org.acegisecurity.ui.cas.ServiceProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; @@ -30,61 +33,18 @@ import org.springframework.util.Assert; * @author Ben Alex * @version $Id$ */ -public abstract class AbstractTicketValidator implements TicketValidator, - InitializingBean { - //~ Static fields/initializers ============================================= +public abstract class AbstractTicketValidator implements TicketValidator, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CasProxyTicketValidator.class); - - //~ Instance fields ======================================================== + + //~ Instance fields ================================================================================================ private ServiceProperties serviceProperties; private String casValidate; private String trustStore; - //~ Methods ================================================================ - - public void setCasValidate(String casValidate) { - this.casValidate = casValidate; - } - - /** - * Mandatory URL to CAS' proxy ticket valiation service. - * - *

- * This is usually something like - * https://www.mycompany.com/cas/proxyValidate. - *

- * - * @return the CAS proxy ticket validation URL - */ - public String getCasValidate() { - return casValidate; - } - - public void setServiceProperties(ServiceProperties serviceProperties) { - this.serviceProperties = serviceProperties; - } - - public ServiceProperties getServiceProperties() { - return serviceProperties; - } - - public void setTrustStore(String trustStore) { - this.trustStore = trustStore; - } - - /** - * Optional property which will be used to set the system property - * javax.net.ssl.trustStore. - * - * @return the javax.net.ssl.trustStore that will be set - * during bean initialization, or null to leave the - * system property unchanged - */ - public String getTrustStore() { - return trustStore; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(casValidate, "A casValidate URL must be set"); @@ -92,10 +52,46 @@ public abstract class AbstractTicketValidator implements TicketValidator, if ((trustStore != null) && (!"".equals(trustStore))) { if (logger.isDebugEnabled()) { - logger.debug("Setting system property 'javax.net.ssl.trustStore'" + - " to value [" + trustStore + "]"); + logger.debug("Setting system property 'javax.net.ssl.trustStore'" + " to value [" + trustStore + "]"); } + System.setProperty("javax.net.ssl.trustStore", trustStore); } } + + /** + * Mandatory URL to CAS' proxy ticket valiation service.

This is usually something like + * https://www.mycompany.com/cas/proxyValidate.

+ * + * @return the CAS proxy ticket validation URL + */ + public String getCasValidate() { + return casValidate; + } + + public ServiceProperties getServiceProperties() { + return serviceProperties; + } + + /** + * Optional property which will be used to set the system property javax.net.ssl.trustStore. + * + * @return the javax.net.ssl.trustStore that will be set during bean initialization, or + * null to leave the system property unchanged + */ + public String getTrustStore() { + return trustStore; + } + + public void setCasValidate(String casValidate) { + this.casValidate = casValidate; + } + + public void setServiceProperties(ServiceProperties serviceProperties) { + this.serviceProperties = serviceProperties; + } + + public void setTrustStore(String trustStore) { + this.trustStore = trustStore; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidator.java b/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidator.java index a0bf3255d5..c5348b74e1 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidator.java +++ b/core/src/main/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import edu.yale.its.tp.cas.client.ProxyTicketValidator; import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.cas.TicketResponse; import org.apache.commons.logging.Log; @@ -33,46 +34,15 @@ import org.apache.commons.logging.LogFactory; * @version $Id$ */ public class CasProxyTicketValidator extends AbstractTicketValidator { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(CasProxyTicketValidator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String proxyCallbackUrl; - //~ Methods ================================================================ - - public void setProxyCallbackUrl(String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - /** - * Optional callback URL to obtain a proxy-granting ticket from CAS. - * - *

- * This callback URL belongs to the Acegi Security System for Spring - * secured application. We suggest you use CAS' - * ProxyTicketReceptor servlet to receive this callback and - * manage the proxy-granting ticket list. The callback URL is usually - * something like - * https://www.mycompany.com/application/casProxy/receptor. - *

- * - *

- * If left null, the CasAuthenticationToken will - * not have a proxy granting ticket IOU and there will be no - * proxy-granting ticket callback. Accordingly, the Acegi Securty System - * for Spring secured application will be unable to obtain a proxy ticket - * to call another CAS-secured service on behalf of the user. This is not - * really an issue for most applications. - *

- * - * @return the proxy callback URL, or null if not used - */ - public String getProxyCallbackUrl() { - return proxyCallbackUrl; - } + //~ Methods ======================================================================================================== public TicketResponse confirmTicketValid(String serviceTicket) throws AuthenticationException { @@ -88,8 +58,7 @@ public class CasProxyTicketValidator extends AbstractTicketValidator { "The current CAS ProxyTicketValidator does not support the 'renew' property. The ticket cannot be validated as having been issued by a 'renew' authentication. It is expected this will be corrected in a future version of CAS' ProxyTicketValidator."); } - if ((this.proxyCallbackUrl != null) - && (!"".equals(this.proxyCallbackUrl))) { + if ((this.proxyCallbackUrl != null) && (!"".equals(this.proxyCallbackUrl))) { pv.setProxyCallbackUrl(proxyCallbackUrl); } @@ -97,15 +66,33 @@ public class CasProxyTicketValidator extends AbstractTicketValidator { } /** - * Perform the actual remote invocation. Protected to enable replacement - * during tests. + * Optional callback URL to obtain a proxy-granting ticket from CAS.

This callback URL belongs to the + * Acegi Security System for Spring secured application. We suggest you use CAS' ProxyTicketReceptor + * servlet to receive this callback and manage the proxy-granting ticket list. The callback URL is usually + * something like https://www.mycompany.com/application/casProxy/receptor.

+ *

If left null, the CasAuthenticationToken will not have a proxy granting + * ticket IOU and there will be no proxy-granting ticket callback. Accordingly, the Acegi Securty System for + * Spring secured application will be unable to obtain a proxy ticket to call another CAS-secured service on + * behalf of the user. This is not really an issue for most applications.

+ * + * @return the proxy callback URL, or null if not used + */ + public String getProxyCallbackUrl() { + return proxyCallbackUrl; + } + + public void setProxyCallbackUrl(String proxyCallbackUrl) { + this.proxyCallbackUrl = proxyCallbackUrl; + } + + /** + * Perform the actual remote invocation. Protected to enable replacement during tests. * * @param pv the populated ProxyTicketValidator * * @return the TicketResponse * - * @throws AuthenticationServiceException - * ifProxyTicketValidator internally fails + * @throws AuthenticationServiceException ifProxyTicketValidator internally fails * @throws BadCredentialsException DOCUMENT ME! */ protected TicketResponse validateNow(ProxyTicketValidator pv) @@ -113,16 +100,13 @@ public class CasProxyTicketValidator extends AbstractTicketValidator { try { pv.validate(); } catch (Exception internalProxyTicketValidatorProblem) { - throw new AuthenticationServiceException(internalProxyTicketValidatorProblem - .getMessage()); + throw new AuthenticationServiceException(internalProxyTicketValidatorProblem.getMessage()); } if (!pv.isAuthenticationSuccesful()) { - throw new BadCredentialsException(pv.getErrorCode() + ": " - + pv.getErrorMessage()); + throw new BadCredentialsException(pv.getErrorCode() + ": " + pv.getErrorMessage()); } - return new TicketResponse(pv.getUser(), pv.getProxyList(), - pv.getPgtIou()); + return new TicketResponse(pv.getUser(), pv.getProxyList(), pv.getPgtIou()); } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java index e7e2869120..11772b5762 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,90 +19,74 @@ import org.acegisecurity.AccountExpiredException; import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; +import org.acegisecurity.BadCredentialsException; import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.DisabledException; import org.acegisecurity.LockedException; -import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.dao.cache.NullUserCache; + import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; /** - * A base {@link AuthenticationProvider} that allows subclasses to override and - * work with {@link org.acegisecurity.userdetails.UserDetails} objects. The class is - * designed to respond to {@link UsernamePasswordAuthenticationToken} - * authentication requests. - * - *

- * Upon successful validation, a - * UsernamePasswordAuthenticationToken will be created and - * returned to the caller. The token will include as its principal either a - * String representation of the username, or the {@link - * UserDetails} that was returned from the authentication repository. Using - * String is appropriate if a container adapter is being used, as - * it expects String representations of the username. Using - * UserDetails is appropriate if you require access to additional - * properties of the authenticated user, such as email addresses, - * human-friendly names etc. As container adapters are not recommended to be - * used, and UserDetails implementations provide additional - * flexibility, by default a UserDetails is returned. To override - * this default, set the {@link #setForcePrincipalAsString} to - * true. - *

- * - *

- * Caching is handled via the UserDetails object being placed in - * the {@link UserCache}. This ensures that subsequent requests with the same - * username can be validated without needing to query the {@link - * UserDetailsService}. It should be noted that if a user appears to present an - * incorrect password, the {@link UserDetailsService} will be queried to - * confirm the most up-to-date password was used for comparison. - *

+ * A base {@link AuthenticationProvider} that allows subclasses to override and work with {@link + * org.acegisecurity.userdetails.UserDetails} objects. The class is designed to respond to {@link + * UsernamePasswordAuthenticationToken} authentication requests.

Upon successful validation, a + * UsernamePasswordAuthenticationToken will be created and returned to the caller. The token will include + * as its principal either a String representation of the username, or the {@link UserDetails} that was + * returned from the authentication repository. Using String is appropriate if a container adapter is + * being used, as it expects String representations of the username. Using UserDetails is + * appropriate if you require access to additional properties of the authenticated user, such as email addresses, + * human-friendly names etc. As container adapters are not recommended to be used, and UserDetails + * implementations provide additional flexibility, by default a UserDetails is returned. To override this + * default, set the {@link #setForcePrincipalAsString} to true.

+ *

Caching is handled via the UserDetails object being placed in the {@link UserCache}. This + * ensures that subsequent requests with the same username can be validated without needing to query the {@link + * UserDetailsService}. It should be noted that if a user appears to present an incorrect password, the {@link + * UserDetailsService} will be queried to confirm the most up-to-date password was used for comparison.

* * @author Ben Alex * @version $Id$ */ -public abstract class AbstractUserDetailsAuthenticationProvider - implements AuthenticationProvider, InitializingBean, MessageSourceAware { - //~ Instance fields ======================================================== +public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean, + MessageSourceAware { + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private UserCache userCache = new NullUserCache(); private boolean forcePrincipalAsString = false; protected boolean hideUserNotFoundExceptions = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Allows subclasses to perform any additional checks of a returned (or - * cached) UserDetails for a given authentication request. - * Generally a subclass will at least compare the {@link - * Authentication#getCredentials()} with a {@link - * UserDetails#getPassword()}. If custom logic is needed to compare - * additional properties of UserDetails and/or - * UsernamePasswordAuthenticationToken, these should also - * appear in this method. + * Allows subclasses to perform any additional checks of a returned (or cached) UserDetails + * for a given authentication request. Generally a subclass will at least compare the {@link + * Authentication#getCredentials()} with a {@link UserDetails#getPassword()}. If custom logic is needed to compare + * additional properties of UserDetails and/or UsernamePasswordAuthenticationToken, + * these should also appear in this method. * - * @param userDetails as retrieved from the {@link #retrieveUser(String, - * UsernamePasswordAuthenticationToken)} or UserCache + * @param userDetails as retrieved from the {@link #retrieveUser(String, UsernamePasswordAuthenticationToken)} or + * UserCache * @param authentication the current request that needs to be authenticated * - * @throws AuthenticationException AuthenticationException if the - * credentials could not be validated (generally a - * BadCredentialsException, an - * AuthenticationServiceException) + * @throws AuthenticationException AuthenticationException if the credentials could not be validated (generally a + * BadCredentialsException, an AuthenticationServiceException) */ - protected abstract void additionalAuthenticationChecks( - UserDetails userDetails, + protected abstract void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException; @@ -114,15 +98,12 @@ public abstract class AbstractUserDetailsAuthenticationProvider public Authentication authenticate(Authentication authentication) throws AuthenticationException { - Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, - authentication, - messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.onlySupports", + Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, + messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports", "Only UsernamePasswordAuthenticationToken is supported")); // Determine username - String username = (authentication.getPrincipal() == null) - ? "NONE_PROVIDED" : authentication.getName(); + String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName(); boolean cacheWasUsed = true; UserDetails user = this.userCache.getUserFromCache(username); @@ -131,59 +112,48 @@ public abstract class AbstractUserDetailsAuthenticationProvider cacheWasUsed = false; try { - user = retrieveUser(username, - (UsernamePasswordAuthenticationToken) authentication); - + user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); } catch (UsernameNotFoundException notFound) { if (hideUserNotFoundExceptions) { throw new BadCredentialsException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.badCredentials", - "Bad credentials")); + "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); } else { throw notFound; } } - Assert.notNull(user, - "retrieveUser returned null - a violation of the interface contract"); + Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract"); } if (!user.isAccountNonLocked()) { - throw new LockedException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.locked", + throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked", "User account is locked")); } if (!user.isEnabled()) { - throw new DisabledException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.disabled", + throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled")); } if (!user.isAccountNonExpired()) { - throw new AccountExpiredException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.expired", + throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", "User account has expired")); } // This check must come here, as we don't want to tell users // about account status unless they presented the correct credentials try { - additionalAuthenticationChecks(user, - (UsernamePasswordAuthenticationToken) authentication); + additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); } catch (AuthenticationException exception) { // There was a problem, so try again after checking we're using latest data cacheWasUsed = false; - user = retrieveUser(username, - (UsernamePasswordAuthenticationToken) authentication); - additionalAuthenticationChecks(user, - (UsernamePasswordAuthenticationToken) authentication); + user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); + additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); } if (!user.isCredentialsNonExpired()) { throw new CredentialsExpiredException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.credentialsExpired", - "User credentials have expired")); + "AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired")); } if (!cacheWasUsed) { @@ -196,33 +166,23 @@ public abstract class AbstractUserDetailsAuthenticationProvider principalToReturn = user.getUsername(); } - return createSuccessAuthentication(principalToReturn, authentication, - user); + return createSuccessAuthentication(principalToReturn, authentication, user); } /** - * Creates a successful {@link Authentication} object. - * - *

- * Protected so subclasses can override. - *

- * - *

- * Subclasses will usually store the original credentials the user supplied - * (not salted or encoded passwords) in the returned - * Authentication object. - *

+ * Creates a successful {@link Authentication} object.

Protected so subclasses can override.

+ *

Subclasses will usually store the original credentials the user supplied (not salted or encoded + * passwords) in the returned Authentication object.

* - * @param principal that should be the principal in the returned object - * (defined by the {@link #isForcePrincipalAsString()} method) - * @param authentication that was presented to the - * provider for validation + * @param principal that should be the principal in the returned object (defined by the {@link + * #isForcePrincipalAsString()} method) + * @param authentication that was presented to the provider for validation * @param user that was loaded by the implementation * * @return the successful authentication token */ - protected Authentication createSuccessAuthentication(Object principal, - Authentication authentication, UserDetails user) { + protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, + UserDetails user) { // Ensure we return the original credentials the user supplied, // so subsequent attempts are successful even with encoded passwords. // Also ensure we return the original getDetails(), so that future @@ -244,61 +204,60 @@ public abstract class AbstractUserDetailsAuthenticationProvider return forcePrincipalAsString; } + public boolean isHideUserNotFoundExceptions() { + return hideUserNotFoundExceptions; + } + /** - * Allows subclasses to actually retrieve the UserDetails from - * an implementation-specific location, with the option of throwing an - * AuthenticationException immediately if the presented - * credentials are incorrect (this is especially useful if it is necessary - * to bind to a resource as the user in order to obtain or generate a - * UserDetails). - * - *

- * Subclasses are not required to perform any caching, as the - * AbstractUserDetailsAuthenticationProvider will by default - * cache the UserDetails. The caching of - * UserDetails does present additional complexity as this - * means subsequent requests that rely on the cache will need to still - * have their credentials validated, even if the correctness of - * credentials was assured by subclasses adopting a binding-based strategy - * in this method. Accordingly it is important that subclasses either - * disable caching (if they want to ensure that this method is the only - * method that is capable of authenticating a request, as no - * UserDetails will ever be cached) or ensure subclasses - * implement {@link #additionalAuthenticationChecks(UserDetails, - * UsernamePasswordAuthenticationToken)} to compare the credentials of a - * cached UserDetails with subsequent authentication - * requests. - *

- * - *

- * Most of the time subclasses will not perform credentials inspection in - * this method, instead performing it in {@link - * #additionalAuthenticationChecks(UserDetails, - * UsernamePasswordAuthenticationToken)} so that code related to - * credentials validation need not be duplicated across two methods. - *

+ * Allows subclasses to actually retrieve the UserDetails from an implementation-specific + * location, with the option of throwing an AuthenticationException immediately if the presented + * credentials are incorrect (this is especially useful if it is necessary to bind to a resource as the user in + * order to obtain or generate a UserDetails).

Subclasses are not required to perform any + * caching, as the AbstractUserDetailsAuthenticationProvider will by default cache the + * UserDetails. The caching of UserDetails does present additional complexity as this + * means subsequent requests that rely on the cache will need to still have their credentials validated, even if + * the correctness of credentials was assured by subclasses adopting a binding-based strategy in this method. + * Accordingly it is important that subclasses either disable caching (if they want to ensure that this method is + * the only method that is capable of authenticating a request, as no UserDetails will ever be + * cached) or ensure subclasses implement {@link #additionalAuthenticationChecks(UserDetails, + * UsernamePasswordAuthenticationToken)} to compare the credentials of a cached UserDetails with + * subsequent authentication requests.

+ *

Most of the time subclasses will not perform credentials inspection in this method, instead + * performing it in {@link #additionalAuthenticationChecks(UserDetails, UsernamePasswordAuthenticationToken)} so + * that code related to credentials validation need not be duplicated across two methods.

* * @param username The username to retrieve - * @param authentication The authentication request, which subclasses - * may need to perform a binding-based retrieval of the - * UserDetails + * @param authentication The authentication request, which subclasses may need to perform a binding-based + * retrieval of the UserDetails * - * @return the user information (never null - instead an - * exception should the thrown) + * @return the user information (never null - instead an exception should the thrown) * - * @throws AuthenticationException if the credentials could not be - * validated (generally a BadCredentialsException, an - * AuthenticationServiceException or + * @throws AuthenticationException if the credentials could not be validated (generally a + * BadCredentialsException, an AuthenticationServiceException or * UsernameNotFoundException) */ - protected abstract UserDetails retrieveUser(String username, - UsernamePasswordAuthenticationToken authentication) + protected abstract UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException; public void setForcePrincipalAsString(boolean forcePrincipalAsString) { this.forcePrincipalAsString = forcePrincipalAsString; } + /** + * By default the AbstractUserDetailsAuthenticationProvider throws a + * BadCredentialsException if a username is not found or the password is incorrect. Setting this + * property to false will cause UsernameNotFoundExceptions to be thrown instead for the + * former. Note this is considered less secure than throwing BadCredentialsException for both + * exceptions. + * + * @param hideUserNotFoundExceptions set to false if you wish UsernameNotFoundExceptions + * to be thrown instead of the non-specific BadCredentialsException (defaults to + * true) + */ + public void setHideUserNotFoundExceptions(boolean hideUserNotFoundExceptions) { + this.hideUserNotFoundExceptions = hideUserNotFoundExceptions; + } + public void setMessageSource(MessageSource messageSource) { this.messages = new MessageSourceAccessor(messageSource); } @@ -310,28 +269,4 @@ public abstract class AbstractUserDetailsAuthenticationProvider public boolean supports(Class authentication) { return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); } - - public boolean isHideUserNotFoundExceptions() { - return hideUserNotFoundExceptions; - } - - /** - * By default the AbstractUserDetailsAuthenticationProvider - * throws a BadCredentialsException if a username is - * not found or the password is incorrect. Setting this property to - * false will cause - * UsernameNotFoundExceptions to be thrown instead for - * the former. Note this is considered less secure than throwing - * BadCredentialsException for both exceptions. - * - * @param hideUserNotFoundExceptions set to false if you - * wish UsernameNotFoundExceptions to be thrown - * instead of the non-specific - * BadCredentialsException (defaults to - * true) - */ - public void setHideUserNotFoundExceptions( - boolean hideUserNotFoundExceptions) { - this.hideUserNotFoundExceptions = hideUserNotFoundExceptions; - } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java index 9654b6912a..e7f7d9f837 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -33,21 +33,19 @@ import org.springframework.util.Assert; /** - * An {@link AuthenticationProvider} implementation that retrieves user details - * from an {@link UserDetailsService}. + * An {@link AuthenticationProvider} implementation that retrieves user details from an {@link UserDetailsService}. * * @author Ben Alex * @version $Id$ */ -public class DaoAuthenticationProvider - extends AbstractUserDetailsAuthenticationProvider { - //~ Instance fields ======================================================== +public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { + //~ Instance fields ================================================================================================ private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); private SaltSource saltSource; private UserDetailsService userDetailsService; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) @@ -58,17 +56,14 @@ public class DaoAuthenticationProvider salt = this.saltSource.getSalt(userDetails); } - if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), - authentication.getCredentials().toString(), salt)) { + if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), authentication.getCredentials().toString(), salt)) { throw new BadCredentialsException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.badCredentials", - "Bad credentials"), userDetails); + "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails); } } protected void doAfterPropertiesSet() throws Exception { - Assert.notNull(this.userDetailsService, - "An Authentication DAO must be set"); + Assert.notNull(this.userDetailsService, "An Authentication DAO must be set"); } public PasswordEncoder getPasswordEncoder() { @@ -83,17 +78,14 @@ public class DaoAuthenticationProvider return userDetailsService; } - protected final UserDetails retrieveUser(String username, - UsernamePasswordAuthenticationToken authentication) + protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { UserDetails loadedUser; try { - loadedUser = this.getUserDetailsService() - .loadUserByUsername(username); + loadedUser = this.getUserDetailsService().loadUserByUsername(username); } catch (DataAccessException repositoryProblem) { - throw new AuthenticationServiceException(repositoryProblem - .getMessage(), repositoryProblem); + throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem); } if (loadedUser == null) { @@ -105,9 +97,8 @@ public class DaoAuthenticationProvider } /** - * Sets the PasswordEncoder instance to be used to encode and validate - * passwords. If not set, {@link PlaintextPasswordEncoder} will be used by - * default. + * Sets the PasswordEncoder instance to be used to encode and validate passwords. If not set, {@link + * PlaintextPasswordEncoder} will be used by default. * * @param passwordEncoder The passwordEncoder to use */ @@ -116,12 +107,11 @@ public class DaoAuthenticationProvider } /** - * The source of salts to use when decoding passwords. null is - * a valid value, meaning the DaoAuthenticationProvider will - * present null to the relevant PasswordEncoder. + * The source of salts to use when decoding passwords. null is a valid value, meaning the + * DaoAuthenticationProvider will present null to the relevant + * PasswordEncoder. * - * @param saltSource to use when attempting to decode passwords via the - * PasswordEncoder + * @param saltSource to use when attempting to decode passwords via the PasswordEncoder */ public void setSaltSource(SaltSource saltSource) { this.saltSource = saltSource; diff --git a/core/src/main/java/org/acegisecurity/providers/dao/SaltSource.java b/core/src/main/java/org/acegisecurity/providers/dao/SaltSource.java index 07af4215ce..a7f1aa6a8e 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/SaltSource.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/SaltSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public interface SaltSource { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Returns the salt to use for the indicated user. diff --git a/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java index 141e297dce..4b3ee4e4a7 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,39 +34,31 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public interface UserCache { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains a {@link UserDetails} from the cache. * - * @param username the {@link User#getUsername()} used to place the user in - * the cache + * @param username the {@link User#getUsername()} used to place the user in the cache * - * @return the populated UserDetails or null if - * the user could not be found or if the cache entry has expired + * @return the populated UserDetails or null if the user could not be found or if the + * cache entry has expired */ public UserDetails getUserFromCache(String username); /** - * Places a {@link UserDetails} in the cache. The username is - * the key used to subsequently retrieve the UserDetails. + * Places a {@link UserDetails} in the cache. The username is the key used to subsequently + * retrieve the UserDetails. * - * @param user the fully populated UserDetails to place in the - * cache + * @param user the fully populated UserDetails to place in the cache */ public void putUserInCache(UserDetails user); /** - * Removes the specified user from the cache. The username is - * the key used to remove the user. If the user is not found, the method - * should simply return (not thrown an exception). - * - *

- * Some cache implementations may not support eviction from the cache, in - * which case they should provide appropriate behaviour to alter the user - * in either its documentation, via an exception, or through a log - * message. - *

+ * Removes the specified user from the cache. The username is the key used to remove the user. + * If the user is not found, the method should simply return (not thrown an exception).

Some cache + * implementations may not support eviction from the cache, in which case they should provide appropriate + * behaviour to alter the user in either its documentation, via an exception, or through a log message.

* * @param username to be evicted from the cache */ diff --git a/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java index 08c67d3d19..bfbf162e38 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,19 +15,21 @@ package org.acegisecurity.providers.dao.cache; -import org.acegisecurity.providers.dao.UserCache; -import org.acegisecurity.userdetails.UserDetails; - import net.sf.ehcache.Cache; import net.sf.ehcache.CacheException; import net.sf.ehcache.Element; +import org.acegisecurity.providers.dao.UserCache; + +import org.acegisecurity.userdetails.UserDetails; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataRetrievalFailureException; + import org.springframework.util.Assert; @@ -39,18 +41,18 @@ import org.springframework.util.Assert; * @version $Id$ */ public class EhCacheBasedUserCache implements UserCache, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Cache cache; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setCache(Cache cache) { - this.cache = cache; + public void afterPropertiesSet() throws Exception { + Assert.notNull(cache, "cache mandatory"); } public Cache getCache() { @@ -63,13 +65,11 @@ public class EhCacheBasedUserCache implements UserCache, InitializingBean { try { element = cache.get(username); } catch (CacheException cacheException) { - throw new DataRetrievalFailureException("Cache failure: " - + cacheException.getMessage()); + throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage()); } if (logger.isDebugEnabled()) { - logger.debug("Cache hit: " + (element != null) + "; username: " - + username); + logger.debug("Cache hit: " + (element != null) + "; username: " + username); } if (element == null) { @@ -79,10 +79,6 @@ public class EhCacheBasedUserCache implements UserCache, InitializingBean { } } - public void afterPropertiesSet() throws Exception { - Assert.notNull(cache, "cache mandatory"); - } - public void putUserInCache(UserDetails user) { Element element = new Element(user.getUsername(), user); @@ -104,4 +100,8 @@ public class EhCacheBasedUserCache implements UserCache, InitializingBean { public void removeUserFromCache(String username) { cache.remove(username); } + + public void setCache(Cache cache) { + this.cache = cache; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java index 8c6fa2b2c6..71d09e1541 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.providers.dao.cache; import org.acegisecurity.providers.dao.UserCache; + import org.acegisecurity.userdetails.UserDetails; @@ -26,7 +27,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class NullUserCache implements UserCache { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public UserDetails getUserFromCache(String username) { return null; diff --git a/core/src/main/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSource.java b/core/src/main/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSource.java index d6c87afcc9..48bd7b5a95 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSource.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSource.java @@ -27,44 +27,32 @@ import java.lang.reflect.Method; /** - * Obtains a salt from a specified property of the {@link User} object. - * - *

- * This allows you to subclass User and provide an additional bean - * getter for a salt. You should use a synthetic value that does not change, - * such as a database primary key. Do not use username if it is - * likely to change. - *

+ * Obtains a salt from a specified property of the {@link User} object.

This allows you to subclass + * User and provide an additional bean getter for a salt. You should use a synthetic value that does not + * change, such as a database primary key. Do not use username if it is likely to change.

* * @author Ben Alex * @version $Id$ */ public class ReflectionSaltSource implements SaltSource, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String userPropertyToUse; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - if ((this.getUserPropertyToUse() == null) - || "".equals(this.getUserPropertyToUse())) { - throw new IllegalArgumentException( - "A userPropertyToUse must be set"); + if ((this.getUserPropertyToUse() == null) || "".equals(this.getUserPropertyToUse())) { + throw new IllegalArgumentException("A userPropertyToUse must be set"); } } /** - * Performs reflection on the passed User to obtain the salt. - * - *

- * The property identified by userPropertyToUse must be - * available from the passed User object. If it is not - * available, an {@link AuthenticationServiceException} will be thrown. - *

+ * Performs reflection on the passed User to obtain the salt.

The property identified by + * userPropertyToUse must be available from the passed User object. If it is not + * available, an {@link AuthenticationServiceException} will be thrown.

* - * @param user which contains the method identified by - * userPropertyToUse + * @param user which contains the method identified by userPropertyToUse * * @return the result of invoking user.userPropertyToUse() * @@ -72,14 +60,11 @@ public class ReflectionSaltSource implements SaltSource, InitializingBean { */ public Object getSalt(UserDetails user) { try { - Method reflectionMethod = user.getClass() - .getMethod(this.userPropertyToUse, - new Class[] {}); + Method reflectionMethod = user.getClass().getMethod(this.userPropertyToUse, new Class[] {}); return reflectionMethod.invoke(user, new Object[] {}); } catch (Exception exception) { - throw new AuthenticationServiceException(exception.getMessage(), - exception); + throw new AuthenticationServiceException(exception.getMessage(), exception); } } @@ -88,12 +73,11 @@ public class ReflectionSaltSource implements SaltSource, InitializingBean { } /** - * The method name to call to obtain the salt. If your - * UserDetails contains a UserDetails.getSalt() - * method, you should set this property to getSalt. + * The method name to call to obtain the salt. If your UserDetails contains a + * UserDetails.getSalt() method, you should set this property to getSalt. * - * @param userPropertyToUse the name of the getter to call to obtain - * the salt from the UserDetails + * @param userPropertyToUse the name of the getter to call to obtain the salt from the + * UserDetails */ public void setUserPropertyToUse(String userPropertyToUse) { this.userPropertyToUse = userPropertyToUse; diff --git a/core/src/main/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSource.java b/core/src/main/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSource.java index 919104d17a..f9f96ec924 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSource.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,46 +16,42 @@ package org.acegisecurity.providers.dao.salt; import org.acegisecurity.providers.dao.SaltSource; + import org.acegisecurity.userdetails.UserDetails; import org.springframework.beans.factory.InitializingBean; /** - * Uses a static system-wide String as the salt. - * - *

- * Does not supply a different salt for each {@link User}. This means users - * sharing the same password will still have the same digested password. Of - * benefit is the digested passwords will at least be more protected than if - * stored without any salt. - *

+ * Uses a static system-wide String as the salt.

Does not supply a different salt for each {@link + * User}. This means users sharing the same password will still have the same digested password. Of benefit is the + * digested passwords will at least be more protected than if stored without any salt.

* * @author Ben Alex * @version $Id$ */ public class SystemWideSaltSource implements SaltSource, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String systemWideSalt; - //~ Methods ================================================================ - - public Object getSalt(UserDetails user) { - return this.systemWideSalt; - } - - public void setSystemWideSalt(String systemWideSalt) { - this.systemWideSalt = systemWideSalt; - } - - public String getSystemWideSalt() { - return this.systemWideSalt; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { if ((this.systemWideSalt == null) || "".equals(this.systemWideSalt)) { throw new IllegalArgumentException("A systemWideSalt must be set"); } } + + public Object getSalt(UserDetails user) { + return this.systemWideSalt; + } + + public String getSystemWideSalt() { + return this.systemWideSalt; + } + + public void setSystemWideSalt(String systemWideSalt) { + this.systemWideSalt = systemWideSalt; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java index ca769efb54..632c4db86b 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/BaseDigestPasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,32 +16,29 @@ package org.acegisecurity.providers.encoding; /** - *

- * Convenience base for digest password encoders. - *

+ *

Convenience base for digest password encoders.

* * @author colin sampaleanu * @version $Id$ */ public abstract class BaseDigestPasswordEncoder extends BasePasswordEncoder { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean encodeHashAsBase64 = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public boolean getEncodeHashAsBase64() { + return encodeHashAsBase64; + } /** - * The encoded password is normally returned as Hex (32 char) version of - * the hash bytes. Setting this property to true will cause the encoded - * pass to be returned as Base64 text, which will consume 24 characters. + * The encoded password is normally returned as Hex (32 char) version of the hash bytes. Setting this + * property to true will cause the encoded pass to be returned as Base64 text, which will consume 24 characters. * * @param encodeHashAsBase64 set to true for Base64 output */ public void setEncodeHashAsBase64(boolean encodeHashAsBase64) { this.encodeHashAsBase64 = encodeHashAsBase64; } - - public boolean getEncodeHashAsBase64() { - return encodeHashAsBase64; - } } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/BasePasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/BasePasswordEncoder.java index d78027dc98..400ce01830 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/BasePasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/BasePasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,40 +16,29 @@ package org.acegisecurity.providers.encoding; /** - *

- * Convenience base for all password encoders. - *

+ *

Convenience base for all password encoders.

* * @author Ben Alex * @version $Id$ */ public abstract class BasePasswordEncoder implements PasswordEncoder { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Used by subclasses to extract the password and salt from a merged - * String created using {@link - * #mergePasswordAndSalt(String,Object,boolean)}. - * - *

- * The first element in the returned array is the password. The second - * element is the salt. The salt array element will always be present, - * even if no salt was found in the mergedPasswordSalt - * argument. - *

+ * Used by subclasses to extract the password and salt from a merged String created using + * {@link #mergePasswordAndSalt(String,Object,boolean)}.

The first element in the returned array is the + * password. The second element is the salt. The salt array element will always be present, even if no salt was + * found in the mergedPasswordSalt argument.

* - * @param mergedPasswordSalt as generated by - * mergePasswordAndSalt + * @param mergedPasswordSalt as generated by mergePasswordAndSalt * - * @return an array, in which the first element is the password and the - * second the salt + * @return an array, in which the first element is the password and the second the salt * * @throws IllegalArgumentException if mergedPasswordSalt is null or empty. */ protected String[] demergePasswordAndSalt(String mergedPasswordSalt) { if ((mergedPasswordSalt == null) || "".equals(mergedPasswordSalt)) { - throw new IllegalArgumentException( - "Cannot pass a null or empty String"); + throw new IllegalArgumentException("Cannot pass a null or empty String"); } String password = mergedPasswordSalt; @@ -57,10 +46,8 @@ public abstract class BasePasswordEncoder implements PasswordEncoder { int saltBegins = mergedPasswordSalt.lastIndexOf("{"); - if ((saltBegins != -1) - && ((saltBegins + 1) < mergedPasswordSalt.length())) { - salt = mergedPasswordSalt.substring(saltBegins + 1, - mergedPasswordSalt.length() - 1); + if ((saltBegins != -1) && ((saltBegins + 1) < mergedPasswordSalt.length())) { + salt = mergedPasswordSalt.substring(saltBegins + 1, mergedPasswordSalt.length() - 1); password = mergedPasswordSalt.substring(0, saltBegins); } @@ -68,21 +55,12 @@ public abstract class BasePasswordEncoder implements PasswordEncoder { } /** - * Used by subclasses to generate a merged password and salt - * String. - * - *

- * The generated password will be in the form of - * password{salt}. - *

- * - *

- * A null can be passed to either method, and will be handled - * correctly. If the salt is null or empty, the - * resulting generated password will simply be the passed - * password. The toString method of the - * salt will be used to represent the salt. - *

+ * Used by subclasses to generate a merged password and salt String.

The generated password + * will be in the form of password{salt}.

+ *

A null can be passed to either method, and will be handled correctly. If the + * salt is null or empty, the resulting generated password will simply be the passed + * password. The toString method of the salt will be used to represent the + * salt.

* * @param password the password to be used (can be null) * @param salt the salt to be used (can be null) @@ -92,17 +70,14 @@ public abstract class BasePasswordEncoder implements PasswordEncoder { * * @throws IllegalArgumentException if the salt contains '{' or '}' characters. */ - protected String mergePasswordAndSalt(String password, Object salt, - boolean strict) { + protected String mergePasswordAndSalt(String password, Object salt, boolean strict) { if (password == null) { password = ""; } if (strict && (salt != null)) { - if ((salt.toString().lastIndexOf("{") != -1) - || (salt.toString().lastIndexOf("}") != -1)) { - throw new IllegalArgumentException( - "Cannot use { or } in salt.toString()"); + if ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1)) { + throw new IllegalArgumentException("Cannot use { or } in salt.toString()"); } } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java index 399e8ddce7..3da97c7324 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/Md5PasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,33 +20,17 @@ import org.apache.commons.codec.digest.DigestUtils; /** - *

- * MD5 implementation of PasswordEncoder. - *

- * - *

- * If a null password is presented, it will be treated as an empty - * String ("") password. - *

- * - *

- * As MD5 is a one-way hash, the salt can contain any characters. - *

+ *

MD5 implementation of PasswordEncoder.

+ *

If a null password is presented, it will be treated as an empty String ("") + * password.

+ *

As MD5 is a one-way hash, the salt can contain any characters.

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ -public class Md5PasswordEncoder extends BaseDigestPasswordEncoder - implements PasswordEncoder { - //~ Methods ================================================================ - - public boolean isPasswordValid(String encPass, String rawPass, Object salt) { - String pass1 = "" + encPass; - String pass2 = encodePassword(rawPass, salt); - - return pass1.equals(pass2); - } +public class Md5PasswordEncoder extends BaseDigestPasswordEncoder implements PasswordEncoder { + //~ Methods ======================================================================================================== public String encodePassword(String rawPass, Object salt) { String saltedPass = mergePasswordAndSalt(rawPass, salt, false); @@ -59,4 +43,11 @@ public class Md5PasswordEncoder extends BaseDigestPasswordEncoder return new String(encoded); } + + public boolean isPasswordValid(String encPass, String rawPass, Object salt) { + String pass1 = "" + encPass; + String pass2 = encodePassword(rawPass, salt); + + return pass1.equals(pass2); + } } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java index 391709908e..0ef90a58d7 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/PasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,74 +27,50 @@ import org.springframework.dao.DataAccessException; * @version $Id$ */ public interface PasswordEncoder { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - *

- * Validates a specified "raw" password against an encoded password. - *

- * - *

- * The encoded password should have previously been generated by {@link - * #encodePassword(String, Object)}. This method will encode the - * rawPass (using the optional salt), and then - * compared it with the presented encPass. - *

- * - *

- * For a discussion of salts, please refer to {@link - * #encodePassword(String, Object)}. - *

- * - * @param encPass a pre-encoded password - * @param rawPass a raw password to encode and compare against the - * pre-encoded password - * @param salt optionally used by the implementation to "salt" the raw - * password before encoding. A null value is legal. - * - * @return DOCUMENT ME! - */ - public boolean isPasswordValid(String encPass, String rawPass, Object salt) - throws DataAccessException; - - /** - *

- * Encodes the specified raw password with an implementation specific - * algorithm. - *

- * - *

- * This will generally be a one-way message digest such as MD5 or SHA, but - * may also be a plaintext variant which does no encoding at all, but - * rather returns the same password it was fed. The latter is useful to - * plug in when the original password must be stored as-is. - *

- * - *

- * The specified salt will potentially be used by the implementation to - * "salt" the initial value before encoding. A salt is usually a - * user-specific value which is added to the password before the digest is - * computed. This means that computation of digests for common dictionary - * words will be different than those in the backend store, because the - * dictionary word digests will not reflect the addition of the salt. If a - * per-user salt is used (rather than a system-wide salt), it also means - * users with the same password will have different digest encoded - * passwords in the backend store. - *

- * - *

- * If a salt value is provided, the same salt value must be use when - * calling the {@link #isPasswordValid(String, String, Object)} method. - * Note that a specific implementation may choose to ignore the salt value - * (via null), or provide its own. - *

+ *

Encodes the specified raw password with an implementation specific algorithm.

+ *

This will generally be a one-way message digest such as MD5 or SHA, but may also be a plaintext + * variant which does no encoding at all, but rather returns the same password it was fed. The latter is useful to + * plug in when the original password must be stored as-is.

+ *

The specified salt will potentially be used by the implementation to "salt" the initial value before + * encoding. A salt is usually a user-specific value which is added to the password before the digest is computed. + * This means that computation of digests for common dictionary words will be different than those in the backend + * store, because the dictionary word digests will not reflect the addition of the salt. If a per-user salt is + * used (rather than a system-wide salt), it also means users with the same password will have different digest + * encoded passwords in the backend store.

+ *

If a salt value is provided, the same salt value must be use when calling the {@link + * #isPasswordValid(String, String, Object)} method. Note that a specific implementation may choose to ignore the + * salt value (via null), or provide its own.

* * @param rawPass the password to encode - * @param salt optionally used by the implementation to "salt" the raw - * password before encoding. A null value is legal. + * @param salt optionally used by the implementation to "salt" the raw password before encoding. A + * null value is legal. * * @return DOCUMENT ME! + * + * @throws DataAccessException DOCUMENT ME! */ public String encodePassword(String rawPass, Object salt) throws DataAccessException; + + /** + *

Validates a specified "raw" password against an encoded password.

+ *

The encoded password should have previously been generated by {@link #encodePassword(String, + * Object)}. This method will encode the rawPass (using the optional salt), and then + * compared it with the presented encPass.

+ *

For a discussion of salts, please refer to {@link #encodePassword(String, Object)}.

+ * + * @param encPass a pre-encoded password + * @param rawPass a raw password to encode and compare against the pre-encoded password + * @param salt optionally used by the implementation to "salt" the raw password before encoding. A + * null value is legal. + * + * @return DOCUMENT ME! + * + * @throws DataAccessException DOCUMENT ME! + */ + public boolean isPasswordValid(String encPass, String rawPass, Object salt) + throws DataAccessException; } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java index bacaed6b28..ae9f4a75ab 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,39 +16,23 @@ package org.acegisecurity.providers.encoding; /** - *

- * Plaintext implementation of PasswordEncoder. - *

- * - *

- * As callers may wish to extract the password and salts separately from the - * encoded password, the salt must not contain reserved characters - * (specifically '{' and '}'). - *

+ *

Plaintext implementation of PasswordEncoder.

+ *

As callers may wish to extract the password and salts separately from the encoded password, the salt must + * not contain reserved characters (specifically '{' and '}').

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ public class PlaintextPasswordEncoder extends BasePasswordEncoder { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean ignorePasswordCase = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - /** - * Indicates whether the password comparison is case sensitive. - * - *

- * Defaults to false, meaning an exact case match is required. - *

- * - * @param ignorePasswordCase set to true for less stringent - * comparison - */ - public void setIgnorePasswordCase(boolean ignorePasswordCase) { - this.ignorePasswordCase = ignorePasswordCase; + public String encodePassword(String rawPass, Object salt) { + return mergePasswordAndSalt(rawPass, salt, true); } public boolean isIgnorePasswordCase() { @@ -70,23 +54,10 @@ public class PlaintextPasswordEncoder extends BasePasswordEncoder { } } - public String encodePassword(String rawPass, Object salt) { - return mergePasswordAndSalt(rawPass, salt, true); - } - /** - * Demerges the previously {@link #encodePassword(String, - * Object)}String. - * - *

- * The resulting array is guaranteed to always contain two elements. The - * first is the password, and the second is the salt. - *

- * - *

- * Throws an exception if null or an empty String - * is passed to the method. - *

+ * Demerges the previously {@link #encodePassword(String, Object)}String.

The resulting + * array is guaranteed to always contain two elements. The first is the password, and the second is the salt.

+ *

Throws an exception if null or an empty String is passed to the method.

* * @param password from {@link #encodePassword(String, Object)} * @@ -95,4 +66,14 @@ public class PlaintextPasswordEncoder extends BasePasswordEncoder { public String[] obtainPasswordAndSalt(String password) { return demergePasswordAndSalt(password); } + + /** + * Indicates whether the password comparison is case sensitive.

Defaults to false, meaning + * an exact case match is required.

+ * + * @param ignorePasswordCase set to true for less stringent comparison + */ + public void setIgnorePasswordCase(boolean ignorePasswordCase) { + this.ignorePasswordCase = ignorePasswordCase; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java index 604434a041..808d06ccfe 100644 --- a/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/encoding/ShaPasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,33 +20,17 @@ import org.apache.commons.codec.digest.DigestUtils; /** - *

- * SHA implementation of PasswordEncoder. - *

- * - *

- * If a null password is presented, it will be treated as an empty - * String ("") password. - *

- * - *

- * As SHA is a one-way hash, the salt can contain any characters. - *

+ *

SHA implementation of PasswordEncoder.

+ *

If a null password is presented, it will be treated as an empty String ("") + * password.

+ *

As SHA is a one-way hash, the salt can contain any characters.

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ -public class ShaPasswordEncoder extends BaseDigestPasswordEncoder - implements PasswordEncoder { - //~ Methods ================================================================ - - public boolean isPasswordValid(String encPass, String rawPass, Object salt) { - String pass1 = "" + encPass; - String pass2 = encodePassword(rawPass, salt); - - return pass1.equals(pass2); - } +public class ShaPasswordEncoder extends BaseDigestPasswordEncoder implements PasswordEncoder { + //~ Methods ======================================================================================================== public String encodePassword(String rawPass, Object salt) { String saltedPass = mergePasswordAndSalt(rawPass, salt, false); @@ -59,4 +43,11 @@ public class ShaPasswordEncoder extends BaseDigestPasswordEncoder return new String(encoded); } + + public boolean isPasswordValid(String encPass, String rawPass, Object salt) { + String pass1 = "" + encPass; + String pass2 = encodePassword(rawPass, salt); + + return pass1.equals(pass2); + } } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java index 852136f940..64479bf433 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/AuthorityGranter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,22 +34,19 @@ import java.util.Set; * @version $Id$ */ public interface AuthorityGranter { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * The grant method is called for each principal returned from the - * LoginContext subject. If the AuthorityGranter wishes to grant any - * authorities, it should return a java.util.Set containing the role names - * it wishes to grant, such as ROLE_USER. If the AuthrityGranter does not - * wish to grant any authorities it should return null.
- * The set may contain any object as all objects in the returned set will be - * passed to the JaasGrantedAuthority constructor using toString(). + * The grant method is called for each principal returned from the LoginContext subject. If the + * AuthorityGranter wishes to grant any authorities, it should return a java.util.Set containing the role names it + * wishes to grant, such as ROLE_USER. If the AuthrityGranter does not wish to grant any authorities it should + * return null.
+ * The set may contain any object as all objects in the returned set will be passed to the JaasGrantedAuthority + * constructor using toString(). * - * @param principal One of the principals from the - * LoginContext.getSubect().getPrincipals() method. + * @param principal One of the principals from the LoginContext.getSubect().getPrincipals() method. * - * @return A java.util.Set of role names to grant, or null meaning no - * roles should be granted for the principal. + * @return A java.util.Set of role names to grant, or null meaning no roles should be granted for the principal. */ public Set grant(Principal principal); } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java b/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java index 45407f7270..ae0b323ebd 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/DefaultLoginExceptionResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,13 @@ import javax.security.auth.login.LoginException; /** - * This LoginExceptionResolver simply wraps the LoginException with an - * AuthenticationServiceException. + * This LoginExceptionResolver simply wraps the LoginException with an AuthenticationServiceException. * * @author Ray Krueger * @version $Revision$ */ public class DefaultLoginExceptionResolver implements LoginExceptionResolver { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public AcegiSecurityException resolveException(LoginException e) { return new AuthenticationServiceException(e.getMessage(), e); diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java index c4722f947c..b1b5d975d8 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationCallbackHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,14 +48,13 @@ import javax.security.auth.callback.UnsupportedCallbackException; * href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/callback/CallbackHandler.html">CallbackHandler */ public interface JaasAuthenticationCallbackHandler { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Handle the Callback. - * The handle method will be called for every callback instance sent from - * the LoginContext. Meaning that The handle method may be called multiple - * times for a given JaasAuthenticationCallbackHandler. + * href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/callback/Callback.html">Callback. The + * handle method will be called for every callback instance sent from the LoginContext. Meaning that The handle + * method may be called multiple times for a given JaasAuthenticationCallbackHandler. * * @param callback * @param auth The Authentication object currently being authenticated. diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java index 14ce0b0833..6c61009bcc 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,284 +19,213 @@ import org.acegisecurity.AcegiSecurityException; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.context.HttpSessionContextIntegrationFilter; import org.acegisecurity.context.SecurityContext; + import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.jaas.event.JaasAuthenticationFailedEvent; import org.acegisecurity.providers.jaas.event.JaasAuthenticationSuccessEvent; + import org.acegisecurity.ui.session.HttpSessionDestroyedEvent; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; + import org.springframework.core.io.Resource; + import org.springframework.util.Assert; +import java.io.IOException; + +import java.security.Principal; +import java.security.Security; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.Configuration; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import java.io.IOException; -import java.security.Principal; -import java.security.Security; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; /** - * An {@link AuthenticationProvider} implementation that retrieves user details - * from a JAAS login configuration. - * - *

- * This AuthenticationProvider is capable of validating {@link - * org.acegisecurity.providers.UsernamePasswordAuthenticationToken} - * requests contain the correct username and password. - *

- * - *

- * This implementation is backed by a JAAS - * configuration. The loginConfig property must be set to a given JAAS - * configuration file. This setter accepts a Spring {@link - * org.springframework.core.io.Resource} instance. It should point to a JAAS - * configuration file containing an index matching the {@link - * #setLoginContextName(java.lang.String) loginContextName} property. - *

- * - *

- * For example: If this JaasAuthenticationProvider were configured in a Spring - * WebApplicationContext the xml to set the loginConfiguration could be as - * follows... - *

- *  <property name="loginConfig">
- *  <value>/WEB-INF/login.conf</value>
- *  </property>
- *  
- *

- * - *

- * The loginContextName should coincide with a given index in the loginConfig - * specifed. The loginConfig file used in the JUnit tests appears as the - * following... - *

- *  JAASTest {
- *  org.acegisecurity.providers.jaas.TestLoginModule required;
- *  };
- *  
- * Using the example login configuration above, the loginContextName property - * would be set as JAASTest... - *
- *  <property name="loginContextName">
- *  <value>JAASTest</value>
- *  </property>
- *  
- *

- * - *

- * When using JAAS login modules as the authentication source, sometimes the LoginContext - * will require CallbackHandlers. The JaasAuthenticationProvider uses - * an internal This + * AuthenticationProvider is capable of validating {@link + * org.acegisecurity.providers.UsernamePasswordAuthenticationToken} requests contain the correct username and + * password.

+ *

This implementation is backed by a JAAS configuration. The + * loginConfig property must be set to a given JAAS configuration file. This setter accepts a Spring {@link + * org.springframework.core.io.Resource} instance. It should point to a JAAS configuration file containing an index + * matching the {@link #setLoginContextName(java.lang.String) loginContextName} property.

+ *

For example: If this JaasAuthenticationProvider were configured in a Spring WebApplicationContext the xml to + * set the loginConfiguration could be as follows...

 <property name="loginConfig">
+ *  <value>/WEB-INF/login.conf</value> </property> 

+ *

The loginContextName should coincide with a given index in the loginConfig specifed. The loginConfig file + * used in the JUnit tests appears as the following...

 JAASTest {
+ *  org.acegisecurity.providers.jaas.TestLoginModule required; }; 
Using the example login configuration + * above, the loginContextName property would be set as JAASTest...
+ *  <property name="loginContextName"> <value>JAASTest</value> </property> 

+ *

When using JAAS login modules as the authentication source, sometimes the LoginContext will + * require CallbackHandlers. The JaasAuthenticationProvider uses an internal CallbackHandler - * to wrap the {@link JaasAuthenticationCallbackHandler}s configured in the - * ApplicationContext. When the LoginContext calls the internal - * CallbackHandler, control is passed to each {@link - * JaasAuthenticationCallbackHandler} for each Callback passed. - *

- * - *

- * {{@link JaasAuthenticationCallbackHandler}s are passed to the - * JaasAuthenticationProvider through the {@link - * #setCallbackHandlers(org.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) - * callbackHandlers} property. } - *

- *  <property name="callbackHandlers">
- *  <list>
+ * to wrap the {@link JaasAuthenticationCallbackHandler}s configured in the ApplicationContext. When the LoginContext
+ * calls the internal CallbackHandler, control is passed to each {@link JaasAuthenticationCallbackHandler} for each
+ * Callback passed.

+ *

{{@link JaasAuthenticationCallbackHandler}s are passed to the JaasAuthenticationProvider through the {@link + * #setCallbackHandlers(org.acegisecurity.providers.jaas.JaasAuthenticationCallbackHandler[]) callbackHandlers} + * property. }

 <property name="callbackHandlers"> <list>
  *  <bean class="org.acegisecurity.providers.jaas.TestCallbackHandler"/>
  *  <bean class="{@link JaasNameCallbackHandler org.acegisecurity.providers.jaas.JaasNameCallbackHandler}"/>
  *  <bean class="{@link JaasPasswordCallbackHandler org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler}"/>
- *  </list>
- *  </property>
- *  
- *

- * - *

- * After calling LoginContext.login(), the JaasAuthenticationProvider will - * retrieve the returned Principals from the Subject - * (LoginContext.getSubject().getPrincipals). Each returned principal is then - * passed to the configured {@link AuthorityGranter}s. An AuthorityGranter is - * a mapping between a returned Principal, and a role name. If an - * AuthorityGranter wishes to grant an Authorization a role, it returns that - * role name from it's {@link AuthorityGranter#grant(java.security.Principal)} - * method. The returned role will be applied to the Authorization object as a - * {@link GrantedAuthority}. - *

- * - *

- * AuthorityGranters are configured in spring xml as follows... - *

- *  <property name="authorityGranters">
- *  <list>
- *  <bean class="org.acegisecurity.providers.jaas.TestAuthorityGranter"/>
- *  </list>
- *  </property>
- *  

- *

- *

- * - * A configuration note: - * The JaasAuthenticationProvider uses the security properites "e;login.config.url.X"e; to configure jaas. - * If you would like to customize the way Jaas gets configured, create a subclass of this and override the {@link #configureJaas(Resource)} method. + * </list> </property>

+ *

After calling LoginContext.login(), the JaasAuthenticationProvider will retrieve the returned Principals + * from the Subject (LoginContext.getSubject().getPrincipals). Each returned principal is then passed to the + * configured {@link AuthorityGranter}s. An AuthorityGranter is a mapping between a returned Principal, and a role + * name. If an AuthorityGranter wishes to grant an Authorization a role, it returns that role name from it's {@link + * AuthorityGranter#grant(java.security.Principal)} method. The returned role will be applied to the Authorization + * object as a {@link GrantedAuthority}.

+ *

AuthorityGranters are configured in spring xml as follows...

 <property name="authorityGranters">
+ *  <list> <bean class="org.acegisecurity.providers.jaas.TestAuthorityGranter"/> </list>
+ *  </property> 

+ * A configuration note: The JaasAuthenticationProvider uses the security properites + * "e;login.config.url.X"e; to configure jaas. If you would like to customize the way Jaas gets configured, + * create a subclass of this and override the {@link #configureJaas(Resource)} method. * * @author Ray Krueger * @version $Id$ */ -public class JaasAuthenticationProvider implements AuthenticationProvider, - InitializingBean, ApplicationContextAware, ApplicationListener { - //~ Static fields/initializers ============================================= +public class JaasAuthenticationProvider implements AuthenticationProvider, InitializingBean, ApplicationContextAware, + ApplicationListener { + //~ Static fields/initializers ===================================================================================== protected static final Log log = LogFactory.getLog(JaasAuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext context; private LoginExceptionResolver loginExceptionResolver = new DefaultLoginExceptionResolver(); private Resource loginConfig; - private String loginContextName = "ACEGI"; private AuthorityGranter[] authorityGranters; private JaasAuthenticationCallbackHandler[] callbackHandlers; - //~ Methods ================================================================ - - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.context = applicationContext; - } - - public ApplicationContext getApplicationContext() { - return context; - } - - /** - * Set the AuthorityGranters that should be consulted for role names to be - * granted to the Authentication. - * - * @param authorityGranters AuthorityGranter array - * @see JaasAuthenticationProvider - */ - public void setAuthorityGranters(AuthorityGranter[] authorityGranters) { - this.authorityGranters = authorityGranters; - } - - /** - * Returns the AuthorityGrannter array that was passed to the {@link - * #setAuthorityGranters(AuthorityGranter[])} method, or null if it none - * were ever set. - * - * @return The AuthorityGranter array, or null - * @see #setAuthorityGranters(AuthorityGranter[]) - */ - public AuthorityGranter[] getAuthorityGranters() { - return authorityGranters; - } - - /** - * Set the JAASAuthentcationCallbackHandler array to handle callback - * objects generated by the LoginContext.login method. - * - * @param callbackHandlers Array of JAASAuthenticationCallbackHandlers - */ - public void setCallbackHandlers( - JaasAuthenticationCallbackHandler[] callbackHandlers) { - this.callbackHandlers = callbackHandlers; - } - - /** - * Returns the current JaasAuthenticationCallbackHandler array, or null if - * none are set. - * - * @return the JAASAuthenticationCallbackHandlers. - * @see #setCallbackHandlers(JaasAuthenticationCallbackHandler[]) - */ - public JaasAuthenticationCallbackHandler[] getCallbackHandlers() { - return callbackHandlers; - } - - /** - * Set the JAAS login configuration file. - * - * @param loginConfig Spring - * Resource - * @see JAAS - * Reference - */ - public void setLoginConfig(Resource loginConfig) { - this.loginConfig = loginConfig; - } - - public Resource getLoginConfig() { - return loginConfig; - } - - /** - * Set the loginContextName, this name is used as the index to the - * configuration specified in the loginConfig property. - * - * @param loginContextName - */ - public void setLoginContextName(String loginContextName) { - this.loginContextName = loginContextName; - } - - public String getLoginContextName() { - return loginContextName; - } - - public void setLoginExceptionResolver( - LoginExceptionResolver loginExceptionResolver) { - this.loginExceptionResolver = loginExceptionResolver; - } - - public LoginExceptionResolver getLoginExceptionResolver() { - return loginExceptionResolver; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(loginConfig, "loginConfig must be set on " + getClass()); - Assert.hasLength(loginContextName, - "loginContextName must be set on " + getClass()); + Assert.hasLength(loginContextName, "loginContextName must be set on " + getClass()); configureJaas(loginConfig); Assert.notNull(Configuration.getConfiguration(), - "As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html \"If a Configuration object was set via the Configuration.setConfiguration method, then that object is returned. Otherwise, a default Configuration object is returned\". Your JRE returned null to Configuration.getConfiguration()."); + "As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html \"If a Configuration object was set via the Configuration.setConfiguration method, then that object is returned. Otherwise, a default Configuration object is returned\". Your JRE returned null to Configuration.getConfiguration()."); + } + + /** + * Attempts to login the user given the Authentication objects principal and credential + * + * @param auth The Authentication object to be authenticated. + * + * @return The authenticated Authentication object, with it's grantedAuthorities set. + * + * @throws AuthenticationException This implementation does not handle 'locked' or 'disabled' accounts. This method + * only throws a AuthenticationServiceException, with the message of the LoginException that will be + * thrown, should the loginContext.login() method fail. + */ + public Authentication authenticate(Authentication auth) + throws AuthenticationException { + if (auth instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) auth; + + try { + //Create the LoginContext object, and pass our InternallCallbackHandler + LoginContext loginContext = new LoginContext(loginContextName, new InternalCallbackHandler(auth)); + + //Attempt to login the user, the LoginContext will call our InternalCallbackHandler at this point. + loginContext.login(); + + //create a set to hold the authorities, and add any that have already been applied. + Set authorities = new HashSet(); + + if (request.getAuthorities() != null) { + authorities.addAll(Arrays.asList(request.getAuthorities())); + } + + //get the subject principals and pass them to each of the AuthorityGranters + Set principals = loginContext.getSubject().getPrincipals(); + + for (Iterator iterator = principals.iterator(); iterator.hasNext();) { + Principal principal = (Principal) iterator.next(); + + for (int i = 0; i < authorityGranters.length; i++) { + AuthorityGranter granter = authorityGranters[i]; + Set roles = granter.grant(principal); + + //If the granter doesn't wish to grant any authorities, it should return null. + if ((roles != null) && !roles.isEmpty()) { + for (Iterator roleIterator = roles.iterator(); roleIterator.hasNext();) { + String role = roleIterator.next().toString(); + authorities.add(new JaasGrantedAuthority(role, principal)); + } + } + } + } + + //Convert the authorities set back to an array and apply it to the token. + JaasAuthenticationToken result = new JaasAuthenticationToken(request.getPrincipal(), + request.getCredentials(), + (GrantedAuthority[]) authorities.toArray(new GrantedAuthority[authorities.size()]), loginContext); + + //Publish the success event + publishSuccessEvent(result); + + //we're done, return the token. + return result; + } catch (LoginException loginException) { + AcegiSecurityException ase = loginExceptionResolver.resolveException(loginException); + + publishFailureEvent(request, ase); + throw ase; + } + } + + return null; } /** * Hook method for configuring Jaas * - * @param loginConfigStr URL to Jaas login configuration + * @param loginConfig URL to Jaas login configuration + * + * @throws IOException DOCUMENT ME! */ - protected void configureJaas(Resource loginConfig) throws IOException { + protected void configureJaas(Resource loginConfig) + throws IOException { configureJaasUsingLoop(); } /** - * Loops through the login.config.url.1,login.config.url.2 properties - * looking for the login configuration. If it is not set, it will be set - * to the last available login.config.url.X property. + * Loops through the login.config.url.1,login.config.url.2 properties looking for the login configuration. + * If it is not set, it will be set to the last available login.config.url.X property. + * + * @throws IOException DOCUMENT ME! */ private void configureJaasUsingLoop() throws IOException { String loginConfigUrl = loginConfig.getURL().toString(); @@ -318,93 +247,85 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, if (!alreadySet) { String key = prefix + n; - log.debug("Setting security property [" + key + "] to: " - + loginConfigUrl); + log.debug("Setting security property [" + key + "] to: " + loginConfigUrl); Security.setProperty(key, loginConfigUrl); } } - /** - * Attempts to login the user given the Authentication objects principal - * and credential - * - * @param auth The Authentication object to be authenticated. - * @return The authenticated Authentication object, with it's - * grantedAuthorities set. - * @throws AuthenticationException This implementation does not handle - * 'locked' or 'disabled' accounts. This method only throws a - * AuthenticationServiceException, with the message of the - * LoginException that will be thrown, should the - * loginContext.login() method fail. - */ - public Authentication authenticate(Authentication auth) - throws AuthenticationException { - if (auth instanceof UsernamePasswordAuthenticationToken) { - UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) auth; - - try { - //Create the LoginContext object, and pass our InternallCallbackHandler - LoginContext loginContext = new LoginContext(loginContextName, - new InternalCallbackHandler(auth)); - - //Attempt to login the user, the LoginContext will call our InternalCallbackHandler at this point. - loginContext.login(); - - //create a set to hold the authorities, and add any that have already been applied. - Set authorities = new HashSet(); - - if (request.getAuthorities() != null) { - authorities.addAll(Arrays.asList(request.getAuthorities())); - } - - //get the subject principals and pass them to each of the AuthorityGranters - Set principals = loginContext.getSubject().getPrincipals(); - - for (Iterator iterator = principals.iterator(); - iterator.hasNext();) { - Principal principal = (Principal) iterator.next(); - - for (int i = 0; i < authorityGranters.length; i++) { - AuthorityGranter granter = authorityGranters[i]; - Set roles = granter.grant(principal); - - //If the granter doesn't wish to grant any authorities, it should return null. - if ((roles != null) && !roles.isEmpty()) { - for (Iterator roleIterator = roles.iterator(); - roleIterator.hasNext();) { - String role = roleIterator.next().toString(); - authorities.add(new JaasGrantedAuthority(role, - principal)); - } - } - } - } - - //Convert the authorities set back to an array and apply it to the token. - JaasAuthenticationToken result = new JaasAuthenticationToken(request - .getPrincipal(), request.getCredentials(), - (GrantedAuthority[]) authorities.toArray( - new GrantedAuthority[authorities.size()]), loginContext); - - //Publish the success event - publishSuccessEvent(result); - - //we're done, return the token. - return result; - } catch (LoginException loginException) { - AcegiSecurityException ase = loginExceptionResolver - .resolveException(loginException); - - publishFailureEvent(request, ase); - throw ase; - } - } - - return null; + public ApplicationContext getApplicationContext() { + return context; } - public boolean supports(Class aClass) { - return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass); + /** + * Returns the AuthorityGrannter array that was passed to the {@link + * #setAuthorityGranters(AuthorityGranter[])} method, or null if it none were ever set. + * + * @return The AuthorityGranter array, or null + * + * @see #setAuthorityGranters(AuthorityGranter[]) + */ + public AuthorityGranter[] getAuthorityGranters() { + return authorityGranters; + } + + /** + * Returns the current JaasAuthenticationCallbackHandler array, or null if none are set. + * + * @return the JAASAuthenticationCallbackHandlers. + * + * @see #setCallbackHandlers(JaasAuthenticationCallbackHandler[]) + */ + public JaasAuthenticationCallbackHandler[] getCallbackHandlers() { + return callbackHandlers; + } + + public Resource getLoginConfig() { + return loginConfig; + } + + public String getLoginContextName() { + return loginContextName; + } + + public LoginExceptionResolver getLoginExceptionResolver() { + return loginExceptionResolver; + } + + /** + * Handles the logout by getting the SecurityContext for the session that was destroyed. MUST NOT use + * SecurityContextHolder we are logging out a session that is not related to the current user. + * + * @param event + */ + protected void handleLogout(HttpSessionDestroyedEvent event) { + SecurityContext context = (SecurityContext) event.getSession() + .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); + + if (context == null) { + log.debug("The destroyed session has no SecurityContext"); + + return; + } + + Authentication auth = context.getAuthentication(); + + if ((auth != null) && (auth instanceof JaasAuthenticationToken)) { + JaasAuthenticationToken token = (JaasAuthenticationToken) auth; + + try { + LoginContext loginContext = token.getLoginContext(); + + if (loginContext != null) { + log.debug("Logging principal: [" + token.getPrincipal() + "] out of LoginContext"); + loginContext.logout(); + } else { + log.debug("Cannot logout principal: [" + token.getPrincipal() + "] from LoginContext. " + + "The LoginContext is unavailable"); + } + } catch (LoginException e) { + log.warn("Error error logging out of LoginContext", e); + } + } } public void onApplicationEvent(ApplicationEvent applicationEvent) { @@ -415,62 +336,84 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, } /** - * Handles the logout by getting the SecurityContext for the session that was destroyed. - * MUST NOT use SecurityContextHolder we are logging out a session that is not related to the current user. - * @param event - */ - protected void handleLogout(HttpSessionDestroyedEvent event) { - SecurityContext context = (SecurityContext) event.getSession().getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); - if (context == null) { - log.debug("The destroyed session has no SecurityContext"); - return; - } - Authentication auth = context.getAuthentication(); - if ((auth != null) && (auth instanceof JaasAuthenticationToken)) { - JaasAuthenticationToken token = (JaasAuthenticationToken) auth; - try { - LoginContext loginContext = token.getLoginContext(); - if (loginContext != null) { - log.debug("Logging principal: [" + token.getPrincipal() + "] out of LoginContext"); - loginContext.logout(); - } else { - log.debug("Cannot logout principal: [" + token.getPrincipal() + "] from LoginContext. " + - "The LoginContext is unavailable"); - } - } catch (LoginException e) { - log.warn("Error error logging out of LoginContext", e); - } - } - } - - /** - * Publishes the {@link JaasAuthenticationFailedEvent}. Can be overridden - * by subclasses for different functionality + * Publishes the {@link JaasAuthenticationFailedEvent}. Can be overridden by subclasses for different + * functionality * - * @param token The {@link UsernamePasswordAuthenticationToken} being - * processed + * @param token The {@link UsernamePasswordAuthenticationToken} being processed * @param ase The {@link AcegiSecurityException} that caused the failure */ - protected void publishFailureEvent( - UsernamePasswordAuthenticationToken token, AcegiSecurityException ase) { - getApplicationContext().publishEvent(new JaasAuthenticationFailedEvent( - token, ase)); + protected void publishFailureEvent(UsernamePasswordAuthenticationToken token, AcegiSecurityException ase) { + getApplicationContext().publishEvent(new JaasAuthenticationFailedEvent(token, ase)); } /** - * Publishes the {@link JaasAuthenticationSuccessEvent}. Can be overridden - * by subclasses for different functionality. + * Publishes the {@link JaasAuthenticationSuccessEvent}. Can be overridden by subclasses for different + * functionality. * - * @param token The {@link UsernamePasswordAuthenticationToken} being - * processed + * @param token The {@link UsernamePasswordAuthenticationToken} being processed */ - protected void publishSuccessEvent( - UsernamePasswordAuthenticationToken token) { - getApplicationContext().publishEvent(new JaasAuthenticationSuccessEvent( - token)); + protected void publishSuccessEvent(UsernamePasswordAuthenticationToken token) { + getApplicationContext().publishEvent(new JaasAuthenticationSuccessEvent(token)); } - //~ Inner Classes ========================================================== + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.context = applicationContext; + } + + /** + * Set the AuthorityGranters that should be consulted for role names to be granted to the Authentication. + * + * @param authorityGranters AuthorityGranter array + * + * @see JaasAuthenticationProvider + */ + public void setAuthorityGranters(AuthorityGranter[] authorityGranters) { + this.authorityGranters = authorityGranters; + } + + /** + * Set the JAASAuthentcationCallbackHandler array to handle callback objects generated by the + * LoginContext.login method. + * + * @param callbackHandlers Array of JAASAuthenticationCallbackHandlers + */ + public void setCallbackHandlers(JaasAuthenticationCallbackHandler[] callbackHandlers) { + this.callbackHandlers = callbackHandlers; + } + + /** + * Set the JAAS login configuration file. + * + * @param loginConfig Spring + * Resource + * + * @see JAAS Reference + */ + public void setLoginConfig(Resource loginConfig) { + this.loginConfig = loginConfig; + } + + /** + * Set the loginContextName, this name is used as the index to the configuration specified in the + * loginConfig property. + * + * @param loginContextName + */ + public void setLoginContextName(String loginContextName) { + this.loginContextName = loginContextName; + } + + public void setLoginExceptionResolver(LoginExceptionResolver loginExceptionResolver) { + this.loginExceptionResolver = loginExceptionResolver; + } + + public boolean supports(Class aClass) { + return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass); + } + + //~ Inner Classes ================================================================================================== /** * Wrapper class for JAASAuthenticationCallbackHandlers @@ -482,8 +425,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, this.authentication = authentication; } - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbackHandlers.length; i++) { JaasAuthenticationCallbackHandler handler = callbackHandlers[i]; diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationToken.java index d9abb958b2..1522638d6b 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasAuthenticationToken.java @@ -1,28 +1,52 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.jaas; +import org.acegisecurity.GrantedAuthority; + +import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import javax.security.auth.login.LoginContext; -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; /** * UsernamePasswordAuthenticationToken extension to carry the Jaas LoginContext that the user was logged into + * * @author Ray Krueger */ public class JaasAuthenticationToken extends UsernamePasswordAuthenticationToken { + //~ Instance fields ================================================================================================ private transient LoginContext loginContext = null; + //~ Constructors =================================================================================================== + public JaasAuthenticationToken(Object principal, Object credentials, LoginContext loginContext) { super(principal, credentials); this.loginContext = loginContext; } - public JaasAuthenticationToken(Object principal, Object credentials, GrantedAuthority[] authorities, LoginContext loginContext) { + public JaasAuthenticationToken(Object principal, Object credentials, GrantedAuthority[] authorities, + LoginContext loginContext) { super(principal, credentials, authorities); this.loginContext = loginContext; } + //~ Methods ======================================================================================================== + public LoginContext getLoginContext() { return loginContext; } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java index a47ca39558..880050a76a 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasGrantedAuthority.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ import java.security.Principal; /** - * Extends GrantedAuthorityImpl to hold the principal that an AuthorityGranter - * justified as a reason to grant this Authority.
+ * Extends GrantedAuthorityImpl to hold the principal that an AuthorityGranter justified as a reason to grant this + * Authority.
* * @author Ray Krueger * @version $Id$ @@ -30,18 +30,18 @@ import java.security.Principal; * @see AuthorityGranter */ public class JaasGrantedAuthority extends GrantedAuthorityImpl { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Principal principal; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JaasGrantedAuthority(String role, Principal principal) { super(role); this.principal = principal; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Principal getPrincipal() { return principal; diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java index 4d694f5027..e4ac6893d4 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasNameCallbackHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.providers.jaas; import org.acegisecurity.Authentication; + import org.acegisecurity.userdetails.UserDetails; import java.io.IOException; @@ -26,27 +27,23 @@ import javax.security.auth.callback.UnsupportedCallbackException; /** - * The most basic Callbacks to be handled when using a LoginContext from JAAS, - * are the NameCallback and PasswordCallback. The acegi security framework - * provides the JaasNameCallbackHandler specifically tailored to handling the - * NameCallback.
+ * The most basic Callbacks to be handled when using a LoginContext from JAAS, are the NameCallback and + * PasswordCallback. The acegi security framework provides the JaasNameCallbackHandler specifically tailored to + * handling the NameCallback.
* * @author Ray Krueger * @version $Id$ * - * @see Callback + * @see Callback * @see NameCallback */ -public class JaasNameCallbackHandler - implements JaasAuthenticationCallbackHandler { - //~ Methods ================================================================ +public class JaasNameCallbackHandler implements JaasAuthenticationCallbackHandler { + //~ Methods ======================================================================================================== /** - * If the callback passed to the 'handle' method is an instance of - * NameCallback, the JaasNameCallbackHandler will call, - * callback.setName(authentication.getPrincipal().toString()). + * If the callback passed to the 'handle' method is an instance of NameCallback, the + * JaasNameCallbackHandler will call, callback.setName(authentication.getPrincipal().toString()). * * @param callback * @param authentication @@ -55,14 +52,13 @@ public class JaasNameCallbackHandler * @throws UnsupportedCallbackException */ public void handle(Callback callback, Authentication authentication) - throws IOException, UnsupportedCallbackException { - + throws IOException, UnsupportedCallbackException { if (callback instanceof NameCallback) { - NameCallback ncb = (NameCallback) callback; String username = ""; Object principal = authentication.getPrincipal(); + if (principal instanceof UserDetails) { username = ((UserDetails) principal).getUsername(); } else { diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java b/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java index eae6377c04..fd3897495b 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/JaasPasswordCallbackHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,27 +25,23 @@ import javax.security.auth.callback.UnsupportedCallbackException; /** - * The most basic Callbacks to be handled when using a LoginContext from JAAS, - * are the NameCallback and PasswordCallback. The acegi security framework - * provides the JaasPasswordCallbackHandler specifically tailored to handling - * the PasswordCallback.
+ * The most basic Callbacks to be handled when using a LoginContext from JAAS, are the NameCallback and + * PasswordCallback. The acegi security framework provides the JaasPasswordCallbackHandler specifically tailored to + * handling the PasswordCallback.
* * @author Ray Krueger * @version $Id$ * - * @see Callback + * @see Callback * @see PasswordCallback */ -public class JaasPasswordCallbackHandler - implements JaasAuthenticationCallbackHandler { - //~ Methods ================================================================ +public class JaasPasswordCallbackHandler implements JaasAuthenticationCallbackHandler { + //~ Methods ======================================================================================================== /** - * If the callback passed to the 'handle' method is an instance of - * PasswordCallback, the JaasPasswordCallbackHandler will call, - * callback.setPassword(authentication.getCredentials().toString()). + * If the callback passed to the 'handle' method is an instance of PasswordCallback, the + * JaasPasswordCallbackHandler will call, callback.setPassword(authentication.getCredentials().toString()). * * @param callback * @param auth diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java b/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java index 924453e4f3..884b952097 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/LoginExceptionResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,15 +32,14 @@ import javax.security.auth.login.LoginException; * @version $Revision$ */ public interface LoginExceptionResolver { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Translates a Jaas LoginException to an AcegiSecurityException. * * @param e The LoginException thrown by the configured LoginModule. * - * @return The AcegiSecurityException that the JaasAuthenticationProvider - * should throw. + * @return The AcegiSecurityException that the JaasAuthenticationProvider should throw. */ public AcegiSecurityException resolveException(LoginException e); } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/SecurityContextLoginModule.java b/core/src/main/java/org/acegisecurity/providers/jaas/SecurityContextLoginModule.java index 82e02b9531..74d34a3d5d 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/SecurityContextLoginModule.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/SecurityContextLoginModule.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.providers.jaas; import org.acegisecurity.Authentication; + import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.logging.Log; @@ -30,45 +31,37 @@ import javax.security.auth.spi.LoginModule; /** - * An implementation of {@link LoginModule} that uses an Acegi Security - * {@link org.acegisecurity.context.SecurityContext SecurityContext} - * to provide authentication.
- * This LoginModule provides opposite functionality to the {@link - * JaasAuthenticationProvider} API, and should not really be used in - * conjunction with it.
- * The {@link JaasAuthenticationProvider} allows Acegi to authenticate against - * Jaas.
- * The SecurityContextLoginModule allows a Jaas based application to - * authenticate against Acegi. If there is no Authentication in the {@link - * SecurityContextHolder} the login() method will throw a LoginException by - * default. This functionality can be changed with the - * ignoreMissingAuthentication option by setting it to "true". - * Setting ignoreMissingAuthentication=true will tell the - * SecurityContextLoginModule to simply return false and be ignored if the - * authentication is null. + * An implementation of {@link LoginModule} that uses an Acegi Security {@link + * org.acegisecurity.context.SecurityContext SecurityContext} to provide authentication.

This LoginModule + * provides opposite functionality to the {@link JaasAuthenticationProvider} API, and should not really be used in + * conjunction with it.

+ *

The {@link JaasAuthenticationProvider} allows Acegi to authenticate against Jaas.

+ *

The SecurityContextLoginModule allows a Jaas based application to authenticate against Acegi. If there is no + * Authentication in the {@link SecurityContextHolder} the login() method will throw a LoginException by default. + * This functionality can be changed with the ignoreMissingAuthentication option by setting it to "true". + * Setting ignoreMissingAuthentication=true will tell the SecurityContextLoginModule to simply return false and be + * ignored if the authentication is null.

* * @author Brian Moseley * @author Ray Krueger */ public class SecurityContextLoginModule implements LoginModule { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log log = LogFactory.getLog(SecurityContextLoginModule.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authentication authen; private Subject subject; private boolean ignoreMissingAuthentication = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Abort the authentication process by forgetting the Acegi Security - * Authentication. + * Abort the authentication process by forgetting the Acegi Security Authentication. * - * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * @return true if this method succeeded, or false if this LoginModule should be ignored. * * @exception LoginException if the abort fails */ @@ -83,12 +76,10 @@ public class SecurityContextLoginModule implements LoginModule { } /** - * Authenticate the Subject (phase two) by adding the Acegi - * Security Authentication to the Subject's - * principals. + * Authenticate the Subject (phase two) by adding the Acegi Security + * Authentication to the Subject's principals. * - * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * @return true if this method succeeded, or false if this LoginModule should be ignored. * * @exception LoginException if the commit fails */ @@ -102,35 +93,37 @@ public class SecurityContextLoginModule implements LoginModule { return true; } + Authentication getAuthentication() { + return authen; + } + + Subject getSubject() { + return subject; + } + /** - * Initialize this LoginModule. Ignores the callback handler, - * since the code establishing the LoginContext likely won't - * provide one that understands Acegi Security. Also ignores the - * sharedState and options parameters, since - * none are recognized. + * Initialize this LoginModule. Ignores the callback handler, since the code establishing the + * LoginContext likely won't provide one that understands Acegi Security. Also ignores the + * sharedState and options parameters, since none are recognized. * * @param subject the Subject to be authenticated.

* @param callbackHandler is ignored * @param sharedState is ignored * @param options are ignored */ - public void initialize(Subject subject, CallbackHandler callbackHandler, - Map sharedState, Map options) { + public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { this.subject = subject; if (options != null) { - ignoreMissingAuthentication = "true".equals(options.get( - "ignoreMissingAuthentication")); + ignoreMissingAuthentication = "true".equals(options.get("ignoreMissingAuthentication")); } } /** - * Authenticate the Subject (phase one) by extracting the - * Acegi Security Authentication from the current - * SecurityContext. + * Authenticate the Subject (phase one) by extracting the Acegi Security + * Authentication from the current SecurityContext. * - * @return true if the authentication succeeded, or false if this - * LoginModule should be ignored. + * @return true if the authentication succeeded, or false if this LoginModule should be ignored. * * @throws LoginException if the authentication fails */ @@ -155,8 +148,7 @@ public class SecurityContextLoginModule implements LoginModule { /** * Log out the Subject. * - * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * @return true if this method succeeded, or false if this LoginModule should be ignored. * * @exception LoginException if the logout fails */ @@ -170,12 +162,4 @@ public class SecurityContextLoginModule implements LoginModule { return true; } - - Authentication getAuthentication() { - return authen; - } - - Subject getSubject() { - return subject; - } } diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java index ec33c33578..d23c2f19d3 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +21,16 @@ import org.springframework.context.ApplicationEvent; /** - * Parent class for events fired by the {@link - * org.acegisecurity.providers.jaas.JaasAuthenticationProvider + * Parent class for events fired by the {@link org.acegisecurity.providers.jaas.JaasAuthenticationProvider * JaasAuthenticationProvider}. * * @author Ray Krueger * @version $Id$ */ public abstract class JaasAuthenticationEvent extends ApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * The Authentication object is stored as the ApplicationEvent 'source'. * * @param auth @@ -40,7 +39,7 @@ public abstract class JaasAuthenticationEvent extends ApplicationEvent { super(auth); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Pre-casted method that returns the 'source' of the event. diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java index a476e7a962..3f77253b3d 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationFailedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,26 +19,24 @@ import org.acegisecurity.Authentication; /** - * Fired when LoginContext.login throws a LoginException, or if any other - * exception is thrown during that time. + * Fired when LoginContext.login throws a LoginException, or if any other exception is thrown during that time. * * @author Ray Krueger * @version $Id$ */ public class JaasAuthenticationFailedEvent extends JaasAuthenticationEvent { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Exception exception; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public JaasAuthenticationFailedEvent(Authentication auth, - Exception exception) { + public JaasAuthenticationFailedEvent(Authentication auth, Exception exception) { super(auth); this.exception = exception; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Exception getException() { return exception; diff --git a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java index 99a4d3a42d..041d7950e0 100644 --- a/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java +++ b/core/src/main/java/org/acegisecurity/providers/jaas/event/JaasAuthenticationSuccessEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,15 @@ import org.acegisecurity.Authentication; /** - * Fired by the {@link - * org.acegisecurity.providers.jaas.JaasAuthenticationProvider - * JaasAuthenticationProvider} after successfully logging the user into the - * LoginContext, handling all callbacks, and calling all AuthorityGranters. + * Fired by the {@link org.acegisecurity.providers.jaas.JaasAuthenticationProvider JaasAuthenticationProvider} + * after successfully logging the user into the LoginContext, handling all callbacks, and calling all + * AuthorityGranters. * * @author Ray Krueger * @version $Id$ */ public class JaasAuthenticationSuccessEvent extends JaasAuthenticationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JaasAuthenticationSuccessEvent(Authentication auth) { super(auth); diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java index 4cb3bd132f..1c82258df5 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,165 +15,109 @@ package org.acegisecurity.providers.ldap; -import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider; -import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; +import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider; + +import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.util.StringUtils; + /** - * An {@link org.acegisecurity.providers.AuthenticationProvider} implementation that - * provides integration with an LDAP server. - * - *

- * There are many ways in which an LDAP directory can be configured so this class - * delegates most of its responsibilites to two separate strategy interfaces, - * {@link LdapAuthenticator} and {@link LdapAuthoritiesPopulator}. - *

- * - *

LdapAuthenticator

- * - * This interface is responsible for performing the user authentication and retrieving - * the user's information from the directory. Example implementations are - * {@link org.acegisecurity.providers.ldap.authenticator.BindAuthenticator BindAuthenticator} - * which authenticates the user by "binding" as that user, and - * {@link org.acegisecurity.providers.ldap.authenticator.PasswordComparisonAuthenticator PasswordComparisonAuthenticator} - * which performs a comparison of the supplied password with the value stored in the directory, - * either by retrieving the password or performing an LDAP "compare" operation. - *

- * The task of retrieving the user attributes is delegated to the authenticator - * because the permissions on the attributes may depend on the type of authentication - * being used; for example, if binding as the user, it may be necessary to read them - * with the user's own permissions (using the same context used for the bind operation). - *

- * - *

LdapAuthoritiesPopulator

- * - * Once the user has been authenticated, this interface is called to obtain the set of - * granted authorities for the user. The - * {@link org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator DefaultLdapAuthoritiesPopulator} - * can be configured to obtain user role information from the user's attributes and/or to perform - * a search for "groups" that the user is a member of and map these to roles. - *

- * A custom implementation could obtain the roles from a completely different source, - * for example from a database. - *

- * - *

Configuration

- * A simple configuration might be as follows: - *
+ * An {@link org.acegisecurity.providers.AuthenticationProvider} implementation that provides integration with an
+ * LDAP server.

There are many ways in which an LDAP directory can be configured so this class delegates most of + * its responsibilites to two separate strategy interfaces, {@link LdapAuthenticator} and {@link + * LdapAuthoritiesPopulator}.

+ *

LdapAuthenticator

This interface is responsible for performing the user authentication and retrieving + * the user's information from the directory. Example implementations are {@link + * org.acegisecurity.providers.ldap.authenticator.BindAuthenticator BindAuthenticator} which authenticates the user by + * "binding" as that user, and {@link org.acegisecurity.providers.ldap.authenticator.PasswordComparisonAuthenticator + * PasswordComparisonAuthenticator} which performs a comparison of the supplied password with the value stored in the + * directory, either by retrieving the password or performing an LDAP "compare" operation.

The task of retrieving + * the user attributes is delegated to the authenticator because the permissions on the attributes may depend on the + * type of authentication being used; for example, if binding as the user, it may be necessary to read them with the + * user's own permissions (using the same context used for the bind operation).

+ *

LdapAuthoritiesPopulator

Once the user has been authenticated, this interface is called to obtain the + * set of granted authorities for the user. The {@link + * org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator DefaultLdapAuthoritiesPopulator} can be + * configured to obtain user role information from the user's attributes and/or to perform a search for "groups" that + * the user is a member of and map these to roles.

A custom implementation could obtain the roles from a + * completely different source, for example from a database.

+ *

Configuration

A simple configuration might be as follows:
  *    <bean id="initialDirContextFactory" class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory">
  *      <constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/>
  *      <property name="managerDn"><value>cn=manager,dc=acegisecurity,dc=org</value></property>
- *      <property name="managerPassword"><value>password</value></property>
- *    </bean>
- *
+ *      <property name="managerPassword"><value>password</value></property>   </bean>
  *    <bean id="ldapAuthProvider" class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
- *    <constructor-arg>
- *      <bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
+ *    <constructor-arg>     <bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
  *         <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
  *         <property name="userDnPatterns"><list><value>uid={0},ou=people</value></list></property>
- *      </bean>
- *    </constructor-arg>
- *    <constructor-arg>
+ *      </bean>   </constructor-arg>   <constructor-arg>
  *      <bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
  *         <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
  *         <constructor-arg><value>ou=groups</value></constructor-arg>
- *         <property name="groupRoleAttribute"><value>ou</value></property>
- *      </bean>
- *    </constructor-arg>
- *  </bean>
- * 
- *

- * This would set up the provider to access an LDAP server with URL - * ldap://monkeymachine:389/dc=acegisecurity,dc=org. Authentication will be performed by - * attempting to bind with the DN uid=<user-login-name>,ou=people,dc=acegisecurity,dc=org. - * After successful authentication, roles will be assigned to the user by searching under the DN - * ou=groups,dc=acegisecurity,dc=org with the default filter (member=<user's-DN>). - * The role name will be taken from the "ou" attribute of each match. - *

- * - * @see org.acegisecurity.providers.ldap.authenticator.BindAuthenticator - * @see org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator + * <property name="groupRoleAttribute"><value>ou</value></property> </bean> + * </constructor-arg> </bean>

This would set up the provider to access an LDAP server with URL + * ldap://monkeymachine:389/dc=acegisecurity,dc=org. Authentication will be performed by attempting to bind + * with the DN uid=<user-login-name>,ou=people,dc=acegisecurity,dc=org. After successful + * authentication, roles will be assigned to the user by searching under the DN + * ou=groups,dc=acegisecurity,dc=org with the default filter (member=<user's-DN>). The role + * name will be taken from the "ou" attribute of each match.

* * @author Luke Taylor * @version $Id$ + * + * @see org.acegisecurity.providers.ldap.authenticator.BindAuthenticator + * @see org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator */ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(LdapAuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private LdapAuthenticator authenticator; - private LdapAuthoritiesPopulator authoritiesPopulator; + //~ Constructors =================================================================================================== - //~ Constructors =========================================================== - - public LdapAuthenticationProvider(LdapAuthenticator authenticator, - LdapAuthoritiesPopulator authoritiesPopulator) { + public LdapAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) { Assert.notNull(authenticator, "An LdapAuthenticator must be supplied"); Assert.notNull(authoritiesPopulator, "An LdapAuthoritiesPopulator must be supplied"); this.authenticator = authenticator; this.authoritiesPopulator = authoritiesPopulator; - } - //~ Methods ================================================================ - - protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { + //~ Methods ======================================================================================================== + protected void additionalAuthenticationChecks(UserDetails userDetails, + UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { if (!userDetails.getPassword().equals(authentication.getCredentials().toString())) { throw new BadCredentialsException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.badCredentials", - "Bad credentials"), userDetails); + "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails); } } - protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - if(!StringUtils.hasLength(username)) { - throw new BadCredentialsException(messages.getMessage( - "LdapAuthenticationProvider.emptyUsername", - "Empty Username")); - } - - if (logger.isDebugEnabled()) { - logger.debug("Retrieving user " + username); - } - - String password = (String)authentication.getCredentials(); - Assert.notNull(password, "Null password was supplied in authentication token"); - - LdapUserDetails ldapUser = authenticator.authenticate(username, password); - - return createUserDetails(ldapUser, username, password); - } - /** - * Creates the final UserDetails object that will be returned by the provider - * once the user has been authenticated. - *

- * The LdapAuthoritiesPopulator will be used to create the granted authorites for the - * user. - *

- *

- * Can be overridden to customize the creation of the final UserDetails instance. The - * default will merge any additional authorities retrieved from the populator with the - * propertis of original ldapUser object and set the values of the username and password. - *

+ * Creates the final UserDetails object that will be returned by the provider once the user has + * been authenticated.

The LdapAuthoritiesPopulator will be used to create the granted + * authorites for the user.

+ *

Can be overridden to customize the creation of the final UserDetails instance. The default will + * merge any additional authorities retrieved from the populator with the propertis of original ldapUser + * object and set the values of the username and password.

* * @param ldapUser The intermediate LdapUserDetails instance returned by the authenticator. * @param username the username submitted to the provider @@ -182,14 +126,13 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio * @return The UserDetails for the successfully authenticated user. */ protected UserDetails createUserDetails(LdapUserDetails ldapUser, String username, String password) { - LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(ldapUser); user.setUsername(username); user.setPassword(password); GrantedAuthority[] extraAuthorities = authoritiesPopulator.getGrantedAuthorities(ldapUser); - for(int i = 0; i < extraAuthorities.length; i++) { + for (int i = 0; i < extraAuthorities.length; i++) { user.addAuthority(extraAuthorities[i]); } @@ -199,5 +142,23 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio protected LdapAuthoritiesPopulator getAuthoritiesPoulator() { return authoritiesPopulator; } -} + protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { + if (!StringUtils.hasLength(username)) { + throw new BadCredentialsException(messages.getMessage("LdapAuthenticationProvider.emptyUsername", + "Empty Username")); + } + + if (logger.isDebugEnabled()) { + logger.debug("Retrieving user " + username); + } + + String password = (String) authentication.getCredentials(); + Assert.notNull(password, "Null password was supplied in authentication token"); + + LdapUserDetails ldapUser = authenticator.authenticate(username, password); + + return createUserDetails(ldapUser, username, password); + } +} diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java index 24c93375b3..626aa5c217 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.providers.ldap; import org.acegisecurity.userdetails.ldap.LdapUserDetails; + /** * The strategy interface for locating and authenticating an Ldap user. *

@@ -29,12 +30,14 @@ import org.acegisecurity.userdetails.ldap.LdapUserDetails; * @version $Id$ */ public interface LdapAuthenticator { + //~ Methods ======================================================================================================== + /** - * Authenticates as a user and obtains additional user information - * from the directory. + * Authenticates as a user and obtains additional user information from the directory. * * @param username the user's login name (not their DN). * @param password the user's password supplied at login. + * * @return the details of the successfully authenticated user. */ LdapUserDetails authenticate(String username, String password); diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java index 2661a2c20a..f42382cbc8 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,12 @@ package org.acegisecurity.providers.ldap; import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; + import org.acegisecurity.ldap.LdapDataAccessException; +import org.acegisecurity.userdetails.ldap.LdapUserDetails; + + /** * Obtains a list of granted authorities for an Ldap user. *

@@ -30,15 +33,17 @@ import org.acegisecurity.ldap.LdapDataAccessException; * @version $Id$ */ public interface LdapAuthoritiesPopulator { + //~ Methods ======================================================================================================== /** * Get the list of authorities for the user. * * @param userDetails the user details object which was returned by the LDAP authenticator. + * * @return the granted authorities for the given user. - * @throws org.acegisecurity.ldap.LdapDataAccessException if there is a problem accessing the directory. + * + * @throws LdapDataAccessException if there is a problem accessing the directory. */ GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) - throws LdapDataAccessException; - + throws LdapDataAccessException; } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java index 46645d5aa1..1a1e8bb98c 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,29 @@ package org.acegisecurity.providers.ldap.authenticator; -import org.acegisecurity.providers.ldap.LdapAuthenticator; -import org.acegisecurity.ldap.InitialDirContextFactory; -import org.acegisecurity.ldap.LdapUserSearch; -import org.acegisecurity.ldap.LdapEntryMapper; import org.acegisecurity.AcegiMessageSource; + +import org.acegisecurity.ldap.InitialDirContextFactory; +import org.acegisecurity.ldap.LdapEntryMapper; +import org.acegisecurity.ldap.LdapUserSearch; + +import org.acegisecurity.providers.ldap.LdapAuthenticator; + import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.context.MessageSourceAware; + import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.support.MessageSourceAccessor; + +import org.springframework.util.Assert; import java.text.MessageFormat; -import java.util.List; + import java.util.ArrayList; +import java.util.List; + /** * Base class for the authenticator implementations. @@ -38,34 +45,30 @@ import java.util.ArrayList; * @author Luke Taylor * @version $Id$ */ -public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, - InitializingBean, MessageSourceAware { +public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, InitializingBean, MessageSourceAware { + //~ Instance fields ================================================================================================ - //~ Instance fields ======================================================== - - protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private InitialDirContextFactory initialDirContextFactory; - - //private String[] userDnPattern = null; - - /** Stores the patterns which are used as potential DN matches */ - private MessageFormat[] userDnFormat = null; + private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); /** Optional search object which can be used to locate a user when a simple DN match isn't sufficient */ private LdapUserSearch userSearch; + protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); + + /** + * The suffix to be added to the DN patterns, worked out internally from the root DN of the configured + * InitialDirContextFactory. + */ + private String dnSuffix = ""; /** The attributes which will be retrieved from the directory. Null means all attributes */ private String[] userAttributes = null; - private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); + //private String[] userDnPattern = null; + /** Stores the patterns which are used as potential DN matches */ + private MessageFormat[] userDnFormat = null; - /** - * The suffix to be added to the DN patterns, worked out internally from the root DN of the - * configured InitialDirContextFactory. - */ - private String dnSuffix = ""; - - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== protected AbstractLdapAuthenticator(InitialDirContextFactory initialDirContextFactory) { Assert.notNull(initialDirContextFactory, "initialDirContextFactory must not be null."); @@ -78,16 +81,33 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() throws Exception { + Assert.isTrue((userDnFormat != null) || (userSearch != null), + "Either an LdapUserSearch or DN pattern (or both) must be supplied."); + } + + protected InitialDirContextFactory getInitialDirContextFactory() { + return initialDirContextFactory; + } + + public String[] getUserAttributes() { + return userAttributes; + } + + protected LdapEntryMapper getUserDetailsMapper() { + return userDetailsMapper; + } /** - * Builds list of possible DNs for the user, worked out from the - * userDnPatterns property. The returned value includes the root DN of - * the provider URL used to configure the InitialDirContextfactory. + * Builds list of possible DNs for the user, worked out from the userDnPatterns property. The + * returned value includes the root DN of the provider URL used to configure the + * InitialDirContextfactory. * * @param username the user's login name - * @return the list of possible DN matches, empty if userDnPatterns wasn't - * set. + * + * @return the list of possible DN matches, empty if userDnPatterns wasn't set. */ protected List getUserDns(String username) { if (userDnFormat == null) { @@ -97,29 +117,22 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, List userDns = new ArrayList(userDnFormat.length); String[] args = new String[] {username}; - synchronized( userDnFormat ) { - for(int i=0; i < userDnFormat.length; i++) { - userDns.add( userDnFormat[i].format(args) + dnSuffix ); + synchronized (userDnFormat) { + for (int i = 0; i < userDnFormat.length; i++) { + userDns.add(userDnFormat[i].format(args) + dnSuffix); } } return userDns; } - /** - * Sets the pattern which will be used to supply a DN for the user. - * The pattern should be the name relative to the root DN. - * The pattern argument {0} will contain the username. - * An example would be "cn={0},ou=people". - */ - public void setUserDnPatterns(String[] dnPattern) { - Assert.notNull(dnPattern, "The array of DN patterns cannot be set to null"); -// this.userDnPattern = dnPattern; - userDnFormat = new MessageFormat[dnPattern.length]; + protected LdapUserSearch getUserSearch() { + return userSearch; + } - for (int i=0; i < dnPattern.length; i++) { - userDnFormat[i] = new MessageFormat(dnPattern[i]); - } + public void setMessageSource(MessageSource messageSource) { + Assert.notNull("Message source must not be null"); + this.messages = new MessageSourceAccessor(messageSource); } /** @@ -132,39 +145,29 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, this.userAttributes = userAttributes; } - public String[] getUserAttributes() { - return userAttributes; + public void setUserDetailsMapper(LdapUserDetailsMapper userDetailsMapper) { + Assert.notNull("userDetailsMapper must not be null"); + this.userDetailsMapper = userDetailsMapper; + } + + /** + * Sets the pattern which will be used to supply a DN for the user. The pattern should be the name relative + * to the root DN. The pattern argument {0} will contain the username. An example would be "cn={0},ou=people". + * + * @param dnPattern DOCUMENT ME! + */ + public void setUserDnPatterns(String[] dnPattern) { + Assert.notNull(dnPattern, "The array of DN patterns cannot be set to null"); +// this.userDnPattern = dnPattern; + userDnFormat = new MessageFormat[dnPattern.length]; + + for (int i = 0; i < dnPattern.length; i++) { + userDnFormat[i] = new MessageFormat(dnPattern[i]); + } } public void setUserSearch(LdapUserSearch userSearch) { Assert.notNull(userSearch, "The userSearch cannot be set to null"); this.userSearch = userSearch; } - - public void setUserDetailsMapper(LdapUserDetailsMapper userDetailsMapper) { - Assert.notNull("userDetailsMapper must not be null"); - this.userDetailsMapper = userDetailsMapper; - } - - protected LdapEntryMapper getUserDetailsMapper() { - return userDetailsMapper; - } - - protected LdapUserSearch getUserSearch() { - return userSearch; - } - - protected InitialDirContextFactory getInitialDirContextFactory() { - return initialDirContextFactory; - } - - public void setMessageSource(MessageSource messageSource) { - Assert.notNull("Message source must not be null"); - this.messages = new MessageSourceAccessor(messageSource); - } - - public void afterPropertiesSet() throws Exception { - Assert.isTrue(userDnFormat != null || userSearch != null, - "Either an LdapUserSearch or DN pattern (or both) must be supplied."); - } } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java index 55cf247334..54e6e53b38 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,11 @@ package org.acegisecurity.providers.ldap.authenticator; +import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.ldap.InitialDirContextFactory; import org.acegisecurity.ldap.LdapTemplate; -import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; @@ -26,55 +28,50 @@ import org.apache.commons.logging.LogFactory; import java.util.Iterator; + /** * An authenticator which binds as a user. * - * @see AbstractLdapAuthenticator - * * @author Luke Taylor * @version $Id$ + * + * @see AbstractLdapAuthenticator */ public class BindAuthenticator extends AbstractLdapAuthenticator { - - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(BindAuthenticator.class); - - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BindAuthenticator(InitialDirContextFactory initialDirContextFactory) { super(initialDirContextFactory); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public LdapUserDetails authenticate(String username, String password) { - LdapUserDetails user = null; // If DN patterns are configured, try authenticating with them directly Iterator dns = getUserDns(username).iterator(); - while(dns.hasNext() && user == null) { - user = bindWithDn((String)dns.next(), username, password); + while (dns.hasNext() && (user == null)) { + user = bindWithDn((String) dns.next(), username, password); } // Otherwise use the configured locator to find the user // and authenticate with the returned DN. - if (user == null && getUserSearch() != null) { + if ((user == null) && (getUserSearch() != null)) { LdapUserDetails userFromSearch = getUserSearch().searchForUser(username); user = bindWithDn(userFromSearch.getDn(), username, password); } - if(user == null) { - throw new BadCredentialsException(messages.getMessage( - "BindAuthenticator.badCredentials", - "Bad credentials")); + if (user == null) { + throw new BadCredentialsException(messages.getMessage("BindAuthenticator.badCredentials", "Bad credentials")); } return user; - } private LdapUserDetails bindWithDn(String userDn, String username, String password) { @@ -85,14 +82,12 @@ public class BindAuthenticator extends AbstractLdapAuthenticator { } try { - - LdapUserDetailsImpl.Essence user = - (LdapUserDetailsImpl.Essence) template.retrieveEntry(userDn, getUserDetailsMapper(), getUserAttributes()); + LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) template.retrieveEntry(userDn, + getUserDetailsMapper(), getUserAttributes()); user.setUsername(username); return user.createUserDetails(); - - } catch(BadCredentialsException e) { + } catch (BadCredentialsException e) { // This will be thrown if an invalid user name is used and the method may // be called multiple times to try different names, so we trap the exception. if (logger.isDebugEnabled()) { diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java index e5ce764d35..b3698cf0f1 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,51 +15,82 @@ package org.acegisecurity.providers.ldap.authenticator; -import org.acegisecurity.providers.encoding.ShaPasswordEncoder; -import org.acegisecurity.providers.encoding.PasswordEncoder; import org.acegisecurity.ldap.LdapDataAccessException; + +import org.acegisecurity.providers.encoding.PasswordEncoder; +import org.acegisecurity.providers.encoding.ShaPasswordEncoder; + import org.apache.commons.codec.binary.Base64; + import org.springframework.util.Assert; import java.security.MessageDigest; + /** - * A version of {@link ShaPasswordEncoder} which supports Ldap SHA - * and SSHA (salted-SHA) encodings. The values are base-64 encoded - * and have the label "{SHA}" (or "{SSHA}") prepended to the encoded hash. + * A version of {@link ShaPasswordEncoder} which supports Ldap SHA and SSHA (salted-SHA) encodings. The values are + * base-64 encoded and have the label "{SHA}" (or "{SSHA}") prepended to the encoded hash. * * @author Luke Taylor * @version $Id$ */ public class LdapShaPasswordEncoder implements PasswordEncoder { + //~ Static fields/initializers ===================================================================================== + /** The number of bytes in a SHA hash */ private static final int SHA_LENGTH = 20; - private static final String SSHA_PREFIX = "{SSHA}"; - private static final String SHA_PREFIX = "{SHA}"; - public LdapShaPasswordEncoder() { + //~ Constructors =================================================================================================== + + public LdapShaPasswordEncoder() {} + + //~ Methods ======================================================================================================== + + private byte[] combineHashAndSalt(byte[] hash, byte[] salt) { + if (salt == null) { + return hash; + } + + byte[] hashAndSalt = new byte[hash.length + salt.length]; + System.arraycopy(hash, 0, hashAndSalt, 0, hash.length); + System.arraycopy(salt, 0, hashAndSalt, hash.length, salt.length); + + return hashAndSalt; } /** - * Checks the validity of an unencoded password against an encoded one in the form - * "{SSHA}sQuQF8vj8Eg2Y1hPdh3bkQhCKQBgjhQI". + * + DOCUMENT ME! * - * @param encPass the SSHA or SHA encoded password - * @param rawPass unencoded password to be verified. - * @param salt ignored. If the format is SSHA the salt - * bytes will be extracted from the encoded password. - * @return true if they match. + * @param rawPass the password to be encoded. + * @param salt the salt. Must be a byte array or null. + * + * @return base64 encoded concatenation of password hash and salt, prefixed with {SHA} or {SSHA} depending on + * whether salt bytes were supplied. + * + * @throws LdapDataAccessException DOCUMENT ME! */ - public boolean isPasswordValid(String encPass, String rawPass, Object salt) { - if(encPass.startsWith(SSHA_PREFIX)) { - salt = extractSalt(encPass); - } else { - salt = null; + public String encodePassword(String rawPass, Object salt) { + MessageDigest sha; + + try { + sha = MessageDigest.getInstance("SHA"); + } catch (java.security.NoSuchAlgorithmException e) { + throw new LdapDataAccessException("No SHA implementation available!"); } - return encPass.equals(encodePassword(rawPass, salt)); + sha.update(rawPass.getBytes()); + + if (salt != null) { + Assert.isInstanceOf(byte[].class, salt, "Salt value must be a byte array"); + sha.update((byte[]) salt); + } + + byte[] hash = combineHashAndSalt(sha.digest(), (byte[]) salt); + + return ((salt == null) ? SHA_PREFIX : SSHA_PREFIX) + new String(Base64.encodeBase64(hash)); } private byte[] extractSalt(String encPass) { @@ -74,45 +105,22 @@ public class LdapShaPasswordEncoder implements PasswordEncoder { } /** + * Checks the validity of an unencoded password against an encoded one in the form + * "{SSHA}sQuQF8vj8Eg2Y1hPdh3bkQhCKQBgjhQI". * - * @param rawPass the password to be encoded. - * @param salt the salt. Must be a byte array or null. + * @param encPass the SSHA or SHA encoded password + * @param rawPass unencoded password to be verified. + * @param salt ignored. If the format is SSHA the salt bytes will be extracted from the encoded password. * - * @return base64 encoded concatenation of password hash and salt, - * prefixed with {SHA} or {SSHA} depending on whether salt - * bytes were supplied. + * @return true if they match. */ - public String encodePassword(String rawPass, Object salt) { - MessageDigest sha; - - try { - sha = MessageDigest.getInstance("SHA"); - } catch (java.security.NoSuchAlgorithmException e) { - throw new LdapDataAccessException("No SHA implementation available!"); + public boolean isPasswordValid(String encPass, String rawPass, Object salt) { + if (encPass.startsWith(SSHA_PREFIX)) { + salt = extractSalt(encPass); + } else { + salt = null; } - sha.update(rawPass.getBytes()); - - if(salt != null) { - Assert.isInstanceOf(byte[].class, salt, "Salt value must be a byte array"); - sha.update((byte[])salt); - } - - byte[] hash = combineHashAndSalt(sha.digest(), (byte[])salt); - - return (salt == null ? SHA_PREFIX : SSHA_PREFIX) + - new String(Base64.encodeBase64(hash)); - } - - private byte[] combineHashAndSalt(byte[] hash, byte[] salt) { - if(salt == null) { - return hash; - } - - byte[] hashAndSalt = new byte[hash.length + salt.length]; - System.arraycopy(hash, 0, hashAndSalt, 0, hash.length); - System.arraycopy(salt, 0, hashAndSalt, hash.length, salt.length); - - return hashAndSalt; + return encPass.equals(encodePassword(rawPass, salt)); } } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java index 9570b50cdd..6599f82bb0 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,62 +15,57 @@ package org.acegisecurity.providers.ldap.authenticator; -import org.acegisecurity.ldap.LdapUtils; +import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.ldap.InitialDirContextFactory; import org.acegisecurity.ldap.LdapTemplate; +import org.acegisecurity.ldap.LdapUtils; + +import org.acegisecurity.providers.encoding.PasswordEncoder; + +import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; -import org.acegisecurity.providers.encoding.PasswordEncoder; -import org.acegisecurity.BadCredentialsException; -import org.acegisecurity.userdetails.UsernameNotFoundException; - -import org.springframework.util.Assert; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.util.Assert; + import java.util.Iterator; + /** - * An {@link org.acegisecurity.providers.ldap.LdapAuthenticator LdapAuthenticator} - * which compares the login password with the value stored in the directory. - *

- * This can be achieved either by retrieving the password attribute for the user - * and comparing it locally, or by peforming an LDAP "compare" operation. - * If the password attribute (default "userPassword") is found in the retrieved - * attributes it will be compared locally. If not, the remote comparison will be - * attempted. - *

- *

- * If passwords are stored in digest form in the repository, then a suitable - * {@link PasswordEncoder} implementation must be supplied. By default, passwords are - * encoded using the {@link LdapShaPasswordEncoder}. - *

+ * An {@link org.acegisecurity.providers.ldap.LdapAuthenticator LdapAuthenticator} which compares the login + * password with the value stored in the directory.

This can be achieved either by retrieving the password + * attribute for the user and comparing it locally, or by peforming an LDAP "compare" operation. If the password + * attribute (default "userPassword") is found in the retrieved attributes it will be compared locally. If not, the + * remote comparison will be attempted.

+ *

If passwords are stored in digest form in the repository, then a suitable {@link PasswordEncoder} + * implementation must be supplied. By default, passwords are encoded using the {@link LdapShaPasswordEncoder}.

* * @author Luke Taylor * @version $Id$ */ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthenticator { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(PasswordComparisonAuthenticator.class); - //~ Instance fields ======================================================== - - private String passwordAttributeName = "userPassword"; + //~ Instance fields ================================================================================================ private PasswordEncoder passwordEncoder = new LdapShaPasswordEncoder(); + private String passwordAttributeName = "userPassword"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PasswordComparisonAuthenticator(InitialDirContextFactory initialDirContextFactory) { super(initialDirContextFactory); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public LdapUserDetails authenticate(final String username, final String password) { - // locate the user and check the password LdapUserDetails user = null; @@ -78,18 +73,18 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic LdapTemplate ldapTemplate = new LdapTemplate(getInitialDirContextFactory()); - while(dns.hasNext() && user == null) { - final String userDn = (String)dns.next(); + while (dns.hasNext() && (user == null)) { + final String userDn = (String) dns.next(); - if(ldapTemplate.nameExists(userDn)) { - LdapUserDetailsImpl.Essence userEssence = - (LdapUserDetailsImpl.Essence) ldapTemplate.retrieveEntry(userDn, getUserDetailsMapper(), getUserAttributes()); + if (ldapTemplate.nameExists(userDn)) { + LdapUserDetailsImpl.Essence userEssence = (LdapUserDetailsImpl.Essence) ldapTemplate.retrieveEntry(userDn, + getUserDetailsMapper(), getUserAttributes()); userEssence.setUsername(username); user = userEssence.createUserDetails(); } } - if (user == null && getUserSearch() != null) { + if ((user == null) && (getUserSearch() != null)) { user = getUserSearch().searchForUser(username); } @@ -99,51 +94,32 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic String retrievedPassword = user.getPassword(); - if(retrievedPassword != null) { + if (retrievedPassword != null) { if (!verifyPassword(password, retrievedPassword)) { throw new BadCredentialsException(messages.getMessage( - "PasswordComparisonAuthenticator.badCredentials", - "Bad credentials")); + "PasswordComparisonAuthenticator.badCredentials", "Bad credentials")); } return user; } if (logger.isDebugEnabled()) { - logger.debug("Password attribute wasn't retrieved for user '" + username - + "' using mapper " + getUserDetailsMapper() - + ". Performing LDAP compare of password attribute '" - + passwordAttributeName + "'" ); + logger.debug("Password attribute wasn't retrieved for user '" + username + "' using mapper " + + getUserDetailsMapper() + ". Performing LDAP compare of password attribute '" + passwordAttributeName + + "'"); } String encodedPassword = passwordEncoder.encodePassword(password, null); byte[] passwordBytes = LdapUtils.getUtf8Bytes(encodedPassword); - if(!ldapTemplate.compare(user.getDn(), passwordAttributeName, passwordBytes)) { - - throw new BadCredentialsException(messages.getMessage( - "PasswordComparisonAuthenticator.badCredentials", - "Bad credentials")); + if (!ldapTemplate.compare(user.getDn(), passwordAttributeName, passwordBytes)) { + throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials", + "Bad credentials")); } return user; } - /** - * Allows the use of both simple and hashed passwords in the directory. - */ - private boolean verifyPassword(String password, String ldapPassword) { - if (ldapPassword.equals(password)) { - return true; - } - - if(passwordEncoder.isPasswordValid(ldapPassword, password, null)) { - return true; - } - - return false; - } - public void setPasswordAttributeName(String passwordAttribute) { Assert.hasLength(passwordAttribute, "passwordAttributeName must not be empty or null"); this.passwordAttributeName = passwordAttribute; @@ -153,4 +129,24 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic Assert.notNull(passwordEncoder, "passwordEncoder must not be null."); this.passwordEncoder = passwordEncoder; } + + /** + * Allows the use of both simple and hashed passwords in the directory. + * + * @param password DOCUMENT ME! + * @param ldapPassword DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private boolean verifyPassword(String password, String ldapPassword) { + if (ldapPassword.equals(password)) { + return true; + } + + if (passwordEncoder.isPasswordValid(ldapPassword, password, null)) { + return true; + } + + return false; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java index 6bd0c2a875..1883988d2d 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,104 +15,90 @@ package org.acegisecurity.providers.ldap.populator; -import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator; -import org.acegisecurity.ldap.InitialDirContextFactory; -import org.acegisecurity.ldap.LdapTemplate; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + +import org.acegisecurity.ldap.InitialDirContextFactory; +import org.acegisecurity.ldap.LdapTemplate; + +import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator; + import org.acegisecurity.userdetails.ldap.LdapUserDetails; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + import javax.naming.directory.Attributes; import javax.naming.directory.SearchControls; -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; + /** - * The default strategy for obtaining user role information from the directory. - *

- * It obtains roles by - *

    - *
  • Reading the values of the roles specified by the attribute names in the - * userRoleAttributes
  • - *
  • Performing a search for "groups" the user is a member of and adding - * those to the list of roles.
  • - *
- *

- *

- * If the userRolesAttributes property is set, any matching - * attributes amongst those retrieved for the user will have their values added - * to the list of roles. - * If userRolesAttributes is null, no attributes will be mapped to roles. - *

- *

- * A typical group search scenario would be where each group/role is specified using - * the groupOfNames (or groupOfUniqueNames) LDAP objectClass - * and the user's DN is listed in the member (or uniqueMember) attribute - * to indicate that they should be assigned that role. The following LDIF sample - * has the groups stored under the DN ou=groups,dc=acegisecurity,dc=org - * and a group called "developers" with "ben" and "marissa" as members: - * - *

- * dn: ou=groups,dc=acegisecurity,dc=org
- * objectClass: top
- * objectClass: organizationalUnit
- * ou: groups
- *
- * dn: cn=developers,ou=groups,dc=acegisecurity,dc=org
- * objectClass: groupOfNames
- * objectClass: top
- * cn: developers
- * description: Acegi Security Developers
- * member: uid=ben,ou=people,dc=acegisecurity,dc=org
- * member: uid=marissa,ou=people,dc=acegisecurity,dc=org
- * ou: developer
- * 
- *

- *

- * The group search is performed within a DN specified by the groupSearchBase - * property, which should be relative to the root DN of its InitialDirContextFactory. - * If the search base is null, group searching is disabled. The filter used in the search is defined by the - * groupSearchFilter property, with the filter argument {0} being the full DN of the user. You can also specify which attribute defines the role name by - * setting the groupRoleAttribute property (the default is "cn"). - *

- *

- * The configuration below shows how the group search might be performed with the above schema. - *

+ * The default strategy for obtaining user role information from the directory.

It obtains roles by + *

    + *
  • Reading the values of the roles specified by the attribute names in the userRoleAttributes
  • + *
  • Performing a search for "groups" the user is a member of and adding those to the list of roles.
  • + *
+ *

+ *

If the userRolesAttributes property is set, any matching attributes amongst those retrieved for the + * user will have their values added to the list of roles. If userRolesAttributes is null, no attributes will + * be mapped to roles.

+ *

A typical group search scenario would be where each group/role is specified using the groupOfNames + * (or groupOfUniqueNames) LDAP objectClass and the user's DN is listed in the member (or + * uniqueMember) attribute to indicate that they should be assigned that role. The following LDIF sample has + * the groups stored under the DN ou=groups,dc=acegisecurity,dc=org and a group called "developers" with + * "ben" and "marissa" as members:

dn: ou=groups,dc=acegisecurity,dc=orgobjectClass: top
+ * objectClass: organizationalUnitou: groupsdn: cn=developers,ou=groups,dc=acegisecurity,dc=org
+ * objectClass: groupOfNamesobjectClass: topcn: developersdescription: Acegi Security Developers
+ * member: uid=ben,ou=people,dc=acegisecurity,dc=orgmember: uid=marissa,ou=people,dc=acegisecurity,dc=orgou: developer
+ * 

+ *

The group search is performed within a DN specified by the groupSearchBase property, which should + * be relative to the root DN of its InitialDirContextFactory. If the search base is null, group searching is + * disabled. The filter used in the search is defined by the groupSearchFilter property, with the filter + * argument {0} being the full DN of the user. You can also specify which attribute defines the role name by setting + * the groupRoleAttribute property (the default is "cn").

+ *

The configuration below shows how the group search might be performed with the above schema.

  * <bean id="ldapAuthoritiesPopulator" class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
  *   <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
  *   <constructor-arg><value>ou=groups</value></constructor-arg>
  *   <property name="groupRoleAttribute"><value>ou</value></property>
- *
  * <!-- the following properties are shown with their default values -->
- *
  *   <property name="searchSubTree"><value>false</value></property>
  *   <property name="rolePrefix"><value>ROLE_</value></property>
- *   <property name="convertToUpperCase"><value>true</value></property>
- * </bean>
- * 
- * A search for roles for user "uid=ben,ou=people,dc=acegisecurity,dc=org" would return the single - * granted authority "ROLE_DEVELOPER". - *

- * + * <property name="convertToUpperCase"><value>true</value></property></bean>
A search for + * roles for user "uid=ben,ou=people,dc=acegisecurity,dc=org" would return the single granted authority + * "ROLE_DEVELOPER".

* * @author Luke Taylor * @version $Id$ */ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(DefaultLdapAuthoritiesPopulator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - /** Attributes of the User's LDAP Object that contain role name information. */ -// private String[] userRoleAttributes = null; + /** A default role which will be assigned to all authenticated users if set */ + private GrantedAuthority defaultRole = null; - private String rolePrefix = "ROLE_"; + /** An initial context factory is only required if searching for groups is required. */ + private InitialDirContextFactory initialDirContextFactory = null; + private LdapTemplate ldapTemplate; + + /** + * Controls used to determine whether group searches should be performed over the full sub-tree from the + * base DN. Modified by searchSubTree property + */ + private SearchControls searchControls = new SearchControls(); + + /** The ID of the attribute which contains the role name for a group */ + private String groupRoleAttribute = "cn"; /** The base DN from which the search for group membership should be performed */ private String groupSearchBase = null; @@ -120,29 +106,15 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator /** The pattern to be used for the user search. {0} is the user's DN */ private String groupSearchFilter = "(member={0})"; - /** The ID of the attribute which contains the role name for a group */ - private String groupRoleAttribute = "cn"; - - /** Controls used to determine whether group searches should be performed over the - * full sub-tree from the base DN. Modified by searchSubTree property - */ - - private SearchControls searchControls = new SearchControls(); + /** Attributes of the User's LDAP Object that contain role name information. */ +// private String[] userRoleAttributes = null; + private String rolePrefix = "ROLE_"; private boolean convertToUpperCase = true; - /** A default role which will be assigned to all authenticated users if set */ - private GrantedAuthority defaultRole = null; + //~ Constructors =================================================================================================== - /** An initial context factory is only required if searching for groups is required. */ - private InitialDirContextFactory initialDirContextFactory = null; - - private LdapTemplate ldapTemplate; - - - //~ Constructors =========================================================== - - /** +/** * Constructor for group search scenarios. userRoleAttributes may still be * set as a property. * @@ -156,45 +128,56 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator this.initialDirContextFactory = initialDirContextFactory; this.groupSearchBase = groupSearchBase; - if(groupSearchBase.length() == 0) { - logger.info("groupSearchBase is empty. Searches will be performed from the root: " + - initialDirContextFactory.getRootDn()); + if (groupSearchBase.length() == 0) { + logger.info("groupSearchBase is empty. Searches will be performed from the root: " + + initialDirContextFactory.getRootDn()); } ldapTemplate = new LdapTemplate(initialDirContextFactory); ldapTemplate.setSearchControls(searchControls); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected Set getAdditionalRoles(LdapUserDetails ldapUser) { + return null; + } /** + * + DOCUMENT ME! + * + * @param userDetails DOCUMENT ME! + * * @return the set of roles granted to the user. */ public final GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) { String userDn = userDetails.getDn(); - logger.debug("Getting authorities for user " + userDn); + if (logger.isDebugEnabled()) { + logger.debug("Getting authorities for user " + userDn); + } Set roles = getGroupMembershipRoles(userDn, userDetails.getUsername()); // Temporary use of deprecated method Set oldGroupRoles = getGroupMembershipRoles(userDn, userDetails.getAttributes()); - if(oldGroupRoles != null) { + if (oldGroupRoles != null) { roles.addAll(oldGroupRoles); } Set extraRoles = getAdditionalRoles(userDetails); - if(extraRoles != null) { + if (extraRoles != null) { roles.addAll(extraRoles); } - if(defaultRole != null) { + if (defaultRole != null) { roles.add(defaultRole); } - return (GrantedAuthority[])roles.toArray(new GrantedAuthority[roles.size()]); + return (GrantedAuthority[]) roles.toArray(new GrantedAuthority[roles.size()]); } // protected Set getRolesFromUserAttributes(String userDn, Attributes userAttributes) { @@ -208,7 +191,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator // // return userRoles; // } - public final Set getGroupMembershipRoles(String userDn, String username) { Set authorities = new HashSet(); @@ -217,14 +199,12 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator } if (logger.isDebugEnabled()) { - logger.debug("Searching for roles for user '" + username + "', DN = " + "'" - + userDn + "', with filter "+ groupSearchFilter - + " in search base '" + groupSearchBase + "'"); + logger.debug("Searching for roles for user '" + username + "', DN = " + "'" + userDn + "', with filter " + + groupSearchFilter + " in search base '" + groupSearchBase + "'"); } - Set userRoles = ldapTemplate.searchForSingleAttributeValues(groupSearchBase, groupSearchFilter, - new String[]{userDn, username}, groupRoleAttribute); + new String[] {userDn, username}, groupRoleAttribute); if (logger.isDebugEnabled()) { logger.debug("Roles from search: " + userRoles); @@ -232,10 +212,10 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator Iterator it = userRoles.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { String role = (String) it.next(); - if(convertToUpperCase) { + if (convertToUpperCase) { role = role.toUpperCase(); } @@ -243,23 +223,18 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator } return authorities; - - } - - - protected Set getAdditionalRoles(LdapUserDetails ldapUser) { - return null; } /** * Searches for groups the user is a member of. * - * @deprecated Subclasses should implement getAdditionalRoles instead. - * * @param userDn the user's distinguished name. * @param userAttributes the retrieved user's attributes (unused by default). - * @return the set of roles obtained from a group membership search, or null if - * groupSearchBase has been set. + * + * @return the set of roles obtained from a group membership search, or null if groupSearchBase has been + * set. + * + * @deprecated Subclasses should implement getAdditionalRoles instead. */ protected Set getGroupMembershipRoles(String userDn, Attributes userAttributes) { return new HashSet(); @@ -269,27 +244,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator return initialDirContextFactory; } - public void setRolePrefix(String rolePrefix) { - Assert.notNull(rolePrefix, "rolePrefix must not be null"); - this.rolePrefix = rolePrefix; - } - - public void setGroupSearchFilter(String groupSearchFilter) { - Assert.notNull(groupSearchFilter, "groupSearchFilter must not be null"); - this.groupSearchFilter = groupSearchFilter; - } - - public void setGroupRoleAttribute(String groupRoleAttribute) { - Assert.notNull(groupRoleAttribute, "groupRoleAttribute must not be null"); - this.groupRoleAttribute = groupRoleAttribute; - } - - public void setSearchSubtree(boolean searchSubtree) { - int searchScope = searchSubtree ? - SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE; - searchControls.setSearchScope(searchScope); - } - public void setConvertToUpperCase(boolean convertToUpperCase) { this.convertToUpperCase = convertToUpperCase; } @@ -303,4 +257,24 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator Assert.notNull(defaultRole, "The defaultRole property cannot be set to null"); this.defaultRole = new GrantedAuthorityImpl(defaultRole); } + + public void setGroupRoleAttribute(String groupRoleAttribute) { + Assert.notNull(groupRoleAttribute, "groupRoleAttribute must not be null"); + this.groupRoleAttribute = groupRoleAttribute; + } + + public void setGroupSearchFilter(String groupSearchFilter) { + Assert.notNull(groupSearchFilter, "groupSearchFilter must not be null"); + this.groupSearchFilter = groupSearchFilter; + } + + public void setRolePrefix(String rolePrefix) { + Assert.notNull(rolePrefix, "rolePrefix must not be null"); + this.rolePrefix = rolePrefix; + } + + public void setSearchSubtree(boolean searchSubtree) { + int searchScope = searchSubtree ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE; + searchControls.setSearchScope(searchScope); + } } diff --git a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationException.java b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationException.java index b733c2ebd1..feda2c68f0 100644 --- a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationException.java +++ b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,22 +19,17 @@ import org.acegisecurity.AcegiSecurityException; /** - * Thrown if a RemoteAuthenticationManager cannot validate the - * presented authentication request. - * - *

- * This is thrown rather than the normal AuthenticationException - * because AuthenticationException contains additional properties - * which may cause issues for the remoting protocol. - *

+ * Thrown if a RemoteAuthenticationManager cannot validate the presented authentication request.

This + * is thrown rather than the normal AuthenticationException because AuthenticationException + * contains additional properties which may cause issues for the remoting protocol.

* * @author Ben Alex * @version $Id$ */ public class RemoteAuthenticationException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a RemoteAuthenticationException with the * specified message and no root cause. * diff --git a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManager.java b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManager.java index cf384a03b1..2886d8243f 100644 --- a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManager.java +++ b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,32 +25,23 @@ import org.acegisecurity.GrantedAuthority; * @version $Id$ */ public interface RemoteAuthenticationManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Attempts to authenticate the remote client using the presented username - * and password. If authentication is successful, an array of - * GrantedAuthority[] objects will be returned. - * - *

- * In order to maximise remoting protocol compatibility, a design decision - * was taken to operate with minimal arguments and return only the minimal - * amount of information required for remote clients to enable/disable - * relevant user interface commands etc. There is nothing preventing users - * from implementing their own equivalent package that works with more - * complex object types. - *

+ * Attempts to authenticate the remote client using the presented username and password. If authentication + * is successful, an array of GrantedAuthority[] objects will be returned.

In order to + * maximise remoting protocol compatibility, a design decision was taken to operate with minimal arguments and + * return only the minimal amount of information required for remote clients to enable/disable relevant user + * interface commands etc. There is nothing preventing users from implementing their own equivalent package that + * works with more complex object types.

* - * @param username the username the remote client wishes to authenticate - * with. - * @param password the password the remote client wishes to authenticate - * with. + * @param username the username the remote client wishes to authenticate with. + * @param password the password the remote client wishes to authenticate with. * - * @return all of the granted authorities the specified username and - * password have access to. + * @return all of the granted authorities the specified username and password have access to. * * @throws RemoteAuthenticationException if the authentication failed. */ - public GrantedAuthority[] attemptAuthentication(String username, - String password) throws RemoteAuthenticationException; + public GrantedAuthority[] attemptAuthentication(String username, String password) + throws RemoteAuthenticationException; } diff --git a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImpl.java b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImpl.java index 611c7fa28c..086499b107 100644 --- a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImpl.java +++ b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,49 +18,36 @@ package org.acegisecurity.providers.rcp; import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationManager; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; /** - * Server-side processor of a remote authentication request. - * - *

- * This bean requires no security interceptor to protect it. Instead, the bean - * uses the configured AuthenticationManager to resolve an - * authentication request. - *

+ * Server-side processor of a remote authentication request.

This bean requires no security interceptor to + * protect it. Instead, the bean uses the configured AuthenticationManager to resolve an authentication + * request.

* * @author Ben Alex * @version $Id$ */ -public class RemoteAuthenticationManagerImpl - implements RemoteAuthenticationManager, InitializingBean { - //~ Instance fields ======================================================== +public class RemoteAuthenticationManagerImpl implements RemoteAuthenticationManager, InitializingBean { + //~ Instance fields ================================================================================================ private AuthenticationManager authenticationManager; - //~ Methods ================================================================ - - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - public AuthenticationManager getAuthenticationManager() { - return authenticationManager; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(this.authenticationManager, "authenticationManager is required"); } - public GrantedAuthority[] attemptAuthentication(String username, - String password) throws RemoteAuthenticationException { - UsernamePasswordAuthenticationToken request = new UsernamePasswordAuthenticationToken(username, - password); + public GrantedAuthority[] attemptAuthentication(String username, String password) + throws RemoteAuthenticationException { + UsernamePasswordAuthenticationToken request = new UsernamePasswordAuthenticationToken(username, password); try { return authenticationManager.authenticate(request).getAuthorities(); @@ -68,4 +55,12 @@ public class RemoteAuthenticationManagerImpl throw new RemoteAuthenticationException(authEx.getMessage()); } } + + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProvider.java index dfbe157dd5..42c718663a 100644 --- a/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProvider.java @@ -28,65 +28,46 @@ import org.springframework.util.Assert; /** - * Client-side object which queries a {@link RemoteAuthenticationManager} to - * validate an authentication request. - * - *

- * A new Authentication object is created by this class comprising - * the request Authentication object's principal, - * credentials and the GrantedAuthority[]s returned - * by the RemoteAuthenticationManager. - *

- * - *

- * The RemoteAuthenticationManager should not require any special - * username or password setting on the remoting client proxy factory to - * execute the call. Instead the entire authentication request must be - * encapsulated solely within the Authentication request object. - * In practical terms this means the RemoteAuthenticationManager - * will not be protected by BASIC or any other HTTP-level - * authentication. - *

- * - *

- * If authentication fails, a RemoteAuthenticationException will - * be thrown. This exception should be caught and displayed to the user, - * enabling them to retry with alternative credentials etc. - *

+ * Client-side object which queries a {@link RemoteAuthenticationManager} to validate an authentication request.

A + * new Authentication object is created by this class comprising the request Authentication + * object's principal, credentials and the GrantedAuthority[]s returned by the + * RemoteAuthenticationManager.

+ *

The RemoteAuthenticationManager should not require any special username or password setting on + * the remoting client proxy factory to execute the call. Instead the entire authentication request must be + * encapsulated solely within the Authentication request object. In practical terms this means the + * RemoteAuthenticationManager will not be protected by BASIC or any other HTTP-level + * authentication.

+ *

If authentication fails, a RemoteAuthenticationException will be thrown. This exception should + * be caught and displayed to the user, enabling them to retry with alternative credentials etc.

* * @author Ben Alex * @version $Id$ */ -public class RemoteAuthenticationProvider implements AuthenticationProvider, - InitializingBean { - //~ Instance fields ======================================================== +public class RemoteAuthenticationProvider implements AuthenticationProvider, InitializingBean { + //~ Instance fields ================================================================================================ private RemoteAuthenticationManager remoteAuthenticationManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(this.remoteAuthenticationManager, - "remoteAuthenticationManager is mandatory"); + Assert.notNull(this.remoteAuthenticationManager, "remoteAuthenticationManager is mandatory"); } public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getPrincipal().toString(); String password = authentication.getCredentials().toString(); - GrantedAuthority[] authorities = remoteAuthenticationManager - .attemptAuthentication(username, password); + GrantedAuthority[] authorities = remoteAuthenticationManager.attemptAuthentication(username, password); - return new UsernamePasswordAuthenticationToken(username, password, - authorities); + return new UsernamePasswordAuthenticationToken(username, password, authorities); } public RemoteAuthenticationManager getRemoteAuthenticationManager() { return remoteAuthenticationManager; } - public void setRemoteAuthenticationManager( - RemoteAuthenticationManager remoteAuthenticationManager) { + public void setRemoteAuthenticationManager(RemoteAuthenticationManager remoteAuthenticationManager) { this.remoteAuthenticationManager = remoteAuthenticationManager; } diff --git a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java index b6faf108a2..02f0383ab5 100644 --- a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,38 +19,38 @@ import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; /** * An {@link AuthenticationProvider} implementation that validates {@link - * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken}s. - * - *

- * To be successfully validated, the {@link{@link - * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()} - * must match this class' {@link #getKey()}. - *

+ * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken}s.

To be successfully validated, the + * {@link{@link org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()} must match this + * class' {@link #getKey()}.

*/ -public class RememberMeAuthenticationProvider implements AuthenticationProvider, - InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class RememberMeAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private String key; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(key); @@ -63,10 +63,8 @@ public class RememberMeAuthenticationProvider implements AuthenticationProvider, return null; } - if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication) - .getKeyHash()) { - throw new BadCredentialsException(messages.getMessage( - "RememberMeAuthenticationProvider.incorrectKey", + if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) { + throw new BadCredentialsException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKey", "The presented RememberMeAuthenticationToken does not contain the expected key")); } diff --git a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationToken.java index b4d199ed55..c605a5af9f 100644 --- a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationToken.java @@ -25,27 +25,21 @@ import java.io.Serializable; /** - * Represents a remembered Authentication. - * - *

- * A remembered Authentication must provide a fully valid - * Authentication, including the GrantedAuthority[]s - * that apply. - *

+ * Represents a remembered Authentication.

A remembered Authentication must provide a + * fully valid Authentication, including the GrantedAuthority[]s that apply.

* * @author Ben Alex * @version $Id$ */ -public class RememberMeAuthenticationToken extends AbstractAuthenticationToken - implements Serializable { - //~ Instance fields ======================================================== +public class RememberMeAuthenticationToken extends AbstractAuthenticationToken implements Serializable { + //~ Instance fields ================================================================================================ private Object principal; private int keyHash; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor. * * @param key to identify if this object made by an authorised client @@ -54,21 +48,17 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken * * @throws IllegalArgumentException if a null was passed */ - public RememberMeAuthenticationToken(String key, Object principal, - GrantedAuthority[] authorities) { + public RememberMeAuthenticationToken(String key, Object principal, GrantedAuthority[] authorities) { super(authorities); - if ((key == null) || ("".equals(key)) || (principal == null) - || "".equals(principal) || (authorities == null) + if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (authorities == null) || (authorities.length == 0)) { - throw new IllegalArgumentException( - "Cannot pass null or empty values to constructor"); + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); } for (int i = 0; i < authorities.length; i++) { Assert.notNull(authorities[i], - "Granted authority element " + i - + " is null - GrantedAuthority[] cannot contain any null elements"); + "Granted authority element " + i + " is null - GrantedAuthority[] cannot contain any null elements"); } this.keyHash = key.hashCode(); @@ -76,7 +66,7 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken setAuthenticated(true); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object obj) { if (!super.equals(obj)) { diff --git a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java index d62fef6ce5..654ba16204 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java @@ -40,58 +40,44 @@ import java.security.cert.X509Certificate; /** - * Processes an X.509 authentication request. - * - *

- * The request will typically originate from {@link - * org.acegisecurity.ui.x509.X509ProcessingFilter}). - *

+ * Processes an X.509 authentication request.

The request will typically originate from {@link + * org.acegisecurity.ui.x509.X509ProcessingFilter}).

* * @author Luke Taylor * @version $Id$ */ -public class X509AuthenticationProvider implements AuthenticationProvider, - InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class X509AuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private X509AuthoritiesPopulator x509AuthoritiesPopulator; private X509UserCache userCache = new NullX509UserCache(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(userCache, "An x509UserCache must be set"); - Assert.notNull(x509AuthoritiesPopulator, - "An X509AuthoritiesPopulator must be set"); + Assert.notNull(x509AuthoritiesPopulator, "An X509AuthoritiesPopulator must be set"); Assert.notNull(this.messages, "A message source must be set"); } /** - * If the supplied authentication token contains a certificate then this - * will be passed to the configured {@link X509AuthoritiesPopulator} to - * obtain the user details and authorities for the user identified by the - * certificate. - * - *

- * If no certificate is present (for example, if the filter is applied to - * an HttpRequest for which client authentication hasn't been configured - * in the container) then a BadCredentialsException will be raised. - *

+ * If the supplied authentication token contains a certificate then this will be passed to the configured + * {@link X509AuthoritiesPopulator} to obtain the user details and authorities for the user identified by the + * certificate.

If no certificate is present (for example, if the filter is applied to an HttpRequest for + * which client authentication hasn't been configured in the container) then a BadCredentialsException will be + * raised.

* * @param authentication the authentication request. * - * @return an X509AuthenticationToken containing the authorities of the - * principal represented by the certificate. + * @return an X509AuthenticationToken containing the authorities of the principal represented by the certificate. * - * @throws AuthenticationException if the {@link X509AuthoritiesPopulator} - * rejects the certficate. - * @throws BadCredentialsException if no certificate was presented in the - * authentication request. + * @throws AuthenticationException if the {@link X509AuthoritiesPopulator} rejects the certficate. + * @throws BadCredentialsException if no certificate was presented in the authentication request. */ public Authentication authenticate(Authentication authentication) throws AuthenticationException { @@ -103,12 +89,10 @@ public class X509AuthenticationProvider implements AuthenticationProvider, logger.debug("X509 authentication request: " + authentication); } - X509Certificate clientCertificate = (X509Certificate) authentication - .getCredentials(); + X509Certificate clientCertificate = (X509Certificate) authentication.getCredentials(); if (clientCertificate == null) { - throw new BadCredentialsException(messages.getMessage( - "X509AuthenticationProvider.certificateNull", + throw new BadCredentialsException(messages.getMessage("X509AuthenticationProvider.certificateNull", "Certificate is null")); } @@ -120,8 +104,7 @@ public class X509AuthenticationProvider implements AuthenticationProvider, userCache.putUserInCache(clientCertificate, user); } - X509AuthenticationToken result = new X509AuthenticationToken(user, - clientCertificate, user.getAuthorities()); + X509AuthenticationToken result = new X509AuthenticationToken(user, clientCertificate, user.getAuthorities()); result.setDetails(authentication.getDetails()); @@ -132,8 +115,7 @@ public class X509AuthenticationProvider implements AuthenticationProvider, this.messages = new MessageSourceAccessor(messageSource); } - public void setX509AuthoritiesPopulator( - X509AuthoritiesPopulator x509AuthoritiesPopulator) { + public void setX509AuthoritiesPopulator(X509AuthoritiesPopulator x509AuthoritiesPopulator) { this.x509AuthoritiesPopulator = x509AuthoritiesPopulator; } diff --git a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationToken.java index 33f9f4aefe..d6ec9468ce 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationToken.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationToken.java @@ -23,21 +23,20 @@ import java.security.cert.X509Certificate; /** - * Authentication implementation for X.509 client-certificate - * authentication. + * Authentication implementation for X.509 client-certificate authentication. * * @author Luke Taylor * @version $Id$ */ public class X509AuthenticationToken extends AbstractAuthenticationToken { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object principal; private X509Certificate credentials; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Used for an authentication request. The {@link * Authentication#isAuthenticated()} will return false. * @@ -48,7 +47,7 @@ public class X509AuthenticationToken extends AbstractAuthenticationToken { this.credentials = credentials; } - /** +/** * Used for an authentication response object. The {@link * Authentication#isAuthenticated()} will return true. * @@ -57,15 +56,14 @@ public class X509AuthenticationToken extends AbstractAuthenticationToken { * @param credentials the certificate * @param authorities the authorities */ - public X509AuthenticationToken(Object principal, - X509Certificate credentials, GrantedAuthority[] authorities) { + public X509AuthenticationToken(Object principal, X509Certificate credentials, GrantedAuthority[] authorities) { super(authorities); this.principal = principal; this.credentials = credentials; setAuthenticated(true); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return credentials; diff --git a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthoritiesPopulator.java index 450e1d3f80..ae57f60994 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,12 @@ package org.acegisecurity.providers.x509; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.userdetails.UserDetails; import java.security.cert.X509Certificate; + /** * Populates the UserDetails associated with the X.509 * certificate presented by a client. @@ -34,23 +36,19 @@ import java.security.cert.X509Certificate; * @version $Id$ */ public interface X509AuthoritiesPopulator { + //~ Methods ======================================================================================================== + /** - * Obtains the granted authorities for the specified user. - * - *

- * May throw any AuthenticationException or return - * null if the authorities are unavailable. - *

+ * Obtains the granted authorities for the specified user.

May throw any + * AuthenticationException or return null if the authorities are unavailable.

* * @param userCertificate the X.509 certificate supplied * - * @return the details of the indicated user (at minimum the granted - * authorities and the username) + * @return the details of the indicated user (at minimum the granted authorities and the username) * - * @throws org.acegisecurity.AuthenticationException if the user details are not available - * or the certificate isn't valid for the application's purpose. + * @throws AuthenticationException if the user details are not available or the certificate isn't valid for the + * application's purpose. */ UserDetails getUserDetails(X509Certificate userCertificate) throws AuthenticationException; - } diff --git a/core/src/main/java/org/acegisecurity/providers/x509/X509UserCache.java b/core/src/main/java/org/acegisecurity/providers/x509/X509UserCache.java index de91bf6486..f38727c383 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/X509UserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/X509UserCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import org.acegisecurity.userdetails.UserDetails; import java.security.cert.X509Certificate; + /** * Provides a cache of {@link UserDetails} objects for the * {@link X509AuthenticationProvider}. @@ -32,6 +33,7 @@ import java.security.cert.X509Certificate; * @version $Id$ */ public interface X509UserCache { + //~ Methods ======================================================================================================== UserDetails getUserFromCache(X509Certificate userCertificate); diff --git a/core/src/main/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCache.java b/core/src/main/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCache.java index 1e9ccf3b6d..a98e0c442d 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCache.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,14 @@ package org.acegisecurity.providers.x509.cache; -import org.acegisecurity.providers.x509.X509UserCache; -import org.acegisecurity.userdetails.UserDetails; - import net.sf.ehcache.Cache; import net.sf.ehcache.CacheException; import net.sf.ehcache.Element; +import org.acegisecurity.providers.x509.X509UserCache; + +import org.acegisecurity.userdetails.UserDetails; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -42,20 +43,19 @@ import java.security.cert.X509Certificate; * @author Ben Alex * @version $Id$ */ -public class EhCacheBasedX509UserCache implements X509UserCache, - InitializingBean { - //~ Static fields/initializers ============================================= +public class EhCacheBasedX509UserCache implements X509UserCache, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(EhCacheBasedX509UserCache.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Cache cache; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setCache(Cache cache) { - this.cache = cache; + public void afterPropertiesSet() throws Exception { + Assert.notNull(cache, "cache is mandatory"); } public UserDetails getUserFromCache(X509Certificate userCert) { @@ -64,8 +64,7 @@ public class EhCacheBasedX509UserCache implements X509UserCache, try { element = cache.get(userCert); } catch (CacheException cacheException) { - throw new DataRetrievalFailureException("Cache failure: " - + cacheException.getMessage()); + throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage()); } if (logger.isDebugEnabled()) { @@ -85,10 +84,6 @@ public class EhCacheBasedX509UserCache implements X509UserCache, } } - public void afterPropertiesSet() throws Exception { - Assert.notNull(cache, "cache is mandatory"); - } - public void putUserInCache(X509Certificate userCert, UserDetails user) { Element element = new Element(userCert, user); @@ -106,4 +101,8 @@ public class EhCacheBasedX509UserCache implements X509UserCache, cache.remove(userCert); } + + public void setCache(Cache cache) { + this.cache = cache; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/x509/cache/NullX509UserCache.java b/core/src/main/java/org/acegisecurity/providers/x509/cache/NullX509UserCache.java index 7a7118bbb1..f26d03155c 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/cache/NullX509UserCache.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/cache/NullX509UserCache.java @@ -1,10 +1,27 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.x509.cache; import org.acegisecurity.providers.x509.X509UserCache; + import org.acegisecurity.userdetails.UserDetails; import java.security.cert.X509Certificate; + /** * "Cache" that doesn't do any caching. * @@ -12,7 +29,7 @@ import java.security.cert.X509Certificate; * @version $Id$ */ public class NullX509UserCache implements X509UserCache { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public UserDetails getUserFromCache(X509Certificate certificate) { return null; diff --git a/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java index 785dee7b83..dc2de3b923 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,50 +15,55 @@ package org.acegisecurity.providers.x509.populator; -import java.security.cert.X509Certificate; - import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.x509.X509AuthoritiesPopulator; + import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.MatchResult; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.security.cert.X509Certificate; + /** - * Populates the X509 authorities via an {@link - * org.acegisecurity.userdetails.UserDetailsService}. + * Populates the X509 authorities via an {@link org.acegisecurity.userdetails.UserDetailsService}. * * @author Luke Taylor * @version $Id$ */ -public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, - InitializingBean, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - private UserDetailsService userDetailsService; protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private Pattern subjectDNPattern; private String subjectDNRegex = "CN=(.*?),"; + private UserDetailsService userDetailsService; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(userDetailsService, "An authenticationDao must be set"); @@ -68,11 +73,9 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, try { subjectDNPattern = compiler.compile(subjectDNRegex, - Perl5Compiler.READ_ONLY_MASK - | Perl5Compiler.CASE_INSENSITIVE_MASK); + Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK); } catch (MalformedPatternException mpe) { - throw new IllegalArgumentException("Malformed regular expression: " - + subjectDNRegex); + throw new IllegalArgumentException("Malformed regular expression: " + subjectDNRegex); } } @@ -82,17 +85,14 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, PatternMatcher matcher = new Perl5Matcher(); if (!matcher.contains(subjectDN, subjectDNPattern)) { - throw new BadCredentialsException(messages.getMessage( - "DaoX509AuthoritiesPopulator.noMatching", - new Object[] {subjectDN}, - "No matching pattern was found in subjectDN: {0}")); + throw new BadCredentialsException(messages.getMessage("DaoX509AuthoritiesPopulator.noMatching", + new Object[] {subjectDN}, "No matching pattern was found in subjectDN: {0}")); } MatchResult match = matcher.getMatch(); if (match.groups() != 2) { // 2 = 1 + the entire match - throw new IllegalArgumentException( - "Regular expression must contain a single group "); + throw new IllegalArgumentException("Regular expression must contain a single group "); } String userName = match.group(1); @@ -100,31 +100,24 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, return this.userDetailsService.loadUserByUsername(userName); } - public void setUserDetailsService(UserDetailsService authenticationDao) { - this.userDetailsService = authenticationDao; - } - public void setMessageSource(MessageSource messageSource) { this.messages = new MessageSourceAccessor(messageSource); } /** - * Sets the regular expression which will by used to extract the user name - * from the certificate's Subject DN. - * - *

- * It should contain a single group; for example the default expression - * "CN=(.*?)," matches the common name field. So "CN=Jimi Hendrix, OU=..." - * will give a user name of "Jimi Hendrix". - *

- *

- * The matches are case insensitive. So "emailAddress=(.*?)," will match - * "EMAILADDRESS=jimi@hendrix.org, CN=..." giving a user name "jimi@hendrix.org" - *

+ * Sets the regular expression which will by used to extract the user name from the certificate's Subject + * DN.

It should contain a single group; for example the default expression "CN=(.?)," matches the common + * name field. So "CN=Jimi Hendrix, OU=..." will give a user name of "Jimi Hendrix".

+ *

The matches are case insensitive. So "emailAddress=(.?)," will match "EMAILADDRESS=jimi@hendrix.org, + * CN=..." giving a user name "jimi@hendrix.org"

* * @param subjectDNRegex the regular expression to find in the subject */ public void setSubjectDNRegex(String subjectDNRegex) { this.subjectDNRegex = subjectDNRegex; } + + public void setUserDetailsService(UserDetailsService authenticationDao) { + this.userDetailsService = authenticationDao; + } } diff --git a/core/src/main/java/org/acegisecurity/runas/NullRunAsManager.java b/core/src/main/java/org/acegisecurity/runas/NullRunAsManager.java index 1480d51a31..937db2d71d 100644 --- a/core/src/main/java/org/acegisecurity/runas/NullRunAsManager.java +++ b/core/src/main/java/org/acegisecurity/runas/NullRunAsManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,21 +22,16 @@ import org.acegisecurity.RunAsManager; /** - * Implementation of a {@link RunAsManager} that does nothing. - * - *

- * This class should be used if you do not require run-as authenticaiton - * replacement functionality. - *

+ * Implementation of a {@link RunAsManager} that does nothing.

This class should be used if you do not require + * run-as authenticaiton replacement functionality.

* * @author Ben Alex * @version $Id$ */ public class NullRunAsManager implements RunAsManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public Authentication buildRunAs(Authentication authentication, - Object object, ConfigAttributeDefinition config) { + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) { return null; } diff --git a/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java index 37fdfdd4ba..c68997124c 100644 --- a/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,41 +19,35 @@ import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; /** - * An {@link AuthenticationProvider} implementation that can authenticate a - * {@link RunAsUserToken}. - * - *

- * Configured in the bean context with a key that should match the key used by - * adapters to generate the RunAsUserToken. It treats as valid - * any RunAsUserToken instance presenting a hash code that - * matches the RunAsImplAuthenticationProvider-configured key. - *

- * - *

- * If the key does not match, a BadCredentialsException is thrown. - *

+ * An {@link AuthenticationProvider} implementation that can authenticate a {@link RunAsUserToken}.

Configured in + * the bean context with a key that should match the key used by adapters to generate the RunAsUserToken. + * It treats as valid any RunAsUserToken instance presenting a hash code that matches the + * RunAsImplAuthenticationProvider-configured key.

+ *

If the key does not match, a BadCredentialsException is thrown.

*/ -public class RunAsImplAuthenticationProvider implements InitializingBean, - AuthenticationProvider, MessageSourceAware { - //~ Instance fields ======================================================== +public class RunAsImplAuthenticationProvider implements InitializingBean, AuthenticationProvider, MessageSourceAware { + //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private String key; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(key, - "A Key is required and should match that configured for the RunAsManagerImpl"); + Assert.notNull(key, "A Key is required and should match that configured for the RunAsManagerImpl"); } public Authentication authenticate(Authentication authentication) @@ -63,8 +57,7 @@ public class RunAsImplAuthenticationProvider implements InitializingBean, if (token.getKeyHash() == key.hashCode()) { return authentication; } else { - throw new BadCredentialsException(messages.getMessage( - "RunAsImplAuthenticationProvider.incorrectKey", + throw new BadCredentialsException(messages.getMessage("RunAsImplAuthenticationProvider.incorrectKey", "The presented RunAsUserToken does not contain the expected key")); } } diff --git a/core/src/main/java/org/acegisecurity/runas/RunAsManagerImpl.java b/core/src/main/java/org/acegisecurity/runas/RunAsManagerImpl.java index d79a246b9f..193fa85114 100644 --- a/core/src/main/java/org/acegisecurity/runas/RunAsManagerImpl.java +++ b/core/src/main/java/org/acegisecurity/runas/RunAsManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.RunAsManager; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.util.Iterator; @@ -31,75 +32,39 @@ import java.util.Vector; /** - * Basic concrete implementation of a {@link RunAsManager}. - * - *

- * Is activated if any {@link ConfigAttribute#getAttribute()} is prefixed with - * RUN_AS_. If found, it generates a new {@link RunAsUserToken} - * containing the same principal, credentials and granted authorities as the - * original {@link Authentication} object, along with {@link - * GrantedAuthorityImpl}s for each RUN_AS_ indicated. The created - * GrantedAuthorityImpls will be prefixed with a special prefix - * indicating that it is a role (default prefix value is ROLE_), - * and then the remainder of the RUN_AS_ keyword. For example, - * RUN_AS_FOO will result in the creation of a granted authority - * of ROLE_RUN_AS_FOO. - *

- * - *

- * The role prefix may be overriden from the default, to match that used - * elsewhere, for example when using an existing role database with another - * prefix. An empty role prefix may also be specified. Note however that there - * are potential issues with using an empty role prefix since different - * categories of {@link org.acegisecurity.ConfigAttribute} can not be - * properly discerned based on the prefix, with possible consequences when - * performing voting and other actions. However, this option may be of some - * use when using preexisting role names without a prefix, and no ability - * exists to prefix them with a role prefix on reading them in, such as - * provided for example in {@link - * org.acegisecurity.userdetails.jdbc.JdbcDaoImpl}. - *

+ * Basic concrete implementation of a {@link RunAsManager}.

Is activated if any {@link + * ConfigAttribute#getAttribute()} is prefixed with RUN_AS_. If found, it generates a new {@link + * RunAsUserToken} containing the same principal, credentials and granted authorities as the original {@link + * Authentication} object, along with {@link GrantedAuthorityImpl}s for each RUN_AS_ indicated. The + * created GrantedAuthorityImpls will be prefixed with a special prefix indicating that it is a role + * (default prefix value is ROLE_), and then the remainder of the RUN_AS_ keyword. For + * example, RUN_AS_FOO will result in the creation of a granted authority of + * ROLE_RUN_AS_FOO.

+ *

The role prefix may be overriden from the default, to match that used elsewhere, for example when using an + * existing role database with another prefix. An empty role prefix may also be specified. Note however that there are + * potential issues with using an empty role prefix since different categories of {@link + * org.acegisecurity.ConfigAttribute} can not be properly discerned based on the prefix, with possible consequences + * when performing voting and other actions. However, this option may be of some use when using preexisting role names + * without a prefix, and no ability exists to prefix them with a role prefix on reading them in, such as provided for + * example in {@link org.acegisecurity.userdetails.jdbc.JdbcDaoImpl}.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class RunAsManagerImpl implements RunAsManager, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String key; private String rolePrefix = "ROLE_"; - //~ Methods ================================================================ - - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; - } - - /** - * Allows the default role prefix of ROLE_ to be overriden. - * May be set to an empty value, although this is usually not desireable. - * - * @param rolePrefix the new prefix - */ - public void setRolePrefix(String rolePrefix) { - this.rolePrefix = rolePrefix; - } - - public String getRolePrefix() { - return rolePrefix; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(key, "A Key is required and should match that configured for the RunAsImplAuthenticationProvider"); } - public Authentication buildRunAs(Authentication authentication, - Object object, ConfigAttributeDefinition config) { + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) { List newAuthorities = new Vector(); Iterator iter = config.getConfigAttributes(); @@ -121,18 +86,37 @@ public class RunAsManagerImpl implements RunAsManager, InitializingBean { } GrantedAuthority[] resultType = {new GrantedAuthorityImpl("holder")}; - GrantedAuthority[] newAuthoritiesAsArray = (GrantedAuthority[]) newAuthorities - .toArray(resultType); + GrantedAuthority[] newAuthoritiesAsArray = (GrantedAuthority[]) newAuthorities.toArray(resultType); - return new RunAsUserToken(this.key, authentication.getPrincipal(), - authentication.getCredentials(), newAuthoritiesAsArray, - authentication.getClass()); + return new RunAsUserToken(this.key, authentication.getPrincipal(), authentication.getCredentials(), + newAuthoritiesAsArray, authentication.getClass()); } } + public String getKey() { + return key; + } + + public String getRolePrefix() { + return rolePrefix; + } + + public void setKey(String key) { + this.key = key; + } + + /** + * Allows the default role prefix of ROLE_ to be overriden. May be set to an empty value, + * although this is usually not desireable. + * + * @param rolePrefix the new prefix + */ + public void setRolePrefix(String rolePrefix) { + this.rolePrefix = rolePrefix; + } + public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) - && attribute.getAttribute().startsWith("RUN_AS_")) { + if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith("RUN_AS_")) { return true; } else { return false; @@ -140,8 +124,7 @@ public class RunAsManagerImpl implements RunAsManager, InitializingBean { } /** - * This implementation supports any type of class, because it does not - * query the presented secure object. + * This implementation supports any type of class, because it does not query the presented secure object. * * @param clazz the secure object * diff --git a/core/src/main/java/org/acegisecurity/runas/RunAsUserToken.java b/core/src/main/java/org/acegisecurity/runas/RunAsUserToken.java index c01d37cfe7..5ba1a26470 100644 --- a/core/src/main/java/org/acegisecurity/runas/RunAsUserToken.java +++ b/core/src/main/java/org/acegisecurity/runas/RunAsUserToken.java @@ -21,24 +21,23 @@ import org.acegisecurity.providers.AbstractAuthenticationToken; /** - * An immutable {@link org.acegisecurity.Authentication} implementation that - * supports {@link RunAsManagerImpl}. + * An immutable {@link org.acegisecurity.Authentication} implementation that supports {@link RunAsManagerImpl}. * * @author Ben Alex * @version $Id$ */ public class RunAsUserToken extends AbstractAuthenticationToken { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Class originalAuthentication; private Object credentials; private Object principal; private int keyHash; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public RunAsUserToken(String key, Object principal, Object credentials, - GrantedAuthority[] authorities, Class originalAuthentication) { + public RunAsUserToken(String key, Object principal, Object credentials, GrantedAuthority[] authorities, + Class originalAuthentication) { super(authorities); this.keyHash = key.hashCode(); this.principal = principal; @@ -47,7 +46,7 @@ public class RunAsUserToken extends AbstractAuthenticationToken { setAuthenticated(true); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return this.credentials; @@ -67,8 +66,7 @@ public class RunAsUserToken extends AbstractAuthenticationToken { public String toString() { StringBuffer sb = new StringBuffer(super.toString()); - sb.append("; Original Class: ") - .append(this.originalAuthentication.getName()); + sb.append("; Original Class: ").append(this.originalAuthentication.getName()); return sb.toString(); } diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java index eee2c5e861..c83eccbd18 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.securechannel; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.intercept.web.FilterInvocation; import java.io.IOException; @@ -37,31 +38,30 @@ import javax.servlet.ServletException; * @version $Id$ */ public interface ChannelDecisionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Decided whether the presented {@link FilterInvocation} provides the - * appropriate level of channel security based on the requested {@link - * ConfigAttributeDefinition}. + * Decided whether the presented {@link FilterInvocation} provides the appropriate level of channel + * security based on the requested {@link ConfigAttributeDefinition}. + * + * @param invocation DOCUMENT ME! + * @param config DOCUMENT ME! + * + * @throws IOException DOCUMENT ME! + * @throws ServletException DOCUMENT ME! */ - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException; + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException; /** - * Indicates whether this ChannelDecisionManager is able to - * process the passed ConfigAttribute. - * - *

- * This allows the ChannelProcessingFilter to check every - * configuration attribute can be consumed by the configured - * ChannelDecisionManager. - *

+ * Indicates whether this ChannelDecisionManager is able to process the passed + * ConfigAttribute.

This allows the ChannelProcessingFilter to check every + * configuration attribute can be consumed by the configured ChannelDecisionManager.

* - * @param attribute a configuration attribute that has been configured - * against the ChannelProcessingFilter + * @param attribute a configuration attribute that has been configured against the + * ChannelProcessingFilter * - * @return true if this ChannelDecisionManager can support the - * passed configuration attribute + * @return true if this ChannelDecisionManager can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); } diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java index 4d876a1550..95d8d21c32 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.securechannel; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.intercept.web.FilterInvocation; import org.springframework.beans.factory.InitializingBean; @@ -30,31 +31,50 @@ import javax.servlet.ServletException; /** - * Implementation of {@link ChannelDecisionManager}. - * - *

- * Iterates through each configured {@link ChannelProcessor}. If a - * ChannelProcessor has any issue with the security of the - * request, it should cause a redirect, exception or whatever other action is - * appropriate for the ChannelProcessor implementation. - *

- * - *

- * Once any response is committed (ie a redirect is written to the response - * object), the ChannelDecisionManagerImpl will not iterate - * through any further ChannelProcessors. - *

+ * Implementation of {@link ChannelDecisionManager}.

Iterates through each configured {@link ChannelProcessor}. + * If a ChannelProcessor has any issue with the security of the request, it should cause a redirect, + * exception or whatever other action is appropriate for the ChannelProcessor implementation.

+ *

Once any response is committed (ie a redirect is written to the response object), the + * ChannelDecisionManagerImpl will not iterate through any further ChannelProcessors.

* * @author Ben Alex * @version $Id$ */ -public class ChannelDecisionManagerImpl implements ChannelDecisionManager, - InitializingBean { - //~ Instance fields ======================================================== +public class ChannelDecisionManagerImpl implements ChannelDecisionManager, InitializingBean { + //~ Instance fields ================================================================================================ private List channelProcessors; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void afterPropertiesSet() throws Exception { + checkIfValidList(this.channelProcessors); + } + + private void checkIfValidList(List listToCheck) { + if ((listToCheck == null) || (listToCheck.size() == 0)) { + throw new IllegalArgumentException("A list of ChannelProcessors is required"); + } + } + + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException { + Iterator iter = this.channelProcessors.iterator(); + + while (iter.hasNext()) { + ChannelProcessor processor = (ChannelProcessor) iter.next(); + + processor.decide(invocation, config); + + if (invocation.getResponse().isCommitted()) { + break; + } + } + } + + public List getChannelProcessors() { + return this.channelProcessors; + } public void setChannelProcessors(List newList) { checkIfValidList(newList); @@ -69,8 +89,7 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager, ChannelProcessor attemptToCast = (ChannelProcessor) currentObject; } catch (ClassCastException cce) { - throw new IllegalArgumentException("ChannelProcessor " - + currentObject.getClass().getName() + throw new IllegalArgumentException("ChannelProcessor " + currentObject.getClass().getName() + " must implement ChannelProcessor"); } } @@ -78,29 +97,6 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager, this.channelProcessors = newList; } - public List getChannelProcessors() { - return this.channelProcessors; - } - - public void afterPropertiesSet() throws Exception { - checkIfValidList(this.channelProcessors); - } - - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException { - Iterator iter = this.channelProcessors.iterator(); - - while (iter.hasNext()) { - ChannelProcessor processor = (ChannelProcessor) iter.next(); - - processor.decide(invocation, config); - - if (invocation.getResponse().isCommitted()) { - break; - } - } - } - public boolean supports(ConfigAttribute attribute) { Iterator iter = this.channelProcessors.iterator(); @@ -114,11 +110,4 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager, return false; } - - private void checkIfValidList(List listToCheck) { - if ((listToCheck == null) || (listToCheck.size() == 0)) { - throw new IllegalArgumentException( - "A list of ChannelProcessors is required"); - } - } } diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelEntryPoint.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelEntryPoint.java index 40f3fd6dcd..ec98ad10dc 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,19 +36,18 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public interface ChannelEntryPoint { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Commences a secure channel. - * - *

- * Implementations should modify the headers on the - * ServletResponse as necessary to commence the user agent - * using the implementation's supported channel type. - *

+ * Commences a secure channel.

Implementations should modify the headers on the + * ServletResponse as necessary to commence the user agent using the implementation's supported + * channel type.

* * @param request that a ChannelProcessor has rejected * @param response so that the user agent can begin using a new channel + * + * @throws IOException DOCUMENT ME! + * @throws ServletException DOCUMENT ME! */ public void commence(ServletRequest request, ServletResponse response) throws IOException, ServletException; diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java index 199ce310fe..d239410cc3 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java @@ -45,49 +45,35 @@ import javax.servlet.http.HttpServletResponse; /** - * Ensures a web request is delivered over the required channel. - * - *

- * Internally uses a {@link FilterInvocation} to represent the request, so that - * the FilterInvocation-related property editors and lookup - * classes can be used. - *

- * - *

- * Delegates the actual channel security decisions and necessary actions to the - * configured {@link ChannelDecisionManager}. If a response is committed by - * the ChannelDecisionManager, the filter chain will not proceed. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Ensures a web request is delivered over the required channel.

Internally uses a {@link FilterInvocation} to + * represent the request, so that the FilterInvocation-related property editors and lookup classes can be + * used.

+ *

Delegates the actual channel security decisions and necessary actions to the configured {@link + * ChannelDecisionManager}. If a response is committed by the ChannelDecisionManager, the filter chain + * will not proceed.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ public class ChannelProcessingFilter implements InitializingBean, Filter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(ChannelProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ChannelDecisionManager channelDecisionManager; private FilterInvocationDefinitionSource filterInvocationDefinitionSource; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(filterInvocationDefinitionSource, - "filterInvocationDefinitionSource must be specified"); - Assert.notNull(channelDecisionManager, - "channelDecisionManager must be specified"); + Assert.notNull(filterInvocationDefinitionSource, "filterInvocationDefinitionSource must be specified"); + Assert.notNull(channelDecisionManager, "channelDecisionManager must be specified"); - Iterator iter = this.filterInvocationDefinitionSource - .getConfigAttributeDefinitions(); + Iterator iter = this.filterInvocationDefinitionSource.getConfigAttributeDefinitions(); if (iter == null) { if (logger.isWarnEnabled()) { @@ -101,8 +87,7 @@ public class ChannelProcessingFilter implements InitializingBean, Filter { Set set = new HashSet(); while (iter.hasNext()) { - ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter - .next(); + ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter.next(); Iterator attributes = def.getConfigAttributes(); while (attributes.hasNext()) { @@ -119,15 +104,14 @@ public class ChannelProcessingFilter implements InitializingBean, Filter { logger.info("Validated configuration attributes"); } } else { - throw new IllegalArgumentException( - "Unsupported configuration attributes: " + set.toString()); + throw new IllegalArgumentException("Unsupported configuration attributes: " + set.toString()); } } public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("HttpServletRequest required"); } @@ -137,13 +121,11 @@ public class ChannelProcessingFilter implements InitializingBean, Filter { } FilterInvocation fi = new FilterInvocation(request, response, chain); - ConfigAttributeDefinition attr = this.filterInvocationDefinitionSource - .getAttributes(fi); + ConfigAttributeDefinition attr = this.filterInvocationDefinitionSource.getAttributes(fi); if (attr != null) { if (logger.isDebugEnabled()) { - logger.debug("Request: " + fi.toString() - + "; ConfigAttributes: " + attr.toString()); + logger.debug("Request: " + fi.toString() + "; ConfigAttributes: " + attr.toString()); } channelDecisionManager.decide(fi, attr); @@ -166,13 +148,11 @@ public class ChannelProcessingFilter implements InitializingBean, Filter { public void init(FilterConfig filterConfig) throws ServletException {} - public void setChannelDecisionManager( - ChannelDecisionManager channelDecisionManager) { + public void setChannelDecisionManager(ChannelDecisionManager channelDecisionManager) { this.channelDecisionManager = channelDecisionManager; } - public void setFilterInvocationDefinitionSource( - FilterInvocationDefinitionSource filterInvocationDefinitionSource) { + public void setFilterInvocationDefinitionSource(FilterInvocationDefinitionSource filterInvocationDefinitionSource) { this.filterInvocationDefinitionSource = filterInvocationDefinitionSource; } } diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java index 7b5467c276..c33957f4ab 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.securechannel; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.intercept.web.FilterInvocation; import java.io.IOException; @@ -42,31 +43,30 @@ import javax.servlet.ServletException; * @version $Id$ */ public interface ChannelProcessor { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Decided whether the presented {@link FilterInvocation} provides the - * appropriate level of channel security based on the requested {@link - * ConfigAttributeDefinition}. + * Decided whether the presented {@link FilterInvocation} provides the appropriate level of channel + * security based on the requested {@link ConfigAttributeDefinition}. + * + * @param invocation DOCUMENT ME! + * @param config DOCUMENT ME! + * + * @throws IOException DOCUMENT ME! + * @throws ServletException DOCUMENT ME! */ - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException; + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException; /** - * Indicates whether this ChannelProcessor is able to process - * the passed ConfigAttribute. - * - *

- * This allows the ChannelProcessingFilter to check every - * configuration attribute can be consumed by the configured - * ChannelDecisionManager. - *

+ * Indicates whether this ChannelProcessor is able to process the passed + * ConfigAttribute.

This allows the ChannelProcessingFilter to check every + * configuration attribute can be consumed by the configured ChannelDecisionManager.

* - * @param attribute a configuration attribute that has been configured - * against the ChannelProcessingFilter + * @param attribute a configuration attribute that has been configured against the + * ChannelProcessingFilter * - * @return true if this ChannelProcessor can support the - * passed configuration attribute + * @return true if this ChannelProcessor can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); } diff --git a/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java index d055f3b12a..117ad7aa22 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,11 @@ package org.acegisecurity.securechannel; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.intercept.web.FilterInvocation; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.io.IOException; @@ -30,60 +32,31 @@ import javax.servlet.ServletException; /** - *

- * Ensures channel security is inactive by review of - * HttpServletRequest.isSecure() responses. - *

- * - *

- * The class responds to one case-sensitive keyword, {@link - * #getInsecureKeyword}. If this keyword is detected, - * HttpServletRequest.isSecure() is used to determine the channel - * security offered. If channel security is present, the configured - * ChannelEntryPoint is called. By default the entry point is - * {@link RetryWithHttpEntryPoint}. - *

- * - *

- * The default insecureKeyword is - * REQUIRES_INSECURE_CHANNEL. - *

+ *

Ensures channel security is inactive by review of HttpServletRequest.isSecure() responses.

+ *

The class responds to one case-sensitive keyword, {@link #getInsecureKeyword}. If this keyword is detected, + * HttpServletRequest.isSecure() is used to determine the channel security offered. If channel security + * is present, the configured ChannelEntryPoint is called. By default the entry point is {@link + * RetryWithHttpEntryPoint}.

+ *

The default insecureKeyword is REQUIRES_INSECURE_CHANNEL.

* * @author Ben Alex * @version $Id$ */ -public class InsecureChannelProcessor implements InitializingBean, - ChannelProcessor { - //~ Instance fields ======================================================== +public class InsecureChannelProcessor implements InitializingBean, ChannelProcessor { + //~ Instance fields ================================================================================================ private ChannelEntryPoint entryPoint = new RetryWithHttpEntryPoint(); private String insecureKeyword = "REQUIRES_INSECURE_CHANNEL"; - //~ Methods ================================================================ - - public void setEntryPoint(ChannelEntryPoint entryPoint) { - this.entryPoint = entryPoint; - } - - public ChannelEntryPoint getEntryPoint() { - return entryPoint; - } - - public void setInsecureKeyword(String secureKeyword) { - this.insecureKeyword = secureKeyword; - } - - public String getInsecureKeyword() { - return insecureKeyword; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(insecureKeyword, "insecureKeyword required"); Assert.notNull(entryPoint, "entryPoint required"); } - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException { + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException { if ((invocation == null) || (config == null)) { throw new IllegalArgumentException("Nulls cannot be provided"); } @@ -95,13 +68,28 @@ public class InsecureChannelProcessor implements InitializingBean, if (supports(attribute)) { if (invocation.getHttpRequest().isSecure()) { - entryPoint.commence(invocation.getRequest(), - invocation.getResponse()); + entryPoint.commence(invocation.getRequest(), invocation.getResponse()); } } } } + public ChannelEntryPoint getEntryPoint() { + return entryPoint; + } + + public String getInsecureKeyword() { + return insecureKeyword; + } + + public void setEntryPoint(ChannelEntryPoint entryPoint) { + this.entryPoint = entryPoint; + } + + public void setInsecureKeyword(String secureKeyword) { + this.insecureKeyword = secureKeyword; + } + public boolean supports(ConfigAttribute attribute) { if ((attribute != null) && (attribute.getAttribute() != null) && attribute.getAttribute().equals(getInsecureKeyword())) { diff --git a/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpEntryPoint.java b/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpEntryPoint.java index 45e7c439e6..d57c5f189b 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.io.IOException; @@ -36,45 +37,24 @@ import javax.servlet.http.HttpServletResponse; /** - * Commences an insecure channel by retrying the original request using HTTP. - * - *

- * This entry point should suffice in most circumstances. However, it is not - * intended to properly handle HTTP POSTs or other usage where a standard - * redirect would cause an issue. - *

+ * Commences an insecure channel by retrying the original request using HTTP.

This entry point should suffice in + * most circumstances. However, it is not intended to properly handle HTTP POSTs or other usage where a standard + * redirect would cause an issue.

* * @author Ben Alex * @version $Id$ */ -public class RetryWithHttpEntryPoint implements InitializingBean, - ChannelEntryPoint { - //~ Static fields/initializers ============================================= +public class RetryWithHttpEntryPoint implements InitializingBean, ChannelEntryPoint { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RetryWithHttpEntryPoint.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private PortMapper portMapper = new PortMapperImpl(); private PortResolver portResolver = new PortResolverImpl(); - //~ Methods ================================================================ - - public void setPortMapper(PortMapper portMapper) { - this.portMapper = portMapper; - } - - public PortMapper getPortMapper() { - return portMapper; - } - - public void setPortResolver(PortResolver portResolver) { - this.portResolver = portResolver; - } - - public PortResolver getPortResolver() { - return portResolver; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(portMapper, "portMapper is required"); @@ -88,8 +68,7 @@ public class RetryWithHttpEntryPoint implements InitializingBean, String pathInfo = req.getPathInfo(); String queryString = req.getQueryString(); String contextPath = req.getContextPath(); - String destination = req.getServletPath() - + ((pathInfo == null) ? "" : pathInfo) + String destination = req.getServletPath() + ((pathInfo == null) ? "" : pathInfo) + ((queryString == null) ? "" : ("?" + queryString)); String redirectUrl = contextPath; @@ -104,8 +83,7 @@ public class RetryWithHttpEntryPoint implements InitializingBean, includePort = false; } - redirectUrl = "http://" + req.getServerName() - + ((includePort) ? (":" + httpPort) : "") + contextPath + redirectUrl = "http://" + req.getServerName() + ((includePort) ? (":" + httpPort) : "") + contextPath + destination; } @@ -113,7 +91,22 @@ public class RetryWithHttpEntryPoint implements InitializingBean, logger.debug("Redirecting to: " + redirectUrl); } - ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response) - .encodeRedirectURL(redirectUrl)); + ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response).encodeRedirectURL(redirectUrl)); + } + + public PortMapper getPortMapper() { + return portMapper; + } + + public PortResolver getPortResolver() { + return portResolver; + } + + public void setPortMapper(PortMapper portMapper) { + this.portMapper = portMapper; + } + + public void setPortResolver(PortResolver portResolver) { + this.portResolver = portResolver; } } diff --git a/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPoint.java b/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPoint.java index 1870a26a95..9d2c839a2c 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.io.IOException; @@ -36,45 +37,24 @@ import javax.servlet.http.HttpServletResponse; /** - * Commences a secure channel by retrying the original request using HTTPS. - * - *

- * This entry point should suffice in most circumstances. However, it is not - * intended to properly handle HTTP POSTs or other usage where a standard - * redirect would cause an issue. - *

+ * Commences a secure channel by retrying the original request using HTTPS.

This entry point should suffice in + * most circumstances. However, it is not intended to properly handle HTTP POSTs or other usage where a standard + * redirect would cause an issue.

* * @author Ben Alex * @version $Id$ */ -public class RetryWithHttpsEntryPoint implements InitializingBean, - ChannelEntryPoint { - //~ Static fields/initializers ============================================= +public class RetryWithHttpsEntryPoint implements InitializingBean, ChannelEntryPoint { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RetryWithHttpsEntryPoint.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private PortMapper portMapper = new PortMapperImpl(); private PortResolver portResolver = new PortResolverImpl(); - //~ Methods ================================================================ - - public void setPortMapper(PortMapper portMapper) { - this.portMapper = portMapper; - } - - public PortMapper getPortMapper() { - return portMapper; - } - - public void setPortResolver(PortResolver portResolver) { - this.portResolver = portResolver; - } - - public PortResolver getPortResolver() { - return portResolver; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(portMapper, "portMapper is required"); @@ -88,8 +68,7 @@ public class RetryWithHttpsEntryPoint implements InitializingBean, String pathInfo = req.getPathInfo(); String queryString = req.getQueryString(); String contextPath = req.getContextPath(); - String destination = req.getServletPath() - + ((pathInfo == null) ? "" : pathInfo) + String destination = req.getServletPath() + ((pathInfo == null) ? "" : pathInfo) + ((queryString == null) ? "" : ("?" + queryString)); String redirectUrl = contextPath; @@ -104,8 +83,7 @@ public class RetryWithHttpsEntryPoint implements InitializingBean, includePort = false; } - redirectUrl = "https://" + req.getServerName() - + ((includePort) ? (":" + httpsPort) : "") + contextPath + redirectUrl = "https://" + req.getServerName() + ((includePort) ? (":" + httpsPort) : "") + contextPath + destination; } @@ -113,7 +91,22 @@ public class RetryWithHttpsEntryPoint implements InitializingBean, logger.debug("Redirecting to: " + redirectUrl); } - ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response) - .encodeRedirectURL(redirectUrl)); + ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response).encodeRedirectURL(redirectUrl)); + } + + public PortMapper getPortMapper() { + return portMapper; + } + + public PortResolver getPortResolver() { + return portResolver; + } + + public void setPortMapper(PortMapper portMapper) { + this.portMapper = portMapper; + } + + public void setPortResolver(PortResolver portResolver) { + this.portResolver = portResolver; } } diff --git a/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java index a59672e3f1..28f593b795 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java +++ b/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,11 @@ package org.acegisecurity.securechannel; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.intercept.web.FilterInvocation; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import java.io.IOException; @@ -30,59 +32,31 @@ import javax.servlet.ServletException; /** - *

- * Ensures channel security is active by review of - * HttpServletRequest.isSecure() responses. - *

- * - *

- * The class responds to one case-sensitive keyword, {@link #getSecureKeyword}. - * If this keyword is detected, HttpServletRequest.isSecure() is - * used to determine the channel security offered. If channel security is not - * present, the configured ChannelEntryPoint is called. By - * default the entry point is {@link RetryWithHttpsEntryPoint}. - *

- * - *

- * The default secureKeyword is - * REQUIRES_SECURE_CHANNEL. - *

+ *

Ensures channel security is active by review of HttpServletRequest.isSecure() responses.

+ *

The class responds to one case-sensitive keyword, {@link #getSecureKeyword}. If this keyword is detected, + * HttpServletRequest.isSecure() is used to determine the channel security offered. If channel security + * is not present, the configured ChannelEntryPoint is called. By default the entry point is {@link + * RetryWithHttpsEntryPoint}.

+ *

The default secureKeyword is REQUIRES_SECURE_CHANNEL.

* * @author Ben Alex * @version $Id$ */ -public class SecureChannelProcessor implements InitializingBean, - ChannelProcessor { - //~ Instance fields ======================================================== +public class SecureChannelProcessor implements InitializingBean, ChannelProcessor { + //~ Instance fields ================================================================================================ private ChannelEntryPoint entryPoint = new RetryWithHttpsEntryPoint(); private String secureKeyword = "REQUIRES_SECURE_CHANNEL"; - //~ Methods ================================================================ - - public void setEntryPoint(ChannelEntryPoint entryPoint) { - this.entryPoint = entryPoint; - } - - public ChannelEntryPoint getEntryPoint() { - return entryPoint; - } - - public void setSecureKeyword(String secureKeyword) { - this.secureKeyword = secureKeyword; - } - - public String getSecureKeyword() { - return secureKeyword; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(secureKeyword, "secureKeyword required"); Assert.notNull(entryPoint, "entryPoint required"); } - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) throws IOException, ServletException { + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) + throws IOException, ServletException { Assert.isTrue((invocation != null) && (config != null), "Nulls cannot be provided"); Iterator iter = config.getConfigAttributes(); @@ -92,13 +66,28 @@ public class SecureChannelProcessor implements InitializingBean, if (supports(attribute)) { if (!invocation.getHttpRequest().isSecure()) { - entryPoint.commence(invocation.getRequest(), - invocation.getResponse()); + entryPoint.commence(invocation.getRequest(), invocation.getResponse()); } } } } + public ChannelEntryPoint getEntryPoint() { + return entryPoint; + } + + public String getSecureKeyword() { + return secureKeyword; + } + + public void setEntryPoint(ChannelEntryPoint entryPoint) { + this.entryPoint = entryPoint; + } + + public void setSecureKeyword(String secureKeyword) { + this.secureKeyword = secureKeyword; + } + public boolean supports(ConfigAttribute attribute) { if ((attribute != null) && (attribute.getAttribute() != null) && attribute.getAttribute().equals(getSecureKeyword())) { diff --git a/core/src/main/java/org/acegisecurity/taglibs/authz/AclTag.java b/core/src/main/java/org/acegisecurity/taglibs/authz/AclTag.java index e026075759..d2ba90ce79 100644 --- a/core/src/main/java/org/acegisecurity/taglibs/authz/AclTag.java +++ b/core/src/main/java/org/acegisecurity/taglibs/authz/AclTag.java @@ -45,54 +45,40 @@ import javax.servlet.jsp.tagext.TagSupport; /** - * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows its - * body through if some authorizations are granted to the request's principal. - * - *

- * Only works with permissions that are subclasses of {@link - * org.acegisecurity.acl.basic.BasicAclEntry}. - *

- * - *

- * One or more comma separate integer permissions are specified via the - * hasPermission attribute. The tag will include its body if - * any of the integer permissions have been granted to the current - * Authentication (obtained from the - * SecurityContextHolder). - *

- * - *

- * For this class to operate it must be able to access the application context - * via the WebApplicationContextUtils and locate an {@link - * AclManager}. Application contexts have no need to have more than one - * AclManager (as a provider-based implementation can be used so - * that it locates a provider that is authoritative for the given domain - * object instance), so the first AclManager located will be - * used. - *

+ * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows its body through if some authorizations + * are granted to the request's principal.

Only works with permissions that are subclasses of {@link + * org.acegisecurity.acl.basic.BasicAclEntry}.

+ *

One or more comma separate integer permissions are specified via the hasPermission attribute. + * The tag will include its body if any of the integer permissions have been granted to the current + * Authentication (obtained from the SecurityContextHolder).

+ *

For this class to operate it must be able to access the application context via the + * WebApplicationContextUtils and locate an {@link AclManager}. Application contexts have no need to have + * more than one AclManager (as a provider-based implementation can be used so that it locates a provider + * that is authoritative for the given domain object instance), so the first AclManager located will be + * used.

* * @author Ben Alex * @version $Id$ */ public class AclTag extends TagSupport { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(AclTag.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object domainObject; private String hasPermission = ""; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public int doStartTag() throws JspException { if ((null == hasPermission) || "".equals(hasPermission)) { return Tag.SKIP_BODY; } - final String evaledPermissionsString = ExpressionEvaluationUtils - .evaluateString("hasPermission", hasPermission, pageContext); + final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission, + pageContext); Integer[] requiredIntegers = null; @@ -105,16 +91,15 @@ public class AclTag extends TagSupport { Object resolvedDomainObject = null; if (domainObject instanceof String) { - resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", - (String) domainObject, Object.class, pageContext); + resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", (String) domainObject, + Object.class, pageContext); } else { resolvedDomainObject = domainObject; } if (resolvedDomainObject == null) { if (logger.isDebugEnabled()) { - logger.debug( - "domainObject resolved to null, so including tag body"); + logger.debug("domainObject resolved to null, so including tag body"); } // Of course they have access to a null object! @@ -130,17 +115,13 @@ public class AclTag extends TagSupport { return Tag.SKIP_BODY; } - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); ApplicationContext context = getContext(pageContext); - String[] beans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, - AclManager.class, false, false); + String[] beans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, AclManager.class, false, false); if (beans.length == 0) { - throw new JspException( - "No AclManager would found the application context: " - + context.toString()); + throw new JspException("No AclManager would found the application context: " + context.toString()); } AclManager aclManager = (AclManager) context.getBean(beans[0]); @@ -149,10 +130,9 @@ public class AclTag extends TagSupport { AclEntry[] acls = aclManager.getAcls(resolvedDomainObject, auth); if (logger.isDebugEnabled()) { - logger.debug("Authentication: '" + auth + "' has: " - + ((acls == null) ? 0 : acls.length) - + " AclEntrys for domain object: '" + resolvedDomainObject - + "' from AclManager: '" + aclManager.toString() + "'"); + logger.debug("Authentication: '" + auth + "' has: " + ((acls == null) ? 0 : acls.length) + + " AclEntrys for domain object: '" + resolvedDomainObject + "' from AclManager: '" + + aclManager.toString() + "'"); } if ((acls == null) || (acls.length == 0)) { @@ -166,13 +146,10 @@ public class AclTag extends TagSupport { // See if principal has any of the required permissions for (int y = 0; y < requiredIntegers.length; y++) { - if (processableAcl.isPermitted( - requiredIntegers[y].intValue())) { + if (processableAcl.isPermitted(requiredIntegers[y].intValue())) { if (logger.isDebugEnabled()) { - logger.debug( - "Including tag body as found permission: " - + requiredIntegers[y] + " due to AclEntry: '" - + processableAcl + "'"); + logger.debug("Including tag body as found permission: " + requiredIntegers[y] + + " due to AclEntry: '" + processableAcl + "'"); } return Tag.EVAL_BODY_INCLUDE; @@ -191,8 +168,8 @@ public class AclTag extends TagSupport { /** * Allows test cases to override where application context obtained from. * - * @param pageContext so the ServletContext can be accessed as - * required by Spring's WebApplicationContextUtils + * @param pageContext so the ServletContext can be accessed as required by Spring's + * WebApplicationContextUtils * * @return the Spring application context (never null) */ diff --git a/core/src/main/java/org/acegisecurity/taglibs/authz/AuthenticationTag.java b/core/src/main/java/org/acegisecurity/taglibs/authz/AuthenticationTag.java index f83b63e20d..2125ba4c42 100644 --- a/core/src/main/java/org/acegisecurity/taglibs/authz/AuthenticationTag.java +++ b/core/src/main/java/org/acegisecurity/taglibs/authz/AuthenticationTag.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.userdetails.UserDetails; import java.io.IOException; @@ -35,21 +36,17 @@ import javax.servlet.jsp.tagext.TagSupport; /** - * An {@link javax.servlet.jsp.tagext.Tag} implementation that allows - * convenient access to the current Authentication object. - * - *

- * Whilst JSPs can access the SecurityContext directly, this tag - * avoids handling null conditions. The tag also properly - * accommodates Authentication.getPrincipal(), which can either - * be a String or a UserDetails. - *

+ * An {@link javax.servlet.jsp.tagext.Tag} implementation that allows convenient access to the current + * Authentication object.

Whilst JSPs can access the SecurityContext directly, this tag + * avoids handling null conditions. The tag also properly accommodates + * Authentication.getPrincipal(), which can either be a String or a + * UserDetails.

* * @author Ben Alex * @version $Id$ */ public class AuthenticationTag extends TagSupport { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private final static Set methodPrefixValidOptions = new HashSet(); @@ -58,28 +55,12 @@ public class AuthenticationTag extends TagSupport { methodPrefixValidOptions.add("is"); } - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String methodPrefix = "get"; private String operation = ""; - //~ Methods ================================================================ - - public void setMethodPrefix(String methodPrefix) { - this.methodPrefix = methodPrefix; - } - - public String getMethodPrefix() { - return methodPrefix; - } - - public void setOperation(String operation) { - this.operation = operation; - } - - public String getOperation() { - return operation; - } + //~ Methods ======================================================================================================== public int doStartTag() throws JspException { if ((null == operation) || "".equals(operation)) { @@ -90,13 +71,11 @@ public class AuthenticationTag extends TagSupport { if ((SecurityContextHolder.getContext() == null) || !(SecurityContextHolder.getContext() instanceof SecurityContext) - || (((SecurityContext) SecurityContextHolder.getContext()) - .getAuthentication() == null)) { + || (((SecurityContext) SecurityContextHolder.getContext()).getAuthentication() == null)) { return Tag.SKIP_BODY; } - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth.getPrincipal() == null) { return Tag.SKIP_BODY; @@ -111,6 +90,14 @@ public class AuthenticationTag extends TagSupport { } } + public String getMethodPrefix() { + return methodPrefix; + } + + public String getOperation() { + return operation; + } + protected String invokeOperation(Object obj) throws JspException { Class clazz = obj.getClass(); String methodToInvoke = getOperation(); @@ -148,15 +135,21 @@ public class AuthenticationTag extends TagSupport { return retVal.toString(); } + public void setMethodPrefix(String methodPrefix) { + this.methodPrefix = methodPrefix; + } + + public void setOperation(String operation) { + this.operation = operation; + } + protected void validateArguments() throws JspException { if ((getMethodPrefix() != null) && !getMethodPrefix().equals("")) { if (!methodPrefixValidOptions.contains(getMethodPrefix())) { - throw new JspException( - "Authorization tag : no valid method prefix available"); + throw new JspException("Authorization tag : no valid method prefix available"); } } else { - throw new JspException( - "Authorization tag : no method prefix available"); + throw new JspException("Authorization tag : no method prefix available"); } } diff --git a/core/src/main/java/org/acegisecurity/taglibs/authz/AuthorizeTag.java b/core/src/main/java/org/acegisecurity/taglibs/authz/AuthorizeTag.java index 9d45374084..40fe691a7f 100644 --- a/core/src/main/java/org/acegisecurity/taglibs/authz/AuthorizeTag.java +++ b/core/src/main/java/org/acegisecurity/taglibs/authz/AuthorizeTag.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.taglibs.authz; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; import org.springframework.util.StringUtils; @@ -37,107 +38,20 @@ import javax.servlet.jsp.tagext.TagSupport; /** - * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's - * body through if some authorizations are granted to the request's principal. + * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's body through if some authorizations + * are granted to the request's principal. * * @author Francois Beausoleil * @version $Id$ */ public class AuthorizeTag extends TagSupport { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String ifAllGranted = ""; private String ifAnyGranted = ""; private String ifNotGranted = ""; - //~ Methods ================================================================ - - public void setIfAllGranted(String ifAllGranted) throws JspException { - this.ifAllGranted = ifAllGranted; - } - - public String getIfAllGranted() { - return ifAllGranted; - } - - public void setIfAnyGranted(String ifAnyGranted) throws JspException { - this.ifAnyGranted = ifAnyGranted; - } - - public String getIfAnyGranted() { - return ifAnyGranted; - } - - public void setIfNotGranted(String ifNotGranted) throws JspException { - this.ifNotGranted = ifNotGranted; - } - - public String getIfNotGranted() { - return ifNotGranted; - } - - public int doStartTag() throws JspException { - if (((null == ifAllGranted) || "".equals(ifAllGranted)) - && ((null == ifAnyGranted) || "".equals(ifAnyGranted)) - && ((null == ifNotGranted) || "".equals(ifNotGranted))) { - return Tag.SKIP_BODY; - } - - final Collection granted = getPrincipalAuthorities(); - - final String evaledIfNotGranted = ExpressionEvaluationUtils - .evaluateString("ifNotGranted", ifNotGranted, pageContext); - - if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) { - Set grantedCopy = retainAll(granted, - parseAuthoritiesString(evaledIfNotGranted)); - - if (!grantedCopy.isEmpty()) { - return Tag.SKIP_BODY; - } - } - - final String evaledIfAllGranted = ExpressionEvaluationUtils - .evaluateString("ifAllGranted", ifAllGranted, pageContext); - - if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) { - if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) { - return Tag.SKIP_BODY; - } - } - - final String evaledIfAnyGranted = ExpressionEvaluationUtils - .evaluateString("ifAnyGranted", ifAnyGranted, pageContext); - - if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) { - Set grantedCopy = retainAll(granted, - parseAuthoritiesString(evaledIfAnyGranted)); - - if (grantedCopy.isEmpty()) { - return Tag.SKIP_BODY; - } - } - - return Tag.EVAL_BODY_INCLUDE; - } - - private Collection getPrincipalAuthorities() { - Authentication currentUser = SecurityContextHolder.getContext() - .getAuthentication(); - - if (null == currentUser) { - return Collections.EMPTY_LIST; - } - - if ((null == currentUser.getAuthorities()) - || (currentUser.getAuthorities().length < 1)) { - return Collections.EMPTY_LIST; - } - - Collection granted = Arrays.asList(currentUser.getAuthorities()); - - return granted; - } + //~ Methods ======================================================================================================== private Set authoritiesToRoles(Collection c) { Set target = new HashSet(); @@ -157,66 +71,118 @@ public class AuthorizeTag extends TagSupport { return target; } + public int doStartTag() throws JspException { + if (((null == ifAllGranted) || "".equals(ifAllGranted)) && ((null == ifAnyGranted) || "".equals(ifAnyGranted)) + && ((null == ifNotGranted) || "".equals(ifNotGranted))) { + return Tag.SKIP_BODY; + } + + final Collection granted = getPrincipalAuthorities(); + + final String evaledIfNotGranted = ExpressionEvaluationUtils.evaluateString("ifNotGranted", ifNotGranted, + pageContext); + + if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) { + Set grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfNotGranted)); + + if (!grantedCopy.isEmpty()) { + return Tag.SKIP_BODY; + } + } + + final String evaledIfAllGranted = ExpressionEvaluationUtils.evaluateString("ifAllGranted", ifAllGranted, + pageContext); + + if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) { + if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) { + return Tag.SKIP_BODY; + } + } + + final String evaledIfAnyGranted = ExpressionEvaluationUtils.evaluateString("ifAnyGranted", ifAnyGranted, + pageContext); + + if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) { + Set grantedCopy = retainAll(granted, parseAuthoritiesString(evaledIfAnyGranted)); + + if (grantedCopy.isEmpty()) { + return Tag.SKIP_BODY; + } + } + + return Tag.EVAL_BODY_INCLUDE; + } + + public String getIfAllGranted() { + return ifAllGranted; + } + + public String getIfAnyGranted() { + return ifAnyGranted; + } + + public String getIfNotGranted() { + return ifNotGranted; + } + + private Collection getPrincipalAuthorities() { + Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); + + if (null == currentUser) { + return Collections.EMPTY_LIST; + } + + if ((null == currentUser.getAuthorities()) || (currentUser.getAuthorities().length < 1)) { + return Collections.EMPTY_LIST; + } + + Collection granted = Arrays.asList(currentUser.getAuthorities()); + + return granted; + } + private Set parseAuthoritiesString(String authorizationsString) { final Set requiredAuthorities = new HashSet(); - final String[] authorities = StringUtils - .commaDelimitedListToStringArray(authorizationsString); + final String[] authorities = StringUtils.commaDelimitedListToStringArray(authorizationsString); for (int i = 0; i < authorities.length; i++) { String authority = authorities[i]; - // Remove the role's whitespace characters without depending on JDK 1.4+ - // Includes space, tab, new line, carriage return and form feed. - String role = StringUtils.replace(authority, " ", ""); - role = StringUtils.replace(role, "\t", ""); - role = StringUtils.replace(role, "\r", ""); - role = StringUtils.replace(role, "\n", ""); - role = StringUtils.replace(role, "\f", ""); + // Remove the role's whitespace characters without depending on JDK 1.4+ + // Includes space, tab, new line, carriage return and form feed. + String role = StringUtils.replace(authority, " ", ""); + role = StringUtils.replace(role, "\t", ""); + role = StringUtils.replace(role, "\r", ""); + role = StringUtils.replace(role, "\n", ""); + role = StringUtils.replace(role, "\f", ""); - requiredAuthorities.add(new GrantedAuthorityImpl(role)); + requiredAuthorities.add(new GrantedAuthorityImpl(role)); } return requiredAuthorities; } /** - * Find the common authorities between the current authentication's {@link - * GrantedAuthority} and the ones that have been specified in the tag's - * ifAny, ifNot or ifAllGranted attributes. - * - *

- * We need to manually iterate over both collections, because the granted - * authorities might not implement {@link Object#equals(Object)} and - * {@link Object#hashCode()} in the same way as {@link - * GrantedAuthorityImpl}, thereby invalidating {@link - * Collection#retainAll(java.util.Collection)} results. - *

- * - *

- * CAVEAT: This method will not work if - * the granted authorities returns a null string as the - * return value of {@link - * org.acegisecurity.GrantedAuthority#getAuthority()}. - *

- * - *

- * Reported by rawdave, on Fri Feb 04, 2005 2:11 pm in the Acegi Security - * System for Spring forums. - *

+ * Find the common authorities between the current authentication's {@link GrantedAuthority} and the ones + * that have been specified in the tag's ifAny, ifNot or ifAllGranted attributes.

We need to manually + * iterate over both collections, because the granted authorities might not implement {@link + * Object#equals(Object)} and {@link Object#hashCode()} in the same way as {@link GrantedAuthorityImpl}, thereby + * invalidating {@link Collection#retainAll(java.util.Collection)} results.

+ *

CAVEAT: This method will not work if the granted authorities + * returns a null string as the return value of {@link + * org.acegisecurity.GrantedAuthority#getAuthority()}.

+ *

Reported by rawdave, on Fri Feb 04, 2005 2:11 pm in the Acegi Security System for Spring forums.

* - * @param granted The authorities granted by the authentication. May be any - * implementation of {@link GrantedAuthority} that does - * not return null from {@link + * @param granted The authorities granted by the authentication. May be any implementation of {@link + * GrantedAuthority} that does not return null from {@link * org.acegisecurity.GrantedAuthority#getAuthority()}. - * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have - * been built using ifAny, ifAll or ifNotGranted. + * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have been built using ifAny, ifAll or + * ifNotGranted. * - * @return A set containing only the common authorities between - * granted and required. + * @return A set containing only the common authorities between granted and required. * - * @see authz:authorize - * ifNotGranted not behaving as expected + * @see authz:authorize ifNotGranted not behaving + * as expected */ private Set retainAll(final Collection granted, final Set required) { Set grantedRoles = authoritiesToRoles(granted); @@ -232,10 +198,8 @@ public class AuthorizeTag extends TagSupport { for (Iterator iterator = grantedRoles.iterator(); iterator.hasNext();) { String role = (String) iterator.next(); - for (Iterator grantedIterator = granted.iterator(); - grantedIterator.hasNext();) { - GrantedAuthority authority = (GrantedAuthority) grantedIterator - .next(); + for (Iterator grantedIterator = granted.iterator(); grantedIterator.hasNext();) { + GrantedAuthority authority = (GrantedAuthority) grantedIterator.next(); if (authority.getAuthority().equals(role)) { target.add(authority); @@ -247,4 +211,16 @@ public class AuthorizeTag extends TagSupport { return target; } + + public void setIfAllGranted(String ifAllGranted) throws JspException { + this.ifAllGranted = ifAllGranted; + } + + public void setIfAnyGranted(String ifAnyGranted) throws JspException { + this.ifAnyGranted = ifAnyGranted; + } + + public void setIfNotGranted(String ifNotGranted) throws JspException { + this.ifNotGranted = ifNotGranted; + } } diff --git a/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java b/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java index b31276e286..9da0761d21 100644 --- a/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java +++ b/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ import org.springframework.context.ApplicationContext; * @version $Id$ */ public interface Authz { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * all the listed roles must be granted to return true, otherwise fasle; @@ -64,28 +64,18 @@ public interface Authz { public ApplicationContext getAppCtx(); /** - * return the principal's name, supports the various type of principals - * that can exist in the {@link Authentication} object, such as a String - * or {@link UserDetails} instance + * return the principal's name, supports the various type of principals that can exist in the {@link + * Authentication} object, such as a String or {@link UserDetails} instance * * @return string representation of principal's name */ public String getPrincipal(); /** - * return true if the principal holds either permission specified for the - * provided domain object - * - *

- * Only works with permissions that are subclasses of {@link - * net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry}. - *

- * - *

- * For this class to operate it must be able to access the application - * context via the WebApplicationContextUtils and locate an - * {@link AclManager}. - *

+ * return true if the principal holds either permission specified for the provided domain object

Only + * works with permissions that are subclasses of {@link net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry}.

+ *

For this class to operate it must be able to access the application context via the + * WebApplicationContextUtils and locate an {@link AclManager}.

* * @param domainObject - domain object need acl control * @param permissions - comma separate integer permissions diff --git a/core/src/main/java/org/acegisecurity/taglibs/velocity/AuthzImpl.java b/core/src/main/java/org/acegisecurity/taglibs/velocity/AuthzImpl.java index 62a136cd34..d0d2ef0804 100644 --- a/core/src/main/java/org/acegisecurity/taglibs/velocity/AuthzImpl.java +++ b/core/src/main/java/org/acegisecurity/taglibs/velocity/AuthzImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,23 +29,22 @@ import javax.servlet.jsp.tagext.Tag; /** - * I decided to wrap several JSP tag in one class, so I have to using inner - * class to wrap these JSP tag. To using this class, you need to inject - * Spring Context via SetAppCtx() method. AclTag need Spring Context to get - * AclManger bean. + * I decided to wrap several JSP tag in one class, so I have to using inner class to wrap these JSP tag. To using + * this class, you need to inject Spring Context via SetAppCtx() method. AclTag need Spring Context to get AclManger + * bean. */ public class AuthzImpl implements Authz { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== static final int ALL_GRANTED = 1; static final int ANY_GRANTED = 2; static final int NONE_GRANTED = 3; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext appCtx; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean allGranted(String roles) { return ifGranted(roles, ALL_GRANTED); @@ -146,8 +145,7 @@ public class AuthzImpl implements Authz { break; default: - throw new IllegalArgumentException("invalid granted type : " - + grantType + " role=" + roles); + throw new IllegalArgumentException("invalid granted type : " + grantType + " role=" + roles); } result = authorizeTag.doStartTag(); @@ -167,8 +165,7 @@ public class AuthzImpl implements Authz { } /** - * test case can use this class to mock application context with aclManager - * bean in it. + * test case can use this class to mock application context with aclManager bean in it. * * @param appCtx DOCUMENT ME! */ @@ -176,13 +173,12 @@ public class AuthzImpl implements Authz { this.appCtx = appCtx; } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** - * AclTag need to access the application context via the - * WebApplicationContextUtils and locate an {@link AclManager}. - * WebApplicationContextUtils get application context via ServletContext. - * I decided to let the Authz provide the Spring application context. + * AclTag need to access the application context via the WebApplicationContextUtils and + * locate an {@link AclManager}. WebApplicationContextUtils get application context via ServletContext. I decided + * to let the Authz provide the Spring application context. */ private class MyAclTag extends AclTag { private static final long serialVersionUID = 6752340622125924108L; @@ -198,9 +194,8 @@ public class AuthzImpl implements Authz { } /** - * it must output somthing to JSP page, so have to override the - * writeMessage method to avoid JSP related operation. Get Idea from Acegi - * Test class. + * it must output somthing to JSP page, so have to override the writeMessage method to avoid JSP related + * operation. Get Idea from Acegi Test class. */ private class MyAuthenticationTag extends AuthenticationTag { private static final long serialVersionUID = -1094246833893599161L; diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java index e7e7a12611..76cccbb1e8 100644 --- a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java @@ -56,59 +56,32 @@ import javax.servlet.http.HttpServletResponse; /** - * Abstract processor of browser-based HTTP-based authentication requests. - * - *

- * This filter is responsible for processing authentication requests. If - * authentication is successful, the resulting {@link Authentication} object - * will be placed into the SecurityContext, which is guaranteed - * to have already been created by an earlier filter. - *

- * - *

- * If authentication fails, the AuthenticationException will be - * placed into the HttpSession with the attribute defined by - * {@link #ACEGI_SECURITY_LAST_EXCEPTION_KEY}. - *

- * - *

- * To use this filter, it is necessary to specify the following properties: - *

- * - *
    - *
  • - * defaultTargetUrl indicates the URL that should be used for - * redirection if the HttpSession attribute named {@link - * #ACEGI_SAVED_REQUEST_KEY} does not indicate the target URL once - * authentication is completed successfully. eg: /. The - * defaultTargetUrl will be treated as relative to the web-app's - * context path, and should include the leading /. Alternatively, - * inclusion of a scheme name (eg http:// or https://) as the prefix will - * denote a fully-qualified URL and this is also supported. - *
  • - *
  • - * authenticationFailureUrl indicates the URL that should be used - * for redirection if the authentication request fails. eg: - * /login.jsp?login_error=1. - *
  • - *
  • - * filterProcessesUrl indicates the URL that this filter will - * respond to. This parameter varies by subclass. - *
  • - *
  • - * alwaysUseDefaultTargetUrl causes successful authentication to - * always redirect to the defaultTargetUrl, even if the - * HttpSession attribute named {@link #ACEGI_SAVED_REQUEST_KEY} - * defines the intended target URL. - *
  • - *
- * - *

- * To configure this filter to redirect to specific pages as the result of - * specific {@link AuthenticationException}s you can do the following. - * Configure the exceptionMappings property in your application - * xml. This property is a java.util.Properties object that maps a - * fully-qualified exception class name to a redirection url target.
+ * Abstract processor of browser-based HTTP-based authentication requests.

This filter is responsible for + * processing authentication requests. If authentication is successful, the resulting {@link Authentication} object + * will be placed into the SecurityContext, which is guaranteed to have already been created by an + * earlier filter.

+ *

If authentication fails, the AuthenticationException will be placed into the + * HttpSession with the attribute defined by {@link #ACEGI_SECURITY_LAST_EXCEPTION_KEY}.

+ *

To use this filter, it is necessary to specify the following properties:

+ *
    + *
  • defaultTargetUrl indicates the URL that should be used for redirection if the + * HttpSession attribute named {@link #ACEGI_SAVED_REQUEST_KEY} does not indicate the target URL once + * authentication is completed successfully. eg: /. The defaultTargetUrl will be treated + * as relative to the web-app's context path, and should include the leading /. Alternatively, + * inclusion of a scheme name (eg http:// or https://) as the prefix will denote a fully-qualified URL and this is + * also supported.
  • + *
  • authenticationFailureUrl indicates the URL that should be used for redirection if the + * authentication request fails. eg: /login.jsp?login_error=1.
  • + *
  • filterProcessesUrl indicates the URL that this filter will respond to. This parameter + * varies by subclass.
  • + *
  • alwaysUseDefaultTargetUrl causes successful authentication to always redirect to the + * defaultTargetUrl, even if the HttpSession attribute named {@link + * #ACEGI_SAVED_REQUEST_KEY} defines the intended target URL.
  • + *
+ *

To configure this filter to redirect to specific pages as the result of specific {@link + * AuthenticationException}s you can do the following. Configure the exceptionMappings property in your + * application xml. This property is a java.util.Properties object that maps a fully-qualified exception class name to + * a redirection url target.
* For example:
* <property name="exceptionMappings">
* *   <props>
@@ -116,37 +89,26 @@ import javax.servlet.http.HttpServletResponse; * *   </props>
* * </property>
* *

- * The example above would redirect all {@link - * org.acegisecurity.BadCredentialsException}s thrown, to a page in the - * web-application called /bad_credentials.jsp. - *

- * - *

- * Any {@link AuthenticationException} thrown that cannot be matched in the - * exceptionMappings will be redirected to the - * authenticationFailureUrl - *

- * - *

- * If authentication is successful, an {@link - * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} - * will be published to the application context. No events will be published - * if authentication was unsuccessful, because this would generally be - * recorded via an AuthenticationManager-specific application - * event. - *

+ * The example above would redirect all {@link org.acegisecurity.BadCredentialsException}s thrown, to a page in the + * web-application called /bad_credentials.jsp.

+ *

Any {@link AuthenticationException} thrown that cannot be matched in the exceptionMappings will + * be redirected to the authenticationFailureUrl

+ *

If authentication is successful, an {@link + * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be published to the application + * context. No events will be published if authentication was unsuccessful, because this would generally be recorded + * via an AuthenticationManager-specific application event.

* * @author Ben Alex * @version $Id$ */ -public abstract class AbstractProcessingFilter implements Filter, - InitializingBean, ApplicationEventPublisherAware, MessageSourceAware { - //~ Static fields/initializers ============================================= +public abstract class AbstractProcessingFilter implements Filter, InitializingBean, ApplicationEventPublisherAware, + MessageSourceAware { + //~ Static fields/initializers ===================================================================================== public static final String ACEGI_SAVED_REQUEST_KEY = "ACEGI_SAVED_REQUEST_KEY"; public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected ApplicationEventPublisher eventPublisher; protected AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); @@ -160,65 +122,59 @@ public abstract class AbstractProcessingFilter implements Filter, private String authenticationFailureUrl; /** - * Where to redirect the browser to if authentication is successful but - * ACEGI_SECURITY_TARGET_URL_KEY is null + * Where to redirect the browser to if authentication is successful but ACEGI_SECURITY_TARGET_URL_KEY is + * null */ private String defaultTargetUrl; /** - * The URL destination that this filter intercepts and processes (usually - * something like /j_acegi_security_check) + * The URL destination that this filter intercepts and processes (usually something like + * /j_acegi_security_check) */ private String filterProcessesUrl = getDefaultFilterProcessesUrl(); /** - * If true, will always redirect to {@link #defaultTargetUrl} - * upon successful authentication, irrespective of the page that caused - * the authentication request (defaults to false). + * If true, will always redirect to {@link #defaultTargetUrl} upon successful authentication, + * irrespective of the page that caused the authentication request (defaults to false). */ private boolean alwaysUseDefaultTargetUrl = false; /** - * Indicates if the filter chain should be continued prior to delegation to - * {@link #successfulAuthentication(HttpServletRequest, - * HttpServletResponse, Authentication)}, which may be useful in certain - * environment (eg Tapestry). Defaults to false. + * Indicates if the filter chain should be continued prior to delegation to {@link + * #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)}, which may be useful in + * certain environment (eg Tapestry). Defaults to false. */ private boolean continueChainBeforeSuccessfulAuthentication = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.hasLength(filterProcessesUrl, - "filterProcessesUrl must be specified"); + Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified"); Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified"); - Assert.hasLength(authenticationFailureUrl, - "authenticationFailureUrl must be specified"); - Assert.notNull(authenticationManager, - "authenticationManager must be specified"); + Assert.hasLength(authenticationFailureUrl, "authenticationFailureUrl must be specified"); + Assert.notNull(authenticationManager, "authenticationManager must be specified"); Assert.notNull(this.rememberMeServices); } /** * Performs actual authentication. * - * @param request from which to extract parameters and perform the - * authentication + * @param request from which to extract parameters and perform the authentication * * @return the authenticated user * * @throws AuthenticationException if authentication fails */ - public abstract Authentication attemptAuthentication( - HttpServletRequest request) throws AuthenticationException; + public abstract Authentication attemptAuthentication(HttpServletRequest request) + throws AuthenticationException; /** * Does nothing. We use IoC container lifecycle services instead. */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -269,8 +225,7 @@ public abstract class AbstractProcessingFilter implements Filter, } /** - * Specifies the default filterProcessesUrl for the - * implementation. + * Specifies the default filterProcessesUrl for the implementation. * * @return the default filterProcessesUrl */ @@ -316,44 +271,28 @@ public abstract class AbstractProcessingFilter implements Filter, return (savedRequest == null) ? null : savedRequest.getFullRequestUrl(); } - protected void onPreAuthentication(HttpServletRequest request, - HttpServletResponse response) + protected void onPreAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException {} - protected void onSuccessfulAuthentication(HttpServletRequest request, - HttpServletResponse response, Authentication authResult) - throws IOException {} + protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, + Authentication authResult) throws IOException {} - protected void onUnsuccessfulAuthentication(HttpServletRequest request, - HttpServletResponse response, AuthenticationException failed) - throws IOException {} + protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, + AuthenticationException failed) throws IOException {} /** - *

- * Indicates whether this filter should attempt to process a login request - * for the current invocation. - *

- * - *

- * It strips any parameters from the "path" section of the request URL - * (such as the jsessionid parameter in - * http://host/myapp/index.html;jsessionid=blah) before matching - * against the filterProcessesUrl property. - *

- * - *

- * Subclasses may override for special requirements, such as Tapestry - * integration. - *

+ *

Indicates whether this filter should attempt to process a login request for the current invocation.

+ *

It strips any parameters from the "path" section of the request URL (such as the jsessionid + * parameter in http://host/myapp/index.html;jsessionid=blah) before matching against the + * filterProcessesUrl property.

+ *

Subclasses may override for special requirements, such as Tapestry integration.

* * @param request as received from the filter chain * @param response as received from the filter chain * - * @return true if the filter should attempt authentication, - * false otherwise + * @return true if the filter should attempt authentication, false otherwise */ - protected boolean requiresAuthentication(HttpServletRequest request, - HttpServletResponse response) { + protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { String uri = request.getRequestURI(); int pathParamIndex = uri.indexOf(';'); @@ -365,11 +304,9 @@ public abstract class AbstractProcessingFilter implements Filter, return uri.endsWith(request.getContextPath() + filterProcessesUrl); } - protected void sendRedirect(HttpServletRequest request, - HttpServletResponse response, String failureUrl) + protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String failureUrl) throws IOException { - if (!failureUrl.startsWith("http://") - && !failureUrl.startsWith("https://")) { + if (!failureUrl.startsWith("http://") && !failureUrl.startsWith("https://")) { failureUrl = request.getContextPath() + failureUrl; } @@ -380,15 +317,12 @@ public abstract class AbstractProcessingFilter implements Filter, this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl; } - public void setApplicationEventPublisher( - ApplicationEventPublisher eventPublisher) { + public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } @@ -396,13 +330,11 @@ public abstract class AbstractProcessingFilter implements Filter, this.authenticationFailureUrl = authenticationFailureUrl; } - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { + public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } - public void setContinueChainBeforeSuccessfulAuthentication( - boolean continueChainBeforeSuccessfulAuthentication) { + public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) { this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication; } @@ -426,9 +358,8 @@ public abstract class AbstractProcessingFilter implements Filter, this.rememberMeServices = rememberMeServices; } - protected void successfulAuthentication(HttpServletRequest request, - HttpServletResponse response, Authentication authResult) - throws IOException { + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, + Authentication authResult) throws IOException { if (logger.isDebugEnabled()) { logger.debug("Authentication success: " + authResult.toString()); } @@ -436,9 +367,7 @@ public abstract class AbstractProcessingFilter implements Filter, SecurityContextHolder.getContext().setAuthentication(authResult); if (logger.isDebugEnabled()) { - logger.debug( - "Updated SecurityContextHolder to contain the following Authentication: '" - + authResult + "'"); + logger.debug("Updated SecurityContextHolder to contain the following Authentication: '" + authResult + "'"); } String targetUrl = obtainFullRequestUrl(request); @@ -452,9 +381,7 @@ public abstract class AbstractProcessingFilter implements Filter, } if (logger.isDebugEnabled()) { - logger.debug( - "Redirecting to target URL from HTTP Session (or default): " - + targetUrl); + logger.debug("Redirecting to target URL from HTTP Session (or default): " + targetUrl); } onSuccessfulAuthentication(request, response, authResult); @@ -463,34 +390,28 @@ public abstract class AbstractProcessingFilter implements Filter, // Fire event if (this.eventPublisher != null) { - eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent( - authResult, this.getClass())); + eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); } response.sendRedirect(response.encodeRedirectURL(targetUrl)); } - protected void unsuccessfulAuthentication(HttpServletRequest request, - HttpServletResponse response, AuthenticationException failed) - throws IOException { + protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, + AuthenticationException failed) throws IOException { SecurityContextHolder.getContext().setAuthentication(null); if (logger.isDebugEnabled()) { - logger.debug( - "Updated SecurityContextHolder to contain null Authentication"); + logger.debug("Updated SecurityContextHolder to contain null Authentication"); } - String failureUrl = exceptionMappings.getProperty(failed.getClass() - .getName(), - authenticationFailureUrl); + String failureUrl = exceptionMappings.getProperty(failed.getClass().getName(), authenticationFailureUrl); if (logger.isDebugEnabled()) { logger.debug("Authentication request failed: " + failed.toString()); } try { - request.getSession() - .setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed); + request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed); } catch (Exception ignored) {} onUnsuccessfulAuthentication(request, response, failed); diff --git a/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandler.java b/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandler.java index 00cb2a8a82..3debb6262a 100644 --- a/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandler.java +++ b/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandler.java @@ -32,7 +32,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public interface AccessDeniedHandler { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Handles an access denied failure. @@ -44,7 +44,6 @@ public interface AccessDeniedHandler { * @throws IOException in the event of an IOException * @throws ServletException in the event of a ServletException */ - public void handle(ServletRequest request, ServletResponse response, - AccessDeniedException accessDeniedException) + public void handle(ServletRequest request, ServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException; } diff --git a/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandlerImpl.java b/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandlerImpl.java index 5ba873556e..c29e0b252e 100644 --- a/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandlerImpl.java +++ b/core/src/main/java/org/acegisecurity/ui/AccessDeniedHandlerImpl.java @@ -31,36 +31,29 @@ import javax.servlet.http.HttpServletResponse; /** - * Base implementation of {@link AccessDeniedHandler}. - * - *

- * This implementation sends a 403 (SC_FORBIDDEN) HTTP error code. In addition, - * if a {@link #errorPage} is defined, the implementation will perform a - * request dispatcher "forward" to the specified error page view. Being a - * "forward", the SecurityContextHolder will remain populated. - * This is of benefit if the view (or a tag library or macro) wishes to access - * the SecurityContextHolder. The request scope will also be - * populated with the exception itself, available from the key {@link - * #ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY}. - *

+ * Base implementation of {@link AccessDeniedHandler}.

This implementation sends a 403 (SC_FORBIDDEN) HTTP error + * code. In addition, if a {@link #errorPage} is defined, the implementation will perform a request dispatcher + * "forward" to the specified error page view. Being a "forward", the SecurityContextHolder will remain + * populated. This is of benefit if the view (or a tag library or macro) wishes to access the + * SecurityContextHolder. The request scope will also be populated with the exception itself, available + * from the key {@link #ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY}.

* * @author Ben Alex * @version $Id$ */ public class AccessDeniedHandlerImpl implements AccessDeniedHandler { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY = "ACEGI_SECURITY_403_EXCEPTION"; protected final static Log logger = LogFactory.getLog(AccessDeniedHandlerImpl.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String errorPage; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void handle(ServletRequest request, ServletResponse response, - AccessDeniedException accessDeniedException) + public void handle(ServletRequest request, ServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { if (errorPage != null) { // Put exception into request scope (perhaps of use to a view) @@ -72,29 +65,26 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler { try { rd.forward(request, response); - ((HttpServletResponse)response).setStatus(HttpServletResponse.SC_FORBIDDEN); + ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_FORBIDDEN); + return; } catch (Exception responseCommitted) { if (logger.isErrorEnabled()) { - logger.error("Error processing " + request.toString(), - responseCommitted); + logger.error("Error processing " + request.toString(), responseCommitted); } } } // Send 403 (we do this after response has been written) - ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, - accessDeniedException.getMessage()); + ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage()); } /** - * The error page to use. Must begin with a "/" and is interpreted relative - * to the current context root. + * The error page to use. Must begin with a "/" and is interpreted relative to the current context root. * * @param errorPage the dispatcher path to display * - * @throws IllegalArgumentException if the argument doesn't comply with the - * above limitations + * @throws IllegalArgumentException if the argument doesn't comply with the above limitations */ public void setErrorPage(String errorPage) { if ((errorPage != null) && !errorPage.startsWith("/")) { diff --git a/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSource.java b/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSource.java index 2955394c20..efede62867 100644 --- a/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSource.java +++ b/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSource.java @@ -26,14 +26,12 @@ import javax.servlet.http.HttpServletRequest; * @version $Id$ */ public interface AuthenticationDetailsSource { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Called by a class when it wishes a new authentication details instance - * to be created. + * Called by a class when it wishes a new authentication details instance to be created. * - * @param request the request object, which may be used by the - * authentication details object + * @param request the request object, which may be used by the authentication details object * * @return a fully-configured authentication details instance */ diff --git a/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSourceImpl.java b/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSourceImpl.java index 0bfe808e1a..d964a83d9e 100644 --- a/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSourceImpl.java +++ b/core/src/main/java/org/acegisecurity/ui/AuthenticationDetailsSourceImpl.java @@ -25,24 +25,19 @@ import javax.servlet.http.HttpServletRequest; /** - * Base implementation of {@link AuthenticationDetailsSource}. - * - *

- * By default will create an instance of WebAuthenticationDetails. - * Any object that accepts a HttpServletRequest as its sole - * constructor can be used instead of this default. - *

+ * Base implementation of {@link AuthenticationDetailsSource}.

By default will create an instance of + * WebAuthenticationDetails. Any object that accepts a HttpServletRequest as its sole + * constructor can be used instead of this default.

* * @author Ben Alex * @version $Id$ */ -public class AuthenticationDetailsSourceImpl - implements AuthenticationDetailsSource { - //~ Instance fields ======================================================== +public class AuthenticationDetailsSourceImpl implements AuthenticationDetailsSource { + //~ Instance fields ================================================================================================ private Class clazz = WebAuthenticationDetails.class; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object buildDetails(HttpServletRequest request) { try { diff --git a/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java index 3c16e1c35e..52fceaef9c 100644 --- a/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,29 +32,23 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public interface AuthenticationEntryPoint { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Commences an authentication scheme. - * - *

- * SecurityEnforcementFilter will populate the + * Commences an authentication scheme.

SecurityEnforcementFilter will populate the * HttpSession attribute named - * AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY - * with the requested target URL before calling this method. - *

- * - *

- * Implementations should modify the headers on the - * ServletResponse as necessary to commence the - * authentication process. - *

+ * AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY with the requested target URL before + * calling this method.

+ *

Implementations should modify the headers on the ServletResponse as necessary to + * commence the authentication process.

* * @param request that resulted in an AuthenticationException * @param response so that the user agent can begin authentication * @param authException that caused the invocation + * + * @throws IOException DOCUMENT ME! + * @throws ServletException DOCUMENT ME! */ - public void commence(ServletRequest request, ServletResponse response, - AuthenticationException authException) + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException; } diff --git a/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java b/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java index 1c7a127c39..35e6f870f0 100644 --- a/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java @@ -49,64 +49,36 @@ import javax.servlet.http.HttpServletResponse; /** - * Handles any AccessDeniedException and - * AuthenticationException thrown within the filter chain. - * - *

- * This filter is necessary because it provides the bridge between Java - * exceptions and HTTP responses. It is solely concerned with maintaining the - * user interface. This filter does not do any actual security enforcement. - *

- * - *

- * If an {@link AuthenticationException} is detected, the filter will launch - * the authenticationEntryPoint. This allows common handling of - * authentication failures originating from any subclass of {@link - * org.acegisecurity.intercept.AbstractSecurityInterceptor}. - *

- * - *

- * If an {@link AccessDeniedException} is detected, the filter will determine - * whether or not the user is an anonymous user. If they are an anonymous - * user, the authenticationEntryPoint will be launched. If they - * are not an anonymous user, the filter will delegate to the {@link - * org.acegisecurity.ui.AccessDeniedHandler}. By default the filter will use - * {@link org.acegisecurity.ui.AccessDeniedHandlerImpl}. - *

- * - *

- * To use this filter, it is necessary to specify the following properties: - *

- * - *
    - *
  • - * authenticationEntryPoint indicates the handler that should - * commence the authentication process if an - * AuthenticationException is detected. Note that this may also - * switch the current protocol from http to https for an SSL login. - *
  • - *
  • - * portResolver is used to determine the "real" port that a - * request was received on. - *
  • - *
- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Handles any AccessDeniedException and AuthenticationException thrown within the filter + * chain.

This filter is necessary because it provides the bridge between Java exceptions and HTTP responses. It + * is solely concerned with maintaining the user interface. This filter does not do any actual security enforcement.

+ *

If an {@link AuthenticationException} is detected, the filter will launch the + * authenticationEntryPoint. This allows common handling of authentication failures originating from any + * subclass of {@link org.acegisecurity.intercept.AbstractSecurityInterceptor}.

+ *

If an {@link AccessDeniedException} is detected, the filter will determine whether or not the user is an + * anonymous user. If they are an anonymous user, the authenticationEntryPoint will be launched. If they + * are not an anonymous user, the filter will delegate to the {@link org.acegisecurity.ui.AccessDeniedHandler}. By + * default the filter will use {@link org.acegisecurity.ui.AccessDeniedHandlerImpl}.

+ *

To use this filter, it is necessary to specify the following properties:

+ *
    + *
  • authenticationEntryPoint indicates the handler that should commence the authentication + * process if an AuthenticationException is detected. Note that this may also switch the current + * protocol from http to https for an SSL login.
  • + *
  • portResolver is used to determine the "real" port that a request was received on.
  • + *
+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class ExceptionTranslationFilter implements Filter, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(ExceptionTranslationFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl(); private AuthenticationEntryPoint authenticationEntryPoint; @@ -114,20 +86,18 @@ public class ExceptionTranslationFilter implements Filter, InitializingBean { private PortResolver portResolver = new PortResolverImpl(); private boolean createSessionAllowed = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(authenticationEntryPoint, - "authenticationEntryPoint must be specified"); + Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint must be specified"); Assert.notNull(portResolver, "portResolver must be specified"); - Assert.notNull(authenticationTrustResolver, - "authenticationTrustResolver must be specified"); + Assert.notNull(authenticationTrustResolver, "authenticationTrustResolver must be specified"); } public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("HttpServletRequest required"); } @@ -149,8 +119,7 @@ public class ExceptionTranslationFilter implements Filter, InitializingBean { } catch (ServletException ex) { if (ex.getRootCause() instanceof AuthenticationException || ex.getRootCause() instanceof AccessDeniedException) { - handleException(request, response, chain, - (AcegiSecurityException) ex.getRootCause()); + handleException(request, response, chain, (AcegiSecurityException) ex.getRootCause()); } else { throw ex; } @@ -171,36 +140,30 @@ public class ExceptionTranslationFilter implements Filter, InitializingBean { return portResolver; } - private void handleException(ServletRequest request, - ServletResponse response, FilterChain chain, + private void handleException(ServletRequest request, ServletResponse response, FilterChain chain, AcegiSecurityException exception) throws IOException, ServletException { if (exception instanceof AuthenticationException) { if (logger.isDebugEnabled()) { - logger.debug("Authentication exception occurred; redirecting to authentication entry point", - exception); + logger.debug("Authentication exception occurred; redirecting to authentication entry point", exception); } - sendStartAuthentication(request, response, chain, - (AuthenticationException) exception); + sendStartAuthentication(request, response, chain, (AuthenticationException) exception); } else if (exception instanceof AccessDeniedException) { - if (authenticationTrustResolver.isAnonymous( - SecurityContextHolder.getContext().getAuthentication())) { + if (authenticationTrustResolver.isAnonymous(SecurityContextHolder.getContext().getAuthentication())) { if (logger.isDebugEnabled()) { logger.debug("Access is denied (user is anonymous); redirecting to authentication entry point", exception); } sendStartAuthentication(request, response, chain, - new InsufficientAuthenticationException( - "Full authentication is required to access this resource")); + new InsufficientAuthenticationException("Full authentication is required to access this resource")); } else { if (logger.isDebugEnabled()) { logger.debug("Access is denied (user is not anonymous); delegating to AccessDeniedHandler", exception); } - accessDeniedHandler.handle(request, response, - (AccessDeniedException) exception); + accessDeniedHandler.handle(request, response, (AccessDeniedException) exception); } } } @@ -208,52 +171,41 @@ public class ExceptionTranslationFilter implements Filter, InitializingBean { public void init(FilterConfig filterConfig) throws ServletException {} /** - * If true, indicates that - * SecurityEnforcementFilter is permitted to store the target - * URL and exception information in the HttpSession (the - * default). In situations where you do not wish to unnecessarily create - * HttpSessions - because the user agent will know the failed - * URL, such as with BASIC or Digest authentication - you may wish to set - * this property to false. Remember to also set the {@link - * org.acegisecurity.context.HttpSessionContextIntegrationFilter#allowSessionCreation} - * to false if you set this property to false. + * If true, indicates that SecurityEnforcementFilter is permitted to store the + * target URL and exception information in the HttpSession (the default). In situations where you do + * not wish to unnecessarily create HttpSessions - because the user agent will know the failed URL, + * such as with BASIC or Digest authentication - you may wish to set this property to false. Remember + * to also set the {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter#allowSessionCreation} to + * false if you set this property to false. * - * @return true if the HttpSession will be used - * to store information about the failed request, - * false if the HttpSession will not be - * used + * @return true if the HttpSession will be used to store information about the failed + * request, false if the HttpSession will not be used */ public boolean isCreateSessionAllowed() { return createSessionAllowed; } - protected void sendStartAuthentication(ServletRequest request, - ServletResponse response, FilterChain chain, + protected void sendStartAuthentication(ServletRequest request, ServletResponse response, FilterChain chain, AuthenticationException reason) throws ServletException, IOException { HttpServletRequest httpRequest = (HttpServletRequest) request; SavedRequest savedRequest = new SavedRequest(httpRequest, portResolver); if (logger.isDebugEnabled()) { - logger.debug( - "Authentication entry point being called; SavedRequest added to Session: " - + savedRequest); + logger.debug("Authentication entry point being called; SavedRequest added to Session: " + savedRequest); } if (createSessionAllowed) { // Store the HTTP request itself. Used by AbstractProcessingFilter // for redirection after successful authentication (SEC-29) - httpRequest.getSession() - .setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, - savedRequest); + httpRequest.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, savedRequest); } // SEC-112: Clear the SecurityContextHolder's Authentication, as the // existing Authentication is no longer considered valid SecurityContextHolder.getContext().setAuthentication(null); - authenticationEntryPoint.commence(httpRequest, - (HttpServletResponse) response, reason); + authenticationEntryPoint.commence(httpRequest, (HttpServletResponse) response, reason); } public void setAccessDeniedHandler(AccessDeniedHandler accessDeniedHandler) { @@ -261,13 +213,11 @@ public class ExceptionTranslationFilter implements Filter, InitializingBean { this.accessDeniedHandler = accessDeniedHandler; } - public void setAuthenticationEntryPoint( - AuthenticationEntryPoint authenticationEntryPoint) { + public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) { this.authenticationEntryPoint = authenticationEntryPoint; } - public void setAuthenticationTrustResolver( - AuthenticationTrustResolver authenticationTrustResolver) { + public void setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) { this.authenticationTrustResolver = authenticationTrustResolver; } diff --git a/core/src/main/java/org/acegisecurity/ui/WebAuthenticationDetails.java b/core/src/main/java/org/acegisecurity/ui/WebAuthenticationDetails.java index a51b4a605e..88ee0d31d1 100644 --- a/core/src/main/java/org/acegisecurity/ui/WebAuthenticationDetails.java +++ b/core/src/main/java/org/acegisecurity/ui/WebAuthenticationDetails.java @@ -29,16 +29,15 @@ import javax.servlet.http.HttpSession; * @author Ben Alex * @version $Id$ */ -public class WebAuthenticationDetails implements SessionIdentifierAware, - Serializable { - //~ Instance fields ======================================================== +public class WebAuthenticationDetails implements SessionIdentifierAware, Serializable { + //~ Instance fields ================================================================================================ private String remoteAddress; private String sessionId; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor. * *

@@ -63,7 +62,7 @@ public class WebAuthenticationDetails implements SessionIdentifierAware, throw new IllegalArgumentException("Cannot use default constructor"); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Provided so that subclasses can populate additional information. @@ -111,8 +110,7 @@ public class WebAuthenticationDetails implements SessionIdentifierAware, } /** - * Indicates the TCP/IP address the authentication request was received - * from. + * Indicates the TCP/IP address the authentication request was received from. * * @return the address */ @@ -121,8 +119,7 @@ public class WebAuthenticationDetails implements SessionIdentifierAware, } /** - * Indicates the HttpSession id the authentication request was - * received from. + * Indicates the HttpSession id the authentication request was received from. * * @return the session ID */ diff --git a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java index a93ce9612e..d72325d844 100644 --- a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java @@ -49,77 +49,41 @@ import javax.servlet.http.HttpServletResponse; /** - * Processes a HTTP request's BASIC authorization headers, putting the result - * into the SecurityContextHolder. - * - *

- * For a detailed background on what this filter is designed to process, refer - * to RFC 1945, Section - * 11.1. Any realm name presented in the HTTP request is ignored. - *

- * - *

- * In summary, this filter is responsible for processing any request that has a - * HTTP request header of Authorization with an authentication - * scheme of Basic and a Base64-encoded - * username:password token. For example, to authenticate user - * "Aladdin" with password "open sesame" the following header would be - * presented: - *

- * - *

- * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==. - *

- * - *

- * This filter can be used to provide BASIC authentication services to both - * remoting protocol clients (such as Hessian and SOAP) as well as standard - * user agents (such as Internet Explorer and Netscape). - *

- * - *

- * If authentication is successful, the resulting {@link Authentication} object - * will be placed into the SecurityContextHolder. - *

- * - *

- * If authentication fails and ignoreFailure is false - * (the default), an {@link AuthenticationEntryPoint} implementation is - * called. Usually this should be {@link BasicProcessingFilterEntryPoint}, - * which will prompt the user to authenticate again via BASIC authentication. - *

- * - *

- * Basic authentication is an attractive protocol because it is simple and - * widely deployed. However, it still transmits a password in clear text and - * as such is undesirable in many situations. Digest authentication is also - * provided by Acegi Security and should be used instead of Basic - * authentication wherever possible. See {@link - * org.acegisecurity.ui.digestauth.DigestProcessingFilter}. - *

- * - *

- * Note that if a {@link #rememberMeServices} is set, this filter will - * automatically send back remember-me details to the client. Therefore, - * subsequent requests will not need to present a BASIC authentication header - * as they will be authenticated using the remember-me mechanism. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Processes a HTTP request's BASIC authorization headers, putting the result into the + * SecurityContextHolder.

For a detailed background on what this filter is designed to process, + * refer to RFC 1945, Section 11.1. Any realm name presented in + * the HTTP request is ignored.

+ *

In summary, this filter is responsible for processing any request that has a HTTP request header of + * Authorization with an authentication scheme of Basic and a Base64-encoded + * username:password token. For example, to authenticate user "Aladdin" with password "open sesame" the + * following header would be presented:

+ *

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==.

+ *

This filter can be used to provide BASIC authentication services to both remoting protocol clients (such as + * Hessian and SOAP) as well as standard user agents (such as Internet Explorer and Netscape).

+ *

If authentication is successful, the resulting {@link Authentication} object will be placed into the + * SecurityContextHolder.

+ *

If authentication fails and ignoreFailure is false (the default), an {@link + * AuthenticationEntryPoint} implementation is called. Usually this should be {@link BasicProcessingFilterEntryPoint}, + * which will prompt the user to authenticate again via BASIC authentication.

+ *

Basic authentication is an attractive protocol because it is simple and widely deployed. However, it still + * transmits a password in clear text and as such is undesirable in many situations. Digest authentication is also + * provided by Acegi Security and should be used instead of Basic authentication wherever possible. See {@link + * org.acegisecurity.ui.digestauth.DigestProcessingFilter}.

+ *

Note that if a {@link #rememberMeServices} is set, this filter will automatically send back remember-me + * details to the client. Therefore, subsequent requests will not need to present a BASIC authentication header as + * they will be authenticated using the remember-me mechanism.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ public class BasicProcessingFilter implements Filter, InitializingBean { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); private AuthenticationEntryPoint authenticationEntryPoint; @@ -127,19 +91,17 @@ public class BasicProcessingFilter implements Filter, InitializingBean { private RememberMeServices rememberMeServices; private boolean ignoreFailure = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(this.authenticationManager, - "An AuthenticationManager is required"); - Assert.notNull(this.authenticationEntryPoint, - "An AuthenticationEntryPoint is required"); + Assert.notNull(this.authenticationManager, "An AuthenticationManager is required"); + Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required"); } public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -159,8 +121,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean { if ((header != null) && header.startsWith("Basic ")) { String base64Token = header.substring(6); - String token = new String(Base64.decodeBase64( - base64Token.getBytes())); + String token = new String(Base64.decodeBase64(base64Token.getBytes())); String username = ""; String password = ""; @@ -172,16 +133,12 @@ public class BasicProcessingFilter implements Filter, InitializingBean { } // Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated (see SEC-53) - Authentication existingAuth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); - if ((existingAuth == null) - || !existingAuth.getName().equals(username) - || !existingAuth.isAuthenticated()) { + if ((existingAuth == null) || !existingAuth.getName().equals(username) || !existingAuth.isAuthenticated()) { UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); - authRequest.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); Authentication authResult; @@ -190,8 +147,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean { } catch (AuthenticationException failed) { // Authentication failed if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " - + username + " failed: " + failed.toString()); + logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); } SecurityContextHolder.getContext().setAuthentication(null); @@ -203,8 +159,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean { if (ignoreFailure) { chain.doFilter(request, response); } else { - authenticationEntryPoint.commence(request, response, - failed); + authenticationEntryPoint.commence(request, response, failed); } return; @@ -212,15 +167,13 @@ public class BasicProcessingFilter implements Filter, InitializingBean { // Authentication success if (logger.isDebugEnabled()) { - logger.debug("Authentication success: " - + authResult.toString()); + logger.debug("Authentication success: " + authResult.toString()); } SecurityContextHolder.getContext().setAuthentication(authResult); if (rememberMeServices != null) { - rememberMeServices.loginSuccess(httpRequest, httpResponse, - authResult); + rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult); } } } @@ -242,20 +195,16 @@ public class BasicProcessingFilter implements Filter, InitializingBean { return ignoreFailure; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } - public void setAuthenticationEntryPoint( - AuthenticationEntryPoint authenticationEntryPoint) { + public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) { this.authenticationEntryPoint = authenticationEntryPoint; } - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { + public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } diff --git a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java index 0c6f9a2e1f..8e8c5074f3 100644 --- a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.ui.basicauth; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.ui.AuthenticationEntryPoint; import org.springframework.beans.factory.InitializingBean; @@ -29,36 +30,21 @@ import javax.servlet.http.HttpServletResponse; /** - * Used by the SecurityEnforcementFilter to commence - * authentication via the {@link BasicProcessingFilter}. - * - *

- * Once a user agent is authenticated using BASIC authentication, logout - * requires that the browser be closed or an unauthorized (401) header be - * sent. The simplest way of achieving the latter is to call the {@link - * #commence(ServletRequest, ServletResponse)} method below. This will - * indicate to the browser its credentials are no longer authorized, causing - * it to prompt the user to login again. - *

+ * Used by the SecurityEnforcementFilter to commence authentication via the {@link + * BasicProcessingFilter}.

Once a user agent is authenticated using BASIC authentication, logout requires that + * the browser be closed or an unauthorized (401) header be sent. The simplest way of achieving the latter is to call + * the {@link #commence(ServletRequest, ServletResponse)} method below. This will indicate to the browser its + * credentials are no longer authorized, causing it to prompt the user to login again.

* * @author Ben Alex * @version $Id$ */ -public class BasicProcessingFilterEntryPoint implements AuthenticationEntryPoint, - InitializingBean { - //~ Instance fields ======================================================== +public class BasicProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean { + //~ Instance fields ================================================================================================ private String realmName; - //~ Methods ================================================================ - - public void setRealmName(String realmName) { - this.realmName = realmName; - } - - public String getRealmName() { - return realmName; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { if ((realmName == null) || "".equals(realmName)) { @@ -66,13 +52,18 @@ public class BasicProcessingFilterEntryPoint implements AuthenticationEntryPoint } } - public void commence(ServletRequest request, ServletResponse response, - AuthenticationException authException) + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; - httpResponse.addHeader("WWW-Authenticate", - "Basic realm=\"" + realmName + "\""); - httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, - authException.getMessage()); + httpResponse.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\""); + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); + } + + public String getRealmName() { + return realmName; + } + + public void setRealmName(String realmName) { + this.realmName = realmName; } } diff --git a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java index c50b10eb89..a5eff646c7 100644 --- a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ package org.acegisecurity.ui.cas; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.ui.AbstractProcessingFilter; import javax.servlet.FilterConfig; @@ -26,71 +28,37 @@ import javax.servlet.http.HttpServletRequest; /** - * Processes a CAS service ticket. - * - *

- * A service ticket consists of an opaque ticket string. It arrives at this - * filter by the user's browser successfully authenticating using CAS, and - * then receiving a HTTP redirect to a service. The opaque ticket - * string is presented in the ticket request parameter. This - * filter monitors the service URL so it can receive the service - * ticket and process it. The CAS server knows which service URL - * to use via the {@link ServiceProperties#getService()} method. - *

- * - *

- * Processing the service ticket involves creating a - * UsernamePasswordAuthenticationToken which uses {@link - * #CAS_STATEFUL_IDENTIFIER} for the principal and the opaque - * ticket string as the credentials. - *

- * - *

- * The configured AuthenticationManager is expected to provide a - * provider that can recognise - * UsernamePasswordAuthenticationTokens containing this special - * principal name, and process them accordingly by validation - * with the CAS server. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Processes a CAS service ticket.

A service ticket consists of an opaque ticket string. It arrives at this + * filter by the user's browser successfully authenticating using CAS, and then receiving a HTTP redirect to a + * service. The opaque ticket string is presented in the ticket request parameter. This + * filter monitors the service URL so it can receive the service ticket and process it. The CAS server + * knows which service URL to use via the {@link ServiceProperties#getService()} method.

+ *

Processing the service ticket involves creating a UsernamePasswordAuthenticationToken which + * uses {@link #CAS_STATEFUL_IDENTIFIER} for the principal and the opaque ticket string as the + * credentials.

+ *

The configured AuthenticationManager is expected to provide a provider that can recognise + * UsernamePasswordAuthenticationTokens containing this special principal name, and process + * them accordingly by validation with the CAS server.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ public class CasProcessingFilter extends AbstractProcessingFilter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== - /** - * Used to identify a CAS request for a stateful user agent, such as a web - * browser. - */ + /** Used to identify a CAS request for a stateful user agent, such as a web browser. */ public static final String CAS_STATEFUL_IDENTIFIER = "_cas_stateful_"; /** - * Used to identify a CAS request for a stateless user agent, such as a - * remoting protocol client (eg Hessian, Burlap, SOAP etc). Results in a - * more aggressive caching strategy being used, as the absence of a - * HttpSession will result in a new authentication attempt on - * every request. + * Used to identify a CAS request for a stateless user agent, such as a remoting protocol client (eg + * Hessian, Burlap, SOAP etc). Results in a more aggressive caching strategy being used, as the absence of a + * HttpSession will result in a new authentication attempt on every request. */ public static final String CAS_STATELESS_IDENTIFIER = "_cas_stateless_"; - //~ Methods ================================================================ - - /** - * This filter by default responds to - * /j_acegi_cas_security_check. - * - * @return the default - */ - public String getDefaultFilterProcessesUrl() { - return "/j_acegi_cas_security_check"; - } + //~ Methods ======================================================================================================== public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { @@ -101,13 +69,21 @@ public class CasProcessingFilter extends AbstractProcessingFilter { password = ""; } - UsernamePasswordAuthenticationToken authRequest = - new UsernamePasswordAuthenticationToken(username, password); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); return this.getAuthenticationManager().authenticate(authRequest); } + /** + * This filter by default responds to /j_acegi_cas_security_check. + * + * @return the default + */ + public String getDefaultFilterProcessesUrl() { + return "/j_acegi_cas_security_check"; + } + public void init(FilterConfig filterConfig) throws ServletException {} } diff --git a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java index 4eea5290b6..e09c2e2fb8 100644 --- a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,12 @@ package org.acegisecurity.ui.cas; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.ui.AuthenticationEntryPoint; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; -import org.springframework.util.StringUtils; import java.io.IOException; @@ -34,33 +35,46 @@ import javax.servlet.http.HttpServletResponse; /** - * Used by the SecurityEnforcementFilter to commence - * authentication via the JA-SIG Central Authentication Service (CAS). - * - *

- * The user's browser will be redirected to the JA-SIG CAS enterprise-wide login - * page. This page is specified by the loginUrl property. Once - * login is complete, the CAS login page will redirect to the page indicated - * by the service property. The service is a HTTP - * URL belonging to the current application. The service URL is - * monitored by the {@link CasProcessingFilter}, which will validate the CAS - * login was successful. - *

+ * Used by the SecurityEnforcementFilter to commence authentication via the JA-SIG Central + * Authentication Service (CAS).

The user's browser will be redirected to the JA-SIG CAS enterprise-wide login + * page. This page is specified by the loginUrl property. Once login is complete, the CAS login page will + * redirect to the page indicated by the service property. The service is a HTTP URL + * belonging to the current application. The service URL is monitored by the {@link CasProcessingFilter}, + * which will validate the CAS login was successful.

* * @author Ben Alex * @version $Id$ */ -public class CasProcessingFilterEntryPoint implements AuthenticationEntryPoint, - InitializingBean { - //~ Instance fields ======================================================== +public class CasProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean { + //~ Instance fields ================================================================================================ private ServiceProperties serviceProperties; private String loginUrl; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setLoginUrl(final String loginUrl) { - this.loginUrl = loginUrl; + public void afterPropertiesSet() throws Exception { + Assert.hasLength(this.loginUrl, "loginUrl must be specified"); + Assert.notNull(this.serviceProperties, "serviceProperties must be specified"); + } + + public void commence(final ServletRequest servletRequest, final ServletResponse servletResponse, + final AuthenticationException authenticationException) + throws IOException, ServletException { + final HttpServletRequest request = (HttpServletRequest) servletRequest; + final HttpServletResponse response = (HttpServletResponse) servletResponse; + final String urlEncodedService = response.encodeURL(this.serviceProperties.getService()); + + final StringBuffer buffer = new StringBuffer(255); + + synchronized (buffer) { + buffer.append(this.loginUrl); + buffer.append("?service="); + buffer.append(URLEncoder.encode(urlEncodedService, "UTF-8")); + buffer.append(this.serviceProperties.isSendRenew() ? "&renew=true" : ""); + } + + response.sendRedirect(buffer.toString()); } /** @@ -73,35 +87,15 @@ public class CasProcessingFilterEntryPoint implements AuthenticationEntryPoint, return this.loginUrl; } - public void setServiceProperties(final ServiceProperties serviceProperties) { - this.serviceProperties = serviceProperties; - } - public ServiceProperties getServiceProperties() { return this.serviceProperties; } - public void afterPropertiesSet() throws Exception { - Assert.hasLength(this.loginUrl, "loginUrl must be specified"); - Assert.notNull(this.serviceProperties, "serviceProperties must be specified"); + public void setLoginUrl(final String loginUrl) { + this.loginUrl = loginUrl; } - public void commence(final ServletRequest servletRequest, final ServletResponse servletResponse, - final AuthenticationException authenticationException) - throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final String urlEncodedService = response.encodeURL(this.serviceProperties.getService()); - - final StringBuffer buffer = new StringBuffer(255); - - synchronized (buffer) { - buffer.append(this.loginUrl); - buffer.append("?service="); - buffer.append(URLEncoder.encode(urlEncodedService, "UTF-8")); - buffer.append(this.serviceProperties.isSendRenew() ? "&renew=true" : ""); - } - - response.sendRedirect(buffer.toString()); + public void setServiceProperties(final ServiceProperties serviceProperties) { + this.serviceProperties = serviceProperties; } } diff --git a/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java b/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java index 32cc887487..0e38b1c614 100644 --- a/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java +++ b/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,61 +19,31 @@ import org.springframework.beans.factory.InitializingBean; /** - * Stores properties related to this CAS service. - * - *

- * Each web application capable of processing CAS tickets is known as a - * service. This class stores the properties that are relevant to the local - * CAS service, being the application that is being secured by the Acegi - * Security System for Spring. - *

+ * Stores properties related to this CAS service.

Each web application capable of processing CAS tickets is known + * as a service. This class stores the properties that are relevant to the local CAS service, being the application + * that is being secured by the Acegi Security System for Spring.

* * @author Ben Alex * @version $Id$ */ public class ServiceProperties implements InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String service; private boolean sendRenew = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setSendRenew(boolean sendRenew) { - this.sendRenew = sendRenew; + public void afterPropertiesSet() throws Exception { + if ((service == null) || "".equals(service)) { + throw new IllegalArgumentException("service must be specified"); + } } /** - * Indicates whether the renew parameter should be sent to the - * CAS login URL and CAS validation URL. - * - *

- * If true, it will force CAS to authenticate the user again - * (even if the user has previously authenticated). During ticket - * validation it will require the ticket was generated as a consequence of - * an explicit login. High security applications would probably set this - * to true. Defaults to false, providing - * automated single sign on. - *

- * - * @return whether to send the renew parameter to CAS - */ - public boolean isSendRenew() { - return sendRenew; - } - - public void setService(String service) { - this.service = service; - } - - /** - * Represents the service the user is authenticating to. - * - *

- * This service is the callback URL belonging to the local Acegi Security - * System for Spring secured application. For example, - *

- * https://www.mycompany.com/application/j_acegi_cas_security_check + * Represents the service the user is authenticating to.

This service is the callback URL belonging to + * the local Acegi Security System for Spring secured application. For example,

+ * https://www.mycompany.com/application/j_acegi_cas_security_check * * @return the URL of the service the user is authenticating to */ @@ -81,9 +51,24 @@ public class ServiceProperties implements InitializingBean { return service; } - public void afterPropertiesSet() throws Exception { - if ((service == null) || "".equals(service)) { - throw new IllegalArgumentException("service must be specified"); - } + /** + * Indicates whether the renew parameter should be sent to the CAS login URL and CAS + * validation URL.

If true, it will force CAS to authenticate the user again (even if the + * user has previously authenticated). During ticket validation it will require the ticket was generated as a + * consequence of an explicit login. High security applications would probably set this to true. + * Defaults to false, providing automated single sign on.

+ * + * @return whether to send the renew parameter to CAS + */ + public boolean isSendRenew() { + return sendRenew; + } + + public void setSendRenew(boolean sendRenew) { + this.sendRenew = sendRenew; + } + + public void setService(String service) { + this.service = service; } } diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java index 958771d879..f954ac752a 100644 --- a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java @@ -64,64 +64,32 @@ import javax.servlet.http.HttpServletResponse; /** - * Processes a HTTP request's Digest authorization headers, putting the result - * into the SecurityContextHolder. - * - *

- * For a detailed background on what this filter is designed to process, refer - * to RFC 2617 (which - * superseded RFC 2069, although this filter support clients that implement - * either RFC 2617 or RFC 2069). - *

- * - *

- * This filter can be used to provide Digest authentication services to both - * remoting protocol clients (such as Hessian and SOAP) as well as standard - * user agents (such as Internet Explorer and FireFox). - *

- * - *

- * This Digest implementation has been designed to avoid needing to store - * session state between invocations. All session management information is - * stored in the "nonce" that is sent to the client by the {@link - * DigestProcessingFilterEntryPoint}. - *

- * - *

- * If authentication is successful, the resulting {@link - * org.acegisecurity.Authentication Authentication} object will be placed into - * the SecurityContextHolder. - *

- * - *

- * If authentication fails, an {@link - * org.acegisecurity.ui.AuthenticationEntryPoint AuthenticationEntryPoint} - * implementation is called. This must always be {@link - * DigestProcessingFilterEntryPoint}, which will prompt the user to - * authenticate again via Digest authentication. - *

- * - *

- * Note there are limitations to Digest authentication, although it is a more - * comprehensive and secure solution than Basic authentication. Please see RFC - * 2617 section 4 for a full discussion on the advantages of Digest - * authentication over Basic authentication, including commentary on the - * limitations that it still imposes. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Processes a HTTP request's Digest authorization headers, putting the result into the + * SecurityContextHolder.

For a detailed background on what this filter is designed to process, + * refer to RFC 2617 (which superseded RFC 2069, although this + * filter support clients that implement either RFC 2617 or RFC 2069).

+ *

This filter can be used to provide Digest authentication services to both remoting protocol clients (such as + * Hessian and SOAP) as well as standard user agents (such as Internet Explorer and FireFox).

+ *

This Digest implementation has been designed to avoid needing to store session state between invocations. + * All session management information is stored in the "nonce" that is sent to the client by the {@link + * DigestProcessingFilterEntryPoint}.

+ *

If authentication is successful, the resulting {@link org.acegisecurity.Authentication Authentication} + * object will be placed into the SecurityContextHolder.

+ *

If authentication fails, an {@link org.acegisecurity.ui.AuthenticationEntryPoint AuthenticationEntryPoint} + * implementation is called. This must always be {@link DigestProcessingFilterEntryPoint}, which will prompt the user + * to authenticate again via Digest authentication.

+ *

Note there are limitations to Digest authentication, although it is a more comprehensive and secure solution + * than Basic authentication. Please see RFC 2617 section 4 for a full discussion on the advantages of Digest + * authentication over Basic authentication, including commentary on the limitations that it still imposes.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

*/ -public class DigestProcessingFilter implements Filter, InitializingBean, - MessageSourceAware { - //~ Static fields/initializers ============================================= +public class DigestProcessingFilter implements Filter, InitializingBean, MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(DigestProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); private DigestProcessingFilterEntryPoint authenticationEntryPoint; @@ -130,18 +98,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean, private UserDetailsService userDetailsService; private boolean passwordAlreadyEncoded = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(userDetailsService, "A UserDetailsService is required"); - Assert.notNull(authenticationEntryPoint, - "A DigestProcessingFilterEntryPoint is required"); + Assert.notNull(authenticationEntryPoint, "A DigestProcessingFilterEntryPoint is required"); } public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -155,16 +122,14 @@ public class DigestProcessingFilter implements Filter, InitializingBean, String header = httpRequest.getHeader("Authorization"); if (logger.isDebugEnabled()) { - logger.debug("Authorization header received from user agent: " - + header); + logger.debug("Authorization header received from user agent: " + header); } if ((header != null) && header.startsWith("Digest ")) { String section212response = header.substring(7); String[] headerEntries = StringUtils.commaDelimitedListToStringArray(section212response); - Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, - "=", "\""); + Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\""); String username = (String) headerMap.get("username"); String realm = (String) headerMap.get("realm"); @@ -176,20 +141,15 @@ public class DigestProcessingFilter implements Filter, InitializingBean, String cnonce = (String) headerMap.get("cnonce"); // RFC 2617 extension // Check all required parameters were supplied (ie RFC 2069) - if ((username == null) || (realm == null) || (nonce == null) - || (uri == null) || (response == null)) { + if ((username == null) || (realm == null) || (nonce == null) || (uri == null) || (response == null)) { if (logger.isDebugEnabled()) { - logger.debug("extracted username: '" + username - + "'; realm: '" + username + "'; nonce: '" + username - + "'; uri: '" + username + "'; response: '" + username - + "'"); + logger.debug("extracted username: '" + username + "'; realm: '" + username + "'; nonce: '" + + username + "'; uri: '" + username + "'; response: '" + username + "'"); } fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.missingMandatory", - new Object[] {section212response}, - "Missing mandatory digest value; received header {0}"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.missingMandatory", + new Object[] {section212response}, "Missing mandatory digest value; received header {0}"))); return; } @@ -198,15 +158,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean, if ("auth".equals(qop)) { if ((nc == null) || (cnonce == null)) { if (logger.isDebugEnabled()) { - logger.debug("extracted nc: '" + nc + "'; cnonce: '" - + cnonce + "'"); + logger.debug("extracted nc: '" + nc + "'; cnonce: '" + cnonce + "'"); } fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.missingAuth", - new Object[] {section212response}, - "Missing mandatory digest value; received header {0}"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.missingAuth", + new Object[] {section212response}, "Missing mandatory digest value; received header {0}"))); return; } @@ -215,10 +172,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, // Check realm name equals what we expected if (!this.getAuthenticationEntryPoint().getRealmName().equals(realm)) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.incorrectRealm", - new Object[] {realm, this.getAuthenticationEntryPoint() - .getRealmName()}, + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.incorrectRealm", + new Object[] {realm, this.getAuthenticationEntryPoint().getRealmName()}, "Response realm name '{0}' does not match system realm name of '{1}'"))); return; @@ -227,10 +182,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, // Check nonce was a Base64 encoded (as sent by DigestProcessingFilterEntryPoint) if (!Base64.isArrayByteBase64(nonce.getBytes())) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.nonceEncoding", - new Object[] {nonce}, - "Nonce is not encoded in Base64; received nonce {0}"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.nonceEncoding", + new Object[] {nonce}, "Nonce is not encoded in Base64; received nonce {0}"))); return; } @@ -238,17 +191,13 @@ public class DigestProcessingFilter implements Filter, InitializingBean, // Decode nonce from Base64 // format of nonce is: // base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) - String nonceAsPlainText = new String(Base64.decodeBase64( - nonce.getBytes())); - String[] nonceTokens = StringUtils.delimitedListToStringArray(nonceAsPlainText, - ":"); + String nonceAsPlainText = new String(Base64.decodeBase64(nonce.getBytes())); + String[] nonceTokens = StringUtils.delimitedListToStringArray(nonceAsPlainText, ":"); if (nonceTokens.length != 2) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.nonceNotTwoTokens", - new Object[] {nonceAsPlainText}, - "Nonce should have yielded two tokens but was {0}"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.nonceNotTwoTokens", + new Object[] {nonceAsPlainText}, "Nonce should have yielded two tokens but was {0}"))); return; } @@ -260,8 +209,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean, nonceExpiryTime = new Long(nonceTokens[0]).longValue(); } catch (NumberFormatException nfe) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.nonceNotNumeric", + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.nonceNotNumeric", new Object[] {nonceAsPlainText}, "Nonce token should have yielded a numeric first token, but was {0}"))); @@ -269,15 +217,13 @@ public class DigestProcessingFilter implements Filter, InitializingBean, } // Check signature of nonce matches this expiry time - String expectedNonceSignature = DigestUtils.md5Hex(nonceExpiryTime - + ":" + this.getAuthenticationEntryPoint().getKey()); + String expectedNonceSignature = DigestUtils.md5Hex(nonceExpiryTime + ":" + + this.getAuthenticationEntryPoint().getKey()); if (!expectedNonceSignature.equals(nonceTokens[1])) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.nonceCompromised", - new Object[] {nonceAsPlainText}, - "Nonce token compromised {0}"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.nonceCompromised", + new Object[] {nonceAsPlainText}, "Nonce token compromised {0}"))); return; } @@ -295,10 +241,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, user = userDetailsService.loadUserByUsername(username); } catch (UsernameNotFoundException notFound) { fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.usernameNotFound", - new Object[] {username}, - "Username {0} not found"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.usernameNotFound", + new Object[] {username}, "Username {0} not found"))); return; } @@ -315,10 +259,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean, String serverDigestMd5; // Don't catch IllegalArgumentException (already checked validity) - serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, - realm, user.getPassword(), - ((HttpServletRequest) request).getMethod(), uri, qop, - nonce, nc, cnonce); + serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm, user.getPassword(), + ((HttpServletRequest) request).getMethod(), uri, qop, nonce, nc, cnonce); // If digest is incorrect, try refreshing from backend and recomputing if (!serverDigestMd5.equals(responseDigest) && !loadedFromDao) { @@ -332,32 +274,26 @@ public class DigestProcessingFilter implements Filter, InitializingBean, } catch (UsernameNotFoundException notFound) { // Would very rarely happen, as user existed earlier fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.usernameNotFound", - new Object[] {username}, - "Username {0} not found"))); + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.usernameNotFound", + new Object[] {username}, "Username {0} not found"))); } userCache.putUserInCache(user); // Don't catch IllegalArgumentException (already checked validity) - serverDigestMd5 = generateDigest(passwordAlreadyEncoded, - username, realm, user.getPassword(), - ((HttpServletRequest) request).getMethod(), uri, qop, - nonce, nc, cnonce); + serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm, user.getPassword(), + ((HttpServletRequest) request).getMethod(), uri, qop, nonce, nc, cnonce); } // If digest is still incorrect, definitely reject authentication attempt if (!serverDigestMd5.equals(responseDigest)) { if (logger.isDebugEnabled()) { - logger.debug("Expected response: '" + serverDigestMd5 - + "' but received: '" + responseDigest + logger.debug("Expected response: '" + serverDigestMd5 + "' but received: '" + responseDigest + "'; is AuthenticationDao returning clear text passwords?"); } fail(request, response, - new BadCredentialsException(messages.getMessage( - "DigestProcessingFilter.incorrectResponse", + new BadCredentialsException(messages.getMessage("DigestProcessingFilter.incorrectResponse", "Incorrect response"))); return; @@ -369,23 +305,21 @@ public class DigestProcessingFilter implements Filter, InitializingBean, // but the request was otherwise appearing to be valid if (nonceExpiryTime < System.currentTimeMillis()) { fail(request, response, - new NonceExpiredException(messages.getMessage( - "DigestProcessingFilter.nonceExpired", + new NonceExpiredException(messages.getMessage("DigestProcessingFilter.nonceExpired", "Nonce has expired/timed out"))); return; } if (logger.isDebugEnabled()) { - logger.debug("Authentication success for user: '" + username - + "' with response: '" + responseDigest + "'"); + logger.debug("Authentication success for user: '" + username + "' with response: '" + responseDigest + + "'"); } UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user, user.getPassword()); - authRequest.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); SecurityContextHolder.getContext().setAuthentication(authRequest); } @@ -393,16 +327,15 @@ public class DigestProcessingFilter implements Filter, InitializingBean, chain.doFilter(request, response); } - public static String encodePasswordInA1Format(String username, - String realm, String password) { + public static String encodePasswordInA1Format(String username, String realm, String password) { String a1 = username + ":" + realm + ":" + password; String a1Md5 = new String(DigestUtils.md5Hex(a1)); return a1Md5; } - private void fail(ServletRequest request, ServletResponse response, - AuthenticationException failed) throws IOException, ServletException { + private void fail(ServletRequest request, ServletResponse response, AuthenticationException failed) + throws IOException, ServletException { SecurityContextHolder.getContext().setAuthentication(null); if (logger.isDebugEnabled()) { @@ -413,13 +346,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean, } /** - * Computes the response portion of a Digest authentication - * header. Both the server and user agent should compute the - * response independently. Provided as a static method to - * simplify the coding of user agents. + * Computes the response portion of a Digest authentication header. Both the server and user + * agent should compute the response independently. Provided as a static method to simplify the + * coding of user agents. * - * @param passwordAlreadyEncoded true if the password argument is already - * encoded in the correct format. False if it is plain text. + * @param passwordAlreadyEncoded true if the password argument is already encoded in the correct format. False if + * it is plain text. * @param username the user's login name. * @param realm the name of the realm. * @param password the user's password in plaintext or ready-encoded. @@ -432,12 +364,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean, * * @return the MD5 of the digest authentication response, encoded in hex * - * @throws IllegalArgumentException if the supplied qop value is - * unsupported. + * @throws IllegalArgumentException if the supplied qop value is unsupported. */ - public static String generateDigest(boolean passwordAlreadyEncoded, - String username, String realm, String password, String httpMethod, - String uri, String qop, String nonce, String nc, String cnonce) + public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm, String password, + String httpMethod, String uri, String qop, String nonce, String nc, String cnonce) throws IllegalArgumentException { String a1Md5 = null; String a2 = httpMethod + ":" + uri; @@ -456,11 +386,9 @@ public class DigestProcessingFilter implements Filter, InitializingBean, digest = a1Md5 + ":" + nonce + ":" + a2Md5; } else if ("auth".equals(qop)) { // As per RFC 2617 compliant clients - digest = a1Md5 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop - + ":" + a2Md5; + digest = a1Md5 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + a2Md5; } else { - throw new IllegalArgumentException( - "This method does not support a qop: '" + qop + "'"); + throw new IllegalArgumentException("This method does not support a qop: '" + qop + "'"); } String digestMd5 = new String(DigestUtils.md5Hex(digest)); @@ -482,15 +410,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean, public void init(FilterConfig ignored) throws ServletException {} - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } - public void setAuthenticationEntryPoint( - DigestProcessingFilterEntryPoint authenticationEntryPoint) { + public void setAuthenticationEntryPoint(DigestProcessingFilterEntryPoint authenticationEntryPoint) { this.authenticationEntryPoint = authenticationEntryPoint; } diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java index 0087c6171e..ffe85c6a4f 100644 --- a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.ui.digestauth; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.ui.AuthenticationEntryPoint; import org.apache.commons.codec.binary.Base64; @@ -34,60 +35,28 @@ import javax.servlet.http.HttpServletResponse; /** - * Used by the SecurityEnforcementFilter to commence - * authentication via the {@link DigestProcessingFilter}. - * - *

- * The nonce sent back to the user agent will be valid for the period indicated - * by {@link #setNonceValiditySeconds(int)}. By default this is 300 seconds. - * Shorter times should be used if replay attacks are a major concern. Larger - * values can be used if performance is a greater concern. This class - * correctly presents the stale=true header when the nonce has - * expierd, so properly implemented user agents will automatically renegotiate - * with a new nonce value (ie without presenting a new password dialog box to - * the user). - *

+ * Used by the SecurityEnforcementFilter to commence authentication via the {@link + * DigestProcessingFilter}.

The nonce sent back to the user agent will be valid for the period indicated by + * {@link #setNonceValiditySeconds(int)}. By default this is 300 seconds. Shorter times should be used if replay + * attacks are a major concern. Larger values can be used if performance is a greater concern. This class correctly + * presents the stale=true header when the nonce has expierd, so properly implemented user agents will + * automatically renegotiate with a new nonce value (ie without presenting a new password dialog box to the user).

* * @author Ben Alex * @version $Id$ */ -public class DigestProcessingFilterEntryPoint - implements AuthenticationEntryPoint, InitializingBean { - //~ Static fields/initializers ============================================= +public class DigestProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(DigestProcessingFilterEntryPoint.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String key; private String realmName; private int nonceValiditySeconds = 300; - //~ Methods ================================================================ - - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; - } - - public void setNonceValiditySeconds(int nonceValiditySeconds) { - this.nonceValiditySeconds = nonceValiditySeconds; - } - - public int getNonceValiditySeconds() { - return nonceValiditySeconds; - } - - public void setRealmName(String realmName) { - this.realmName = realmName; - } - - public String getRealmName() { - return realmName; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { if ((realmName == null) || "".equals(realmName)) { @@ -99,39 +68,57 @@ public class DigestProcessingFilterEntryPoint } } - public void commence(ServletRequest request, ServletResponse response, - AuthenticationException authException) + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; // compute a nonce (do not use remote IP address due to proxy farms) // format of nonce is: // base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) - long expiryTime = System.currentTimeMillis() - + (nonceValiditySeconds * 1000); - String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" - + key)); + long expiryTime = System.currentTimeMillis() + (nonceValiditySeconds * 1000); + String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" + key)); String nonceValue = expiryTime + ":" + signatureValue; - String nonceValueBase64 = new String(Base64.encodeBase64( - nonceValue.getBytes())); + String nonceValueBase64 = new String(Base64.encodeBase64(nonceValue.getBytes())); // qop is quality of protection, as defined by RFC 2617. // we do not use opaque due to IE violation of RFC 2617 in not // representing opaque on subsequent requests in same session. - String authenticateHeader = "Digest realm=\"" + realmName + "\", " - + "qop=\"auth\", nonce=\"" + nonceValueBase64 + "\""; + String authenticateHeader = "Digest realm=\"" + realmName + "\", " + "qop=\"auth\", nonce=\"" + + nonceValueBase64 + "\""; if (authException instanceof NonceExpiredException) { authenticateHeader = authenticateHeader + ", stale=\"true\""; } if (logger.isDebugEnabled()) { - logger.debug("WWW-Authenticate header sent to user agent: " - + authenticateHeader); + logger.debug("WWW-Authenticate header sent to user agent: " + authenticateHeader); } httpResponse.addHeader("WWW-Authenticate", authenticateHeader); - httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, - authException.getMessage()); + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); + } + + public String getKey() { + return key; + } + + public int getNonceValiditySeconds() { + return nonceValiditySeconds; + } + + public String getRealmName() { + return realmName; + } + + public void setKey(String key) { + this.key = key; + } + + public void setNonceValiditySeconds(int nonceValiditySeconds) { + this.nonceValiditySeconds = nonceValiditySeconds; + } + + public void setRealmName(String realmName) { + this.realmName = realmName; } } diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/NonceExpiredException.java b/core/src/main/java/org/acegisecurity/ui/digestauth/NonceExpiredException.java index 525ba87080..205918627d 100644 --- a/core/src/main/java/org/acegisecurity/ui/digestauth/NonceExpiredException.java +++ b/core/src/main/java/org/acegisecurity/ui/digestauth/NonceExpiredException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,15 @@ import org.acegisecurity.AuthenticationException; /** - * Thrown if an authentication request is rejected because the digest nonce has - * expired. + * Thrown if an authentication request is rejected because the digest nonce has expired. * * @author Ben Alex * @version $Id$ */ public class NonceExpiredException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a NonceExpiredException with the specified * message. * @@ -38,7 +37,7 @@ public class NonceExpiredException extends AuthenticationException { super(msg); } - /** +/** * Constructs a NonceExpiredException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java b/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java index 3294b337ee..782d244bcf 100644 --- a/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java @@ -37,40 +37,28 @@ import javax.servlet.http.HttpServletResponse; /** - * Logs a principal out. - * - *

- * Polls a series of {@link LogoutHandler}s. The handlers should be specified - * in the order they are required. Generally you will want to call logout - * handlers TokenBasedRememberMeServices and - * SecurityContextLogoutHandler (in that order). - *

- * - *

- * After logout, the URL specified by {@link #logoutSuccessUrl} will be shown. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Logs a principal out.

Polls a series of {@link LogoutHandler}s. The handlers should be specified in the order + * they are required. Generally you will want to call logout handlers TokenBasedRememberMeServices and + * SecurityContextLogoutHandler (in that order).

+ *

After logout, the URL specified by {@link #logoutSuccessUrl} will be shown.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ public class LogoutFilter implements Filter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(LogoutFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String filterProcessesUrl = "/j_acegi_logout"; private String logoutSuccessUrl; private LogoutHandler[] handlers; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public LogoutFilter(String logoutSuccessUrl, LogoutHandler[] handlers) { Assert.hasText(logoutSuccessUrl, "LogoutSuccessUrl required"); @@ -79,15 +67,15 @@ public class LogoutFilter implements Filter { this.handlers = handlers; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Not used. Use IoC container lifecycle methods instead. */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -100,12 +88,10 @@ public class LogoutFilter implements Filter { HttpServletResponse httpResponse = (HttpServletResponse) response; if (requiresLogout(httpRequest, httpResponse)) { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (logger.isDebugEnabled()) { - logger.debug("Logging out user '" + auth - + "' and redirecting to logout page"); + logger.debug("Logging out user '" + auth + "' and redirecting to logout page"); } if (auth != null) { @@ -137,11 +123,9 @@ public class LogoutFilter implements Filter { * @param request the request * @param response the response * - * @return true if logout should occur, false - * otherwise + * @return true if logout should occur, false otherwise */ - protected boolean requiresLogout(HttpServletRequest request, - HttpServletResponse response) { + protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) { String uri = request.getRequestURI(); int pathParamIndex = uri.indexOf(';'); @@ -162,8 +146,8 @@ public class LogoutFilter implements Filter { * * @throws IOException in the event of any failure */ - protected void sendRedirect(HttpServletRequest request, - HttpServletResponse response, String url) throws IOException { + protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) + throws IOException { if (!url.startsWith("http://") && !url.startsWith("https://")) { url = request.getContextPath() + url; } diff --git a/core/src/main/java/org/acegisecurity/ui/logout/LogoutHandler.java b/core/src/main/java/org/acegisecurity/ui/logout/LogoutHandler.java index 24c363a850..05dadf6c2d 100644 --- a/core/src/main/java/org/acegisecurity/ui/logout/LogoutHandler.java +++ b/core/src/main/java/org/acegisecurity/ui/logout/LogoutHandler.java @@ -1,9 +1,25 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.ui.logout; +import org.acegisecurity.Authentication; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.acegisecurity.Authentication; /** * Indicates a class that is able to participate in logout handling. @@ -15,13 +31,14 @@ import org.acegisecurity.Authentication; * @version $Id$ */ public interface LogoutHandler { - - /** - * Causes a logout to be completed. The method must complete successfully. - * - * @param request the HTTP request - * @param response the HTTP resonse - * @param authentication the current principal details - */ - public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication); + //~ Methods ======================================================================================================== + + /** + * Causes a logout to be completed. The method must complete successfully. + * + * @param request the HTTP request + * @param response the HTTP resonse + * @param authentication the current principal details + */ + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication); } diff --git a/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java b/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java index 99a5745a40..f7649062e9 100644 --- a/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java +++ b/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java @@ -24,14 +24,13 @@ import javax.servlet.http.HttpServletResponse; /** - * Performs a logout by modifying the {@link - * org.acegisecurity.context.SecurityContextHolder}. + * Performs a logout by modifying the {@link org.acegisecurity.context.SecurityContextHolder}. * * @author Ben Alex * @version $Id$ */ public class SecurityContextLogoutHandler implements LogoutHandler { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Does not use any arguments. They can all be null. @@ -40,8 +39,7 @@ public class SecurityContextLogoutHandler implements LogoutHandler { * @param response not used (can be null) * @param authentication not used (can be null) */ - public void logout(HttpServletRequest request, - HttpServletResponse response, Authentication authentication) { + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { SecurityContextHolder.clearContext(); } } diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/NullRememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/NullRememberMeServices.java index 9a33882487..e5bfb3adda 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/NullRememberMeServices.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/NullRememberMeServices.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,26 +22,21 @@ import javax.servlet.http.HttpServletResponse; /** - * Implementation of {@link NullRememberMeServices} that does nothing. - * - *

- * Used as a default by several framework classes. - *

+ * Implementation of {@link NullRememberMeServices} that does nothing.

Used as a default by several framework + * classes.

* * @author Ben Alex * @version $Id$ */ public class NullRememberMeServices implements RememberMeServices { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public Authentication autoLogin(HttpServletRequest request, - HttpServletResponse response) { + public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) { return null; } - public void loginFail(HttpServletRequest request, - HttpServletResponse response) {} + public void loginFail(HttpServletRequest request, HttpServletResponse response) {} - public void loginSuccess(HttpServletRequest request, - HttpServletResponse response, Authentication successfulAuthentication) {} + public void loginSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication successfulAuthentication) {} } diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilter.java index 265629d3b4..deb571894d 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilter.java @@ -46,57 +46,36 @@ import javax.servlet.http.HttpServletResponse; /** - * Detects if there is no Authentication object in the - * SecurityContext, and populates it with a remember-me - * authentication token if a {@link - * org.acegisecurity.ui.rememberme.RememberMeServices} implementation so - * requests. - * - *

- * Concrete RememberMeServices implementations will have their - * {@link - * org.acegisecurity.ui.rememberme.RememberMeServices#autoLogin(HttpServletRequest, - * HttpServletResponse)} method called by this filter. The - * Authentication or null returned by that method - * will be placed into the SecurityContext. The - * AuthenticationManager will be used, so that any concurrent - * session management or other authentication-specific behaviour can be - * achieved. This is the same pattern as with other authentication mechanisms, - * which call the AuthenticationManager as part of their - * contract. - *

- * - *

- * If authentication is successful, an {@link - * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} - * will be published to the application context. No events will be published - * if authentication was unsuccessful, because this would generally be - * recorded via an AuthenticationManager-specific application - * event. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Detects if there is no Authentication object in the SecurityContext, and populates it + * with a remember-me authentication token if a {@link org.acegisecurity.ui.rememberme.RememberMeServices} + * implementation so requests.

Concrete RememberMeServices implementations will have their {@link + * org.acegisecurity.ui.rememberme.RememberMeServices#autoLogin(HttpServletRequest, HttpServletResponse)} method + * called by this filter. The Authentication or null returned by that method will be placed + * into the SecurityContext. The AuthenticationManager will be used, so that any concurrent + * session management or other authentication-specific behaviour can be achieved. This is the same pattern as with + * other authentication mechanisms, which call the AuthenticationManager as part of their contract.

+ *

If authentication is successful, an {@link + * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be published to the application + * context. No events will be published if authentication was unsuccessful, because this would generally be recorded + * via an AuthenticationManager-specific application event.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @version $Id$ */ -public class RememberMeProcessingFilter implements Filter, InitializingBean, - ApplicationEventPublisherAware { - //~ Static fields/initializers ============================================= +public class RememberMeProcessingFilter implements Filter, InitializingBean, ApplicationEventPublisherAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(RememberMeProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationEventPublisher eventPublisher; private AuthenticationManager authenticationManager; private RememberMeServices rememberMeServices = new NullRememberMeServices(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(rememberMeServices, "RememberMeServices required"); @@ -108,8 +87,8 @@ public class RememberMeProcessingFilter implements Filter, InitializingBean, */ public void destroy() {} - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -122,53 +101,42 @@ public class RememberMeProcessingFilter implements Filter, InitializingBean, HttpServletResponse httpResponse = (HttpServletResponse) response; if (SecurityContextHolder.getContext().getAuthentication() == null) { - Authentication rememberMeAuth = rememberMeServices.autoLogin(httpRequest, - httpResponse); + Authentication rememberMeAuth = rememberMeServices.autoLogin(httpRequest, httpResponse); if (rememberMeAuth != null) { // Attempt authenticaton via AuthenticationManager try { authenticationManager.authenticate(rememberMeAuth); - + // Store to SecurityContextHolder - SecurityContextHolder.getContext() - .setAuthentication(rememberMeAuth); + SecurityContextHolder.getContext().setAuthentication(rememberMeAuth); if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder populated with remember-me token: '" - + SecurityContextHolder.getContext().getAuthentication() - + "'"); + logger.debug("SecurityContextHolder populated with remember-me token: '" + + SecurityContextHolder.getContext().getAuthentication() + "'"); } // Fire event if (this.eventPublisher != null) { eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent( - SecurityContextHolder.getContext() - .getAuthentication(), - this.getClass())); + SecurityContextHolder.getContext().getAuthentication(), this.getClass())); } } catch (AuthenticationException authenticationException) { if (logger.isDebugEnabled()) { logger.debug( "SecurityContextHolder not populated with remember-me token, as AuthenticationManager rejected Authentication returned by RememberMeServices: '" - + rememberMeAuth - + "'; invalidating remember-me token", - authenticationException); + + rememberMeAuth + "'; invalidating remember-me token", authenticationException); } rememberMeServices.loginFail(httpRequest, httpResponse); } - } chain.doFilter(request, response); } else { if (logger.isDebugEnabled()) { - logger.debug( - "SecurityContextHolder not populated with remember-me token, as it already contained: '" - + SecurityContextHolder.getContext().getAuthentication() - + "'"); + logger.debug("SecurityContextHolder not populated with remember-me token, as it already contained: '" + + SecurityContextHolder.getContext().getAuthentication() + "'"); } chain.doFilter(request, response); @@ -188,13 +156,11 @@ public class RememberMeProcessingFilter implements Filter, InitializingBean, */ public void init(FilterConfig ignored) throws ServletException {} - public void setApplicationEventPublisher( - ApplicationEventPublisher eventPublisher) { + public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { + public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java index 144d1aef1a..069cea6bf6 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,65 +51,48 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public interface RememberMeServices { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This method will be called whenever the SecurityContextHolder does - * not contain an Authentication and the Acegi Security - * system wishes to provide an implementation with an opportunity to - * authenticate the request using remember-me capabilities. Acegi Security - * makes no attempt whatsoever to determine whether the browser has - * requested remember-me services or presented a valid cookie. Such - * determinations are left to the implementation. If a browser has - * presented an unauthorised cookie for whatever reason, it should be - * silently ignored and invalidated using the - * HttpServletResponse object. - * - *

- * The returned Authentication must be acceptable to {@link - * org.acegisecurity.AuthenticationManager} or {@link - * org.acegisecurity.providers.AuthenticationProvider} defined by the - * web application. It is recommended {@link - * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken} - * be used in most cases, as it has a corresponding authentication - * provider. - *

+ * This method will be called whenever the SecurityContextHolder does not contain an + * Authentication and the Acegi Security system wishes to provide an implementation with an + * opportunity to authenticate the request using remember-me capabilities. Acegi Security makes no attempt + * whatsoever to determine whether the browser has requested remember-me services or presented a valid cookie. + * Such determinations are left to the implementation. If a browser has presented an unauthorised cookie for + * whatever reason, it should be silently ignored and invalidated using the HttpServletResponse + * object.

The returned Authentication must be acceptable to {@link + * org.acegisecurity.AuthenticationManager} or {@link org.acegisecurity.providers.AuthenticationProvider} defined + * by the web application. It is recommended {@link + * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken} be used in most cases, as it has a + * corresponding authentication provider.

* * @param request to look for a remember-me token within * @param response to change, cancel or modify the remember-me token * - * @return a valid authentication object, or null if the - * request should not be authenticated + * @return a valid authentication object, or null if the request should not be authenticated */ - public Authentication autoLogin(HttpServletRequest request, - HttpServletResponse response); + public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); /** - * Called whenever an interactive authentication attempt was made, but the - * credentials supplied by the user were missing or otherwise invalid. - * Implementations should invalidate any and all remember-me tokens - * indicated in the HttpServletRequest. + * Called whenever an interactive authentication attempt was made, but the credentials supplied by the user + * were missing or otherwise invalid. Implementations should invalidate any and all remember-me tokens indicated + * in the HttpServletRequest. * * @param request that contained an invalid authentication request * @param response to change, cancel or modify the remember-me token */ - public void loginFail(HttpServletRequest request, - HttpServletResponse response); + public void loginFail(HttpServletRequest request, HttpServletResponse response); /** - * Called whenever an interactive authentication attempt is successful. An - * implementation may automatically set a remember-me token in the - * HttpServletResponse, although this is not recommended. - * Instead, implementations should typically look for a request parameter - * that indicates the browser has presented an explicit request for - * authentication to be remembered, such as the presence of a HTTP POST - * parameter. + * Called whenever an interactive authentication attempt is successful. An implementation may automatically + * set a remember-me token in the HttpServletResponse, although this is not recommended. Instead, + * implementations should typically look for a request parameter that indicates the browser has presented an + * explicit request for authentication to be remembered, such as the presence of a HTTP POST parameter. * * @param request that contained the valid authentication request * @param response to change, cancel or modify the remember-me token - * @param successfulAuthentication representing the successfully - * authenticated principal + * @param successfulAuthentication representing the successfully authenticated principal */ - public void loginSuccess(HttpServletRequest request, - HttpServletResponse response, Authentication successfulAuthentication); + public void loginSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication successfulAuthentication); } diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java index 9a8d08d6e8..5cec838c49 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java @@ -47,76 +47,43 @@ import javax.servlet.http.HttpServletResponse; /** - * Identifies previously remembered users by a Base-64 encoded cookie. - * - *

- * This implementation does not rely on an external database, so is attractive - * for simple applications. The cookie will be valid for a specific period - * from the date of the last {@link #loginSuccess(HttpServletRequest, - * HttpServletResponse, Authentication)}. As per the interface contract, this - * method will only be called when the principal completes a successful - * interactive authentication. As such the time period commences from the last - * authentication attempt where they furnished credentials - not the time - * period they last logged in via remember-me. The implementation will only - * send a remember-me token if the parameter defined by {@link - * #setParameter(String)} is present. - *

- * - *

- * An {@link org.acegisecurity.userdetails.UserDetailsService} is required by - * this implementation, so that it can construct a valid - * Authentication from the returned {@link - * org.acegisecurity.userdetails.UserDetails}. This is also necessary so that - * the user's password is available and can be checked as part of the encoded - * cookie. - *

- * - *

- * The cookie encoded by this implementation adopts the following form: - *

- * - *

- * username + ":" + expiryTime + ":" + Md5Hex(username + ":" + - * expiryTime + ":" + password + ":" + key) . - *

- * - *

- * As such, if the user changes their password any remember-me token will be - * invalidated. Equally, the system administrator may invalidate every - * remember-me token on issue by changing the key. This provides some - * reasonable approaches to recovering from a remember-me token being left on - * a public machine (eg kiosk system, Internet cafe etc). Most importantly, at - * no time is the user's password ever sent to the user agent, providing an - * important security safeguard. Unfortunately the username is necessary in - * this implementation (as we do not want to rely on a database for - * remember-me services) and as such high security applications should be - * aware of this occasionally undesired disclosure of a valid username. - *

- * - *

- * This is a basic remember-me implementation which is suitable for many - * applications. However, we recommend a database-based implementation if you - * require a more secure remember-me approach. - *

- * - *

- * By default the tokens will be valid for 14 days from the last successful - * authentication attempt. This can be changed using {@link - * #setTokenValiditySeconds(int)}. - *

+ * Identifies previously remembered users by a Base-64 encoded cookie.

This implementation does not rely on an + * external database, so is attractive for simple applications. The cookie will be valid for a specific period from + * the date of the last {@link #loginSuccess(HttpServletRequest, HttpServletResponse, Authentication)}. As per the + * interface contract, this method will only be called when the principal completes a successful interactive + * authentication. As such the time period commences from the last authentication attempt where they furnished + * credentials - not the time period they last logged in via remember-me. The implementation will only send a + * remember-me token if the parameter defined by {@link #setParameter(String)} is present.

+ *

An {@link org.acegisecurity.userdetails.UserDetailsService} is required by this implementation, so that it + * can construct a valid Authentication from the returned {@link + * org.acegisecurity.userdetails.UserDetails}. This is also necessary so that the user's password is available and can + * be checked as part of the encoded cookie.

+ *

The cookie encoded by this implementation adopts the following form:

+ *

username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key) + * .

+ *

As such, if the user changes their password any remember-me token will be invalidated. Equally, the system + * administrator may invalidate every remember-me token on issue by changing the key. This provides some reasonable + * approaches to recovering from a remember-me token being left on a public machine (eg kiosk system, Internet cafe + * etc). Most importantly, at no time is the user's password ever sent to the user agent, providing an important + * security safeguard. Unfortunately the username is necessary in this implementation (as we do not want to rely on a + * database for remember-me services) and as such high security applications should be aware of this occasionally + * undesired disclosure of a valid username.

+ *

This is a basic remember-me implementation which is suitable for many applications. However, we recommend a + * database-based implementation if you require a more secure remember-me approach.

+ *

By default the tokens will be valid for 14 days from the last successful authentication attempt. This can be + * changed using {@link #setTokenValiditySeconds(int)}.

* * @author Ben Alex * @version $Id$ */ -public class TokenBasedRememberMeServices implements RememberMeServices, - InitializingBean, LogoutHandler { - //~ Static fields/initializers ============================================= +public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler { + //~ Static fields/initializers ===================================================================================== public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY = "ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE"; public static final String DEFAULT_PARAMETER = "_acegi_security_remember_me"; protected static final Log logger = LogFactory.getLog(TokenBasedRememberMeServices.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); private String key; @@ -124,7 +91,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, private UserDetailsService userDetailsService; private long tokenValiditySeconds = 1209600; // 14 days - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(key); @@ -132,8 +99,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Assert.notNull(userDetailsService); } - public Authentication autoLogin(HttpServletRequest request, - HttpServletResponse response) { + public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) { Cookie[] cookies = request.getCookies(); if ((cookies == null) || (cookies.length == 0)) { @@ -141,8 +107,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, } for (int i = 0; i < cookies.length; i++) { - if (ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY.equals( - cookies[i].getName())) { + if (ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY.equals(cookies[i].getName())) { String cookieValue = cookies[i].getValue(); if (Base64.isArrayByteBase64(cookieValue.getBytes())) { @@ -153,21 +118,17 @@ public class TokenBasedRememberMeServices implements RememberMeServices, // Decode token from Base64 // format of token is: // username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key) - String cookieAsPlainText = new String(Base64.decodeBase64( - cookieValue.getBytes())); - String[] cookieTokens = StringUtils - .delimitedListToStringArray(cookieAsPlainText, ":"); + String cookieAsPlainText = new String(Base64.decodeBase64(cookieValue.getBytes())); + String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":"); if (cookieTokens.length == 3) { long tokenExpiryTime; try { - tokenExpiryTime = new Long(cookieTokens[1]) - .longValue(); + tokenExpiryTime = new Long(cookieTokens[1]).longValue(); } catch (NumberFormatException nfe) { cancelCookie(request, response, - "Cookie token[1] did not contain a valid number (contained '" - + cookieTokens[1] + "')"); + "Cookie token[1] did not contain a valid number (contained '" + cookieTokens[1] + "')"); return null; } @@ -175,8 +136,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, // Check it has not expired if (tokenExpiryTime < System.currentTimeMillis()) { cancelCookie(request, response, - "Cookie token[1] has expired (expired on '" - + new Date(tokenExpiryTime) + "Cookie token[1] has expired (expired on '" + new Date(tokenExpiryTime) + "'; current time is '" + new Date() + "')"); return null; @@ -187,23 +147,19 @@ public class TokenBasedRememberMeServices implements RememberMeServices, UserDetails userDetails; try { - userDetails = this.userDetailsService - .loadUserByUsername(cookieTokens[0]); + userDetails = this.userDetailsService.loadUserByUsername(cookieTokens[0]); } catch (UsernameNotFoundException notFound) { cancelCookie(request, response, - "Cookie token[0] contained username '" - + cookieTokens[0] + "' but was not found"); + "Cookie token[0] contained username '" + cookieTokens[0] + "' but was not found"); return null; } // Immediately reject if the user is not allowed to login - if (!userDetails.isAccountNonExpired() - || !userDetails.isCredentialsNonExpired() + if (!userDetails.isAccountNonExpired() || !userDetails.isCredentialsNonExpired() || !userDetails.isEnabled()) { cancelCookie(request, response, - "Cookie token[0] contained username '" - + cookieTokens[0] + "Cookie token[0] contained username '" + cookieTokens[0] + "' but account has expired, credentials have expired, or user is disabled"); return null; @@ -215,14 +171,12 @@ public class TokenBasedRememberMeServices implements RememberMeServices, // but recall this method is usually only called one per HttpSession // (as if the token is valid, it will cause SecurityContextHolder population, whilst // if invalid, will cause the cookie to be cancelled) - String expectedTokenSignature = DigestUtils.md5Hex(userDetails - .getUsername() + ":" + tokenExpiryTime + ":" - + userDetails.getPassword() + ":" + this.key); + String expectedTokenSignature = DigestUtils.md5Hex(userDetails.getUsername() + ":" + + tokenExpiryTime + ":" + userDetails.getPassword() + ":" + this.key); if (!expectedTokenSignature.equals(cookieTokens[2])) { cancelCookie(request, response, - "Cookie token[2] contained signature '" - + cookieTokens[2] + "' but expected '" + "Cookie token[2] contained signature '" + cookieTokens[2] + "' but expected '" + expectedTokenSignature + "'"); return null; @@ -233,23 +187,20 @@ public class TokenBasedRememberMeServices implements RememberMeServices, logger.debug("Remember-me cookie accepted"); } - RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(this.key, - userDetails, userDetails.getAuthorities()); - auth.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(this.key, userDetails, + userDetails.getAuthorities()); + auth.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); return auth; } else { cancelCookie(request, response, - "Cookie token did not contain 3 tokens; decoded value was '" - + cookieAsPlainText + "'"); + "Cookie token did not contain 3 tokens; decoded value was '" + cookieAsPlainText + "'"); return null; } } else { cancelCookie(request, response, - "Cookie token was not Base64 encoded; value was '" - + cookieValue + "'"); + "Cookie token was not Base64 encoded; value was '" + cookieValue + "'"); return null; } @@ -259,8 +210,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, return null; } - private void cancelCookie(HttpServletRequest request, - HttpServletResponse response, String reasonForLog) { + private void cancelCookie(HttpServletRequest request, HttpServletResponse response, String reasonForLog) { if ((reasonForLog != null) && logger.isDebugEnabled()) { logger.debug("Cancelling cookie for reason: " + reasonForLog); } @@ -284,20 +234,17 @@ public class TokenBasedRememberMeServices implements RememberMeServices, return userDetailsService; } - public void loginFail(HttpServletRequest request, - HttpServletResponse response) { - cancelCookie(request, response, - "Interactive authentication attempt was unsuccessful"); + public void loginFail(HttpServletRequest request, HttpServletResponse response) { + cancelCookie(request, response, "Interactive authentication attempt was unsuccessful"); } - public void loginSuccess(HttpServletRequest request, - HttpServletResponse response, Authentication successfulAuthentication) { + public void loginSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication successfulAuthentication) { // Exit if the principal hasn't asked to be remembered if (!RequestUtils.getBooleanParameter(request, parameter, false)) { if (logger.isDebugEnabled()) { - logger.debug( - "Did not send remember-me cookie (principal did not set parameter '" - + this.parameter + "')"); + logger.debug("Did not send remember-me cookie (principal did not set parameter '" + this.parameter + + "')"); } return; @@ -311,10 +258,8 @@ public class TokenBasedRememberMeServices implements RememberMeServices, String password; if (successfulAuthentication.getPrincipal() instanceof UserDetails) { - username = ((UserDetails) successfulAuthentication.getPrincipal()) - .getUsername(); - password = ((UserDetails) successfulAuthentication.getPrincipal()) - .getPassword(); + username = ((UserDetails) successfulAuthentication.getPrincipal()).getUsername(); + password = ((UserDetails) successfulAuthentication.getPrincipal()).getPassword(); } else { username = successfulAuthentication.getPrincipal().toString(); password = successfulAuthentication.getCredentials().toString(); @@ -323,53 +268,42 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Assert.hasLength(username); Assert.hasLength(password); - long expiryTime = System.currentTimeMillis() - + (tokenValiditySeconds * 1000); + long expiryTime = System.currentTimeMillis() + (tokenValiditySeconds * 1000); // construct token to put in cookie; format is: // username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key) - String signatureValue = new String(DigestUtils.md5Hex(username + ":" - + expiryTime + ":" + password + ":" + key)); + String signatureValue = new String(DigestUtils.md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)); String tokenValue = username + ":" + expiryTime + ":" + signatureValue; - String tokenValueBase64 = new String(Base64.encodeBase64( - tokenValue.getBytes())); + String tokenValueBase64 = new String(Base64.encodeBase64(tokenValue.getBytes())); response.addCookie(makeValidCookie(expiryTime, tokenValueBase64, request)); if (logger.isDebugEnabled()) { - logger.debug("Added remember-me cookie for user '" + username - + "', expiry: '" + new Date(expiryTime) + "'"); + logger.debug("Added remember-me cookie for user '" + username + "', expiry: '" + new Date(expiryTime) + "'"); } } - public void logout(HttpServletRequest request, - HttpServletResponse response, Authentication authentication) { - cancelCookie(request, response, - "Logout of user " + authentication.getName()); + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + cancelCookie(request, response, "Logout of user " + authentication.getName()); } protected Cookie makeCancelCookie(HttpServletRequest request) { - Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - null); + Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, null); cookie.setMaxAge(0); cookie.setPath(request.getContextPath()); return cookie; } - protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, - HttpServletRequest request) { - Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - tokenValueBase64); + protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, HttpServletRequest request) { + Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, tokenValueBase64); cookie.setMaxAge(60 * 60 * 24 * 365 * 5); // 5 years cookie.setPath(request.getContextPath()); return cookie; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } diff --git a/core/src/main/java/org/acegisecurity/ui/savedrequest/Enumerator.java b/core/src/main/java/org/acegisecurity/ui/savedrequest/Enumerator.java index bf88c49c9d..65ef181647 100644 --- a/core/src/main/java/org/acegisecurity/ui/savedrequest/Enumerator.java +++ b/core/src/main/java/org/acegisecurity/ui/savedrequest/Enumerator.java @@ -25,35 +25,23 @@ import java.util.NoSuchElementException; /** - *

- * Adapter that wraps an Enumeration around a Java 2 collection - * Iterator. - *

- * - *

- * Constructors are provided to easily create such wrappers. - *

- * - *

- * This class is based on code in Apache Tomcat. - *

+ *

Adapter that wraps an Enumeration around a Java 2 collection Iterator.

+ *

Constructors are provided to easily create such wrappers.

+ *

This class is based on code in Apache Tomcat.

* * @author Craig McClanahan * @author Andrey Grebnev * @version $Id$ */ public class Enumerator implements Enumeration { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - /** - * The Iterator over which the Enumeration - * represented by this class actually operates. - */ + /** The Iterator over which the Enumeration represented by this class actually operates. */ private Iterator iterator = null; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Return an Enumeration over the values of the specified Collection. * * @param collection Collection whose values should be enumerated @@ -62,7 +50,7 @@ public class Enumerator implements Enumeration { this(collection.iterator()); } - /** +/** * Return an Enumeration over the values of the specified Collection. * * @param collection Collection whose values should be enumerated @@ -72,7 +60,7 @@ public class Enumerator implements Enumeration { this(collection.iterator(), clone); } - /** +/** * Return an Enumeration over the values returned by the specified * Iterator. * @@ -83,7 +71,7 @@ public class Enumerator implements Enumeration { this.iterator = iterator; } - /** +/** * Return an Enumeration over the values returned by the specified * Iterator. * @@ -106,7 +94,7 @@ public class Enumerator implements Enumeration { } } - /** +/** * Return an Enumeration over the values of the specified Map. * * @param map Map whose values should be enumerated @@ -115,7 +103,7 @@ public class Enumerator implements Enumeration { this(map.values().iterator()); } - /** +/** * Return an Enumeration over the values of the specified Map. * * @param map Map whose values should be enumerated @@ -125,13 +113,12 @@ public class Enumerator implements Enumeration { this(map.values().iterator(), clone); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Tests if this enumeration contains more elements. * - * @return true if and only if this enumeration object - * contains at least one more element to provide, + * @return true if and only if this enumeration object contains at least one more element to provide, * false otherwise */ public boolean hasMoreElements() { @@ -139,8 +126,8 @@ public class Enumerator implements Enumeration { } /** - * Returns the next element of this enumeration if this enumeration has at - * least one more element to provide. + * Returns the next element of this enumeration if this enumeration has at least one more element to + * provide. * * @return the next element of this enumeration * diff --git a/core/src/main/java/org/acegisecurity/ui/savedrequest/FastHttpDateFormat.java b/core/src/main/java/org/acegisecurity/ui/savedrequest/FastHttpDateFormat.java index 4c0cac39f7..954420de27 100644 --- a/core/src/main/java/org/acegisecurity/ui/savedrequest/FastHttpDateFormat.java +++ b/core/src/main/java/org/acegisecurity/ui/savedrequest/FastHttpDateFormat.java @@ -26,33 +26,25 @@ import java.util.TimeZone; /** - *

- * Utility class to generate HTTP dates. - *

- * - *

- * This class is based on code in Apache Tomcat. - *

+ *

Utility class to generate HTTP dates.

+ *

This class is based on code in Apache Tomcat.

* * @author Remy Maucherat * @author Andrey Grebnev * @version $Id$ */ public class FastHttpDateFormat { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== /** HTTP date format. */ - protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", - Locale.US); + protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); - /** - * The set of SimpleDateFormat formats to use in - * getDateHeader(). - */ - protected static final SimpleDateFormat[] formats = {new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", - Locale.US), new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", - Locale.US), new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", - Locale.US)}; + /** The set of SimpleDateFormat formats to use in getDateHeader(). */ + protected static final SimpleDateFormat[] formats = { + new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), + new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), + new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) + }; /** GMT timezone - all HTTP dates are on GMT */ protected final static TimeZone gmtZone = TimeZone.getTimeZone("GMT"); @@ -77,20 +69,17 @@ public class FastHttpDateFormat { /** Parser cache. */ protected static final HashMap parseCache = new HashMap(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Formats a specified date to HTTP format. If local format is not - * null, it's used instead. + * Formats a specified date to HTTP format. If local format is not null, it's used instead. * * @param value Date value to format - * @param threadLocalformat The format to use (or null -- then - * HTTP format will be used) + * @param threadLocalformat The format to use (or null -- then HTTP format will be used) * * @return Formatted date */ - public static final String formatDate(long value, - DateFormat threadLocalformat) { + public static final String formatDate(long value, DateFormat threadLocalformat) { String cachedDate = null; Long longValue = new Long(value); @@ -149,8 +138,7 @@ public class FastHttpDateFormat { * * @return Parsed date (or null if no formatter mached) */ - private static final Long internalParseDate(String value, - DateFormat[] formats) { + private static final Long internalParseDate(String value, DateFormat[] formats) { Date date = null; for (int i = 0; (date == null) && (i < formats.length); i++) { @@ -169,17 +157,15 @@ public class FastHttpDateFormat { } /** - * Tries to parse the given date as an HTTP date. If local format list is - * not null, it's used instead. + * Tries to parse the given date as an HTTP date. If local format list is not null, it's used + * instead. * * @param value The string to parse - * @param threadLocalformats Array of formats to use for parsing. If - * null, HTTP formats are used. + * @param threadLocalformats Array of formats to use for parsing. If null, HTTP formats are used. * * @return Parsed date (or -1 if error occured) */ - public static final long parseDate(String value, - DateFormat[] threadLocalformats) { + public static final long parseDate(String value, DateFormat[] threadLocalformats) { Long cachedDate = null; try { @@ -219,8 +205,7 @@ public class FastHttpDateFormat { * @param key Key to be updated * @param value New value */ - private static final void updateCache(HashMap cache, Object key, - Object value) { + private static final void updateCache(HashMap cache, Object key, Object value) { if (value == null) { return; } diff --git a/core/src/main/java/org/acegisecurity/ui/savedrequest/SavedRequest.java b/core/src/main/java/org/acegisecurity/ui/savedrequest/SavedRequest.java index 38a134f6f9..57034d9186 100644 --- a/core/src/main/java/org/acegisecurity/ui/savedrequest/SavedRequest.java +++ b/core/src/main/java/org/acegisecurity/ui/savedrequest/SavedRequest.java @@ -36,25 +36,13 @@ import javax.servlet.http.HttpServletRequest; /** - * Represents central information from a HttpServletRequest. - * - *

- * This class is used by {@link org.acegisecurity.ui.AbstractProcessingFilter} - * and {@link org.acegisecurity.wrapper.SavedRequestAwareWrapper} to reproduce - * the request after successful authentication. An instance of this class is - * stored at the time of an authentication exception by {@link - * org.acegisecurity.ui.ExceptionTranslationFilter}. - *

- * - *

- * IMPLEMENTATION NOTE: It is assumed that this object is accessed - * only from the context of a single thread, so no synchronization around - * internal collection classes is performed. - *

- * - *

- * This class is based on code in Apache Tomcat. - *

+ * Represents central information from a HttpServletRequest.

This class is used by {@link + * org.acegisecurity.ui.AbstractProcessingFilter} and {@link org.acegisecurity.wrapper.SavedRequestAwareWrapper} to + * reproduce the request after successful authentication. An instance of this class is stored at the time of an + * authentication exception by {@link org.acegisecurity.ui.ExceptionTranslationFilter}.

+ *

IMPLEMENTATION NOTE: It is assumed that this object is accessed only from the context of a single + * thread, so no synchronization around internal collection classes is performed.

+ *

This class is based on code in Apache Tomcat.

* * @author Craig McClanahan * @author Andrey Grebnev @@ -62,11 +50,11 @@ import javax.servlet.http.HttpServletRequest; * @version $Id$ */ public class SavedRequest implements java.io.Serializable { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(SavedRequest.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ArrayList cookies = new ArrayList(); private ArrayList locales = new ArrayList(); @@ -83,7 +71,7 @@ public class SavedRequest implements java.io.Serializable { private String servletPath; private int serverPort; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SavedRequest(HttpServletRequest request, PortResolver portResolver) { Assert.notNull(request, "Request required"); @@ -142,7 +130,7 @@ public class SavedRequest implements java.io.Serializable { this.servletPath = request.getServletPath(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private void addCookie(Cookie cookie) { cookies.add(cookie); @@ -168,17 +156,15 @@ public class SavedRequest implements java.io.Serializable { } /** - * Determines if the current request matches the SavedRequest. - * All URL arguments are considered, but not method (POST/GET), - * cookies, locales, headers or parameters. + * Determines if the current request matches the SavedRequest. All URL arguments are + * considered, but not method (POST/GET), cookies, locales, headers or parameters. * * @param request DOCUMENT ME! * @param portResolver DOCUMENT ME! * * @return DOCUMENT ME! */ - public boolean doesRequestMatch(HttpServletRequest request, - PortResolver portResolver) { + public boolean doesRequestMatch(HttpServletRequest request, PortResolver portResolver) { Assert.notNull(request, "Request required"); Assert.notNull(portResolver, "PortResolver required"); @@ -186,23 +172,19 @@ public class SavedRequest implements java.io.Serializable { return false; } - if (!propertyEquals("queryString", this.queryString, - request.getQueryString())) { + if (!propertyEquals("queryString", this.queryString, request.getQueryString())) { return false; } - if (!propertyEquals("requestURI", this.requestURI, - request.getRequestURI())) { + if (!propertyEquals("requestURI", this.requestURI, request.getRequestURI())) { return false; } - if (!propertyEquals("serverPort", new Integer(this.serverPort), - new Integer(portResolver.getServerPort(request)))) { + if (!propertyEquals("serverPort", new Integer(this.serverPort), new Integer(portResolver.getServerPort(request)))) { return false; } - if (!propertyEquals("requestURL", this.requestURL, - request.getRequestURL().toString())) { + if (!propertyEquals("requestURL", this.requestURL, request.getRequestURL().toString())) { return false; } @@ -210,18 +192,15 @@ public class SavedRequest implements java.io.Serializable { return false; } - if (!propertyEquals("serverName", this.serverName, - request.getServerName())) { + if (!propertyEquals("serverName", this.serverName, request.getServerName())) { return false; } - if (!propertyEquals("contextPath", this.contextPath, - request.getContextPath())) { + if (!propertyEquals("contextPath", this.contextPath, request.getContextPath())) { return false; } - if (!propertyEquals("servletPath", this.servletPath, - request.getServletPath())) { + if (!propertyEquals("servletPath", this.servletPath, request.getServletPath())) { return false; } @@ -329,11 +308,9 @@ public class SavedRequest implements java.io.Serializable { return true; } - if (((arg1 == null) && (arg2 != null)) - || ((arg1 != null) && (arg2 == null))) { + if (((arg1 == null) && (arg2 != null)) || ((arg1 != null) && (arg2 == null))) { if (logger.isDebugEnabled()) { - logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 - + " (property not equals)"); + logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)"); } return false; @@ -341,15 +318,13 @@ public class SavedRequest implements java.io.Serializable { if (arg1.equals(arg2)) { if (logger.isDebugEnabled()) { - logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 - + " (property equals)"); + logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property equals)"); } return true; } else { if (logger.isDebugEnabled()) { - logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 - + " (property not equals)"); + logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)"); } return false; diff --git a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionApplicationEvent.java b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionApplicationEvent.java index e0d1fae2cb..a4b7edfdf8 100644 --- a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionApplicationEvent.java +++ b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionApplicationEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,9 @@ import javax.servlet.http.HttpSession; * @author Ray Krueger */ public abstract class HttpSessionApplicationEvent extends ApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Base constructor for all subclasses must have an HttpSession * * @param httpSession The session to carry as the event source. @@ -37,7 +37,7 @@ public abstract class HttpSessionApplicationEvent extends ApplicationEvent { super(httpSession); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Get the HttpSession that is the cause of the event diff --git a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionCreatedEvent.java b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionCreatedEvent.java index 788631a15d..86e76cb912 100644 --- a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionCreatedEvent.java +++ b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionCreatedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,12 @@ import javax.servlet.http.HttpSession; /** - * Published by the {@link HttpSessionEventPublisher} when a HttpSession is - * destroyed by the container + * Published by the {@link HttpSessionEventPublisher} when a HttpSession is destroyed by the container * * @author Ray Krueger */ public class HttpSessionCreatedEvent extends HttpSessionApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public HttpSessionCreatedEvent(HttpSession o) { super(o); diff --git a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionDestroyedEvent.java b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionDestroyedEvent.java index 36e199bff1..c1ddff339c 100644 --- a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionDestroyedEvent.java +++ b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionDestroyedEvent.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,12 @@ import javax.servlet.http.HttpSession; /** - * Published by the {@link HttpSessionEventPublisher} when a HttpSession is - * created in the container + * Published by the {@link HttpSessionEventPublisher} when a HttpSession is created in the container * * @author Ray Krueger */ public class HttpSessionDestroyedEvent extends HttpSessionApplicationEvent { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public HttpSessionDestroyedEvent(HttpSession o) { super(o); diff --git a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java index 4970ed0741..3e9b89660b 100644 --- a/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java +++ b/core/src/main/java/org/acegisecurity/ui/session/HttpSessionEventPublisher.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,41 +22,33 @@ import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** - * Declared in web.xml as
- *
- * <listener>
- * <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
- * </listener>
- * 
- * Publishes HttpSessionApplicationEvents to the Spring - * Root WebApplicationContext. - * Maps javax.servlet.http.HttpSessionListener.sessionCreated() to {@link - * HttpSessionCreatedEvent}. - * Maps javax.servlet.http.HttpSessionListener.sessionDestroyed() to {@link - * HttpSessionDestroyedEvent}. + * Declared in web.xml as
<listener>
+ * <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class></listener>
+ * 
Publishes HttpSessionApplicationEvents to the Spring Root WebApplicationContext. Maps + * javax.servlet.http.HttpSessionListener.sessionCreated() to {@link HttpSessionCreatedEvent}. Maps + * javax.servlet.http.HttpSessionListener.sessionDestroyed() to {@link HttpSessionDestroyedEvent}. * * @author Ray Krueger */ -public class HttpSessionEventPublisher implements HttpSessionListener, - ServletContextListener { - //~ Static fields/initializers ============================================= +public class HttpSessionEventPublisher implements HttpSessionListener, ServletContextListener { + //~ Static fields/initializers ===================================================================================== private static final Log log = LogFactory.getLog(HttpSessionEventPublisher.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext appContext; private ServletContext servletContext = null; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Not implemented @@ -69,58 +61,59 @@ public class HttpSessionEventPublisher implements HttpSessionListener, * Handled internally by a call to {@link * org.springframework.web.appContext.support.WebApplicationContextUtils#getRequiredWebApplicationContext(javax.servlet.ServletContext)} * - * @param event the ServletContextEvent passed in by the container, - * event.getServletContext() will be used to get the - * WebApplicationContext + * @param event the ServletContextEvent passed in by the container, event.getServletContext() will be used to get + * the WebApplicationContext */ public void contextInitialized(ServletContextEvent event) { - log.debug("Received ServletContextEvent: " + event); + if (log.isDebugEnabled()) { + log.debug("Received ServletContextEvent: " + event); + } - appContext = WebApplicationContextUtils.getWebApplicationContext( - event.getServletContext()); + appContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); - if(appContext == null) { + if (appContext == null) { log.warn("Web application context is null. Will delay initialization until it's first used."); servletContext = event.getServletContext(); } - - } - - /** - * Handles the HttpSessionEvent by publishing a {@link - * HttpSessionCreatedEvent} to the application appContext. - * - * @param event HttpSessionEvent passed in by the container - */ - public void sessionCreated(HttpSessionEvent event) { - HttpSessionCreatedEvent e = new HttpSessionCreatedEvent(event - .getSession()); - - log.debug("Publishing event: " + e); - - getContext().publishEvent(e); - } - - /** - * Handles the HttpSessionEvent by publishing a {@link - * HttpSessionDestroyedEvent} to the application appContext. - * - * @param event The HttpSessionEvent pass in by the container - */ - public void sessionDestroyed(HttpSessionEvent event) { - HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event - .getSession()); - - log.debug("Publishing event: " + e); - - getContext().publishEvent(e); } ApplicationContext getContext() { - if(appContext == null) { + if (appContext == null) { appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); } return appContext; } + + /** + * Handles the HttpSessionEvent by publishing a {@link HttpSessionCreatedEvent} to the application + * appContext. + * + * @param event HttpSessionEvent passed in by the container + */ + public void sessionCreated(HttpSessionEvent event) { + HttpSessionCreatedEvent e = new HttpSessionCreatedEvent(event.getSession()); + + if (log.isDebugEnabled()) { + log.debug("Publishing event: " + e); + } + + getContext().publishEvent(e); + } + + /** + * Handles the HttpSessionEvent by publishing a {@link HttpSessionDestroyedEvent} to the application + * appContext. + * + * @param event The HttpSessionEvent pass in by the container + */ + public void sessionDestroyed(HttpSessionEvent event) { + HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession()); + + if (log.isDebugEnabled()) { + log.debug("Publishing event: " + e); + } + + getContext().publishEvent(e); + } } diff --git a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserGrantedAuthority.java b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserGrantedAuthority.java index 472e18ac23..ce658b0179 100644 --- a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserGrantedAuthority.java +++ b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserGrantedAuthority.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +20,8 @@ import org.acegisecurity.GrantedAuthorityImpl; /** - * Custom GrantedAuthority used by {@link - * org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter} - * - *

- * Stores the Authentication object of the original user to be - * used later when 'exiting' from a user switch. - *

+ * Custom GrantedAuthority used by {@link org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter}

Stores + * the Authentication object of the original user to be used later when 'exiting' from a user switch.

* * @author Mark St.Godard * @version $Id$ @@ -34,24 +29,23 @@ import org.acegisecurity.GrantedAuthorityImpl; * @see org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter */ public class SwitchUserGrantedAuthority extends GrantedAuthorityImpl { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authentication source; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SwitchUserGrantedAuthority(String role, Authentication source) { super(role); this.source = source; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Returns the original user associated with a successful user switch. * - * @return The original Authentication object of the switched - * user. + * @return The original Authentication object of the switched user. */ public Authentication getSource() { return source; diff --git a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java index ba58fc9ea1..10b0439e3d 100644 --- a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java @@ -69,60 +69,36 @@ import javax.servlet.http.HttpServletResponse; /** - * Switch User processing filter responsible for user context switching. - * - *

- * This filter is similar to Unix 'su' however for Acegi-managed web - * applications. A common use-case for this feature is the ability to allow - * higher-authority users (i.e. ROLE_ADMIN) to switch to a regular user (i.e. - * ROLE_USER). - *

- * - *

- * This filter assumes that the user performing the switch will be required to - * be logged in as normal (i.e. ROLE_ADMIN user). The user will then access a - * page/controller that enables the administrator to specify who they wish to - * become (see switchUserUrl).
- * Note: This URL will be required to have to appropriate security - * contraints configured so that only users of that role can access (i.e. - * ROLE_ADMIN). - *

- * - *

- * On successful switch, the user's SecurityContextHolder will be - * updated to reflect the specified user and will also contain an additinal - * {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority } which - * contains the original user. - *

- * - *

- * To 'exit' from a user context, the user will then need to access a URL (see - * exitUserUrl) that will switch back to the original user as - * identified by the SWITCH_USER_GRANTED_AUTHORITY. - *

- * - *

- * To configure the Switch User Processing Filter, create a bean definition for - * the Switch User processing filter and add to the filterChainProxy.
- * Example: - *

+ * Switch User processing filter responsible for user context switching.

This filter is similar to Unix 'su' + * however for Acegi-managed web applications. A common use-case for this feature is the ability to allow + * higher-authority users (i.e. ROLE_ADMIN) to switch to a regular user (i.e. ROLE_USER).

+ *

This filter assumes that the user performing the switch will be required to be logged in as normal (i.e. + * ROLE_ADMIN user). The user will then access a page/controller that enables the administrator to specify who they + * wish to become (see switchUserUrl).
+ * Note: This URL will be required to have to appropriate security contraints configured so that only users of that + * role can access (i.e. ROLE_ADMIN).

+ *

On successful switch, the user's SecurityContextHolder will be updated to reflect the + * specified user and will also contain an additinal {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority + * } which contains the original user.

+ *

To 'exit' from a user context, the user will then need to access a URL (see exitUserUrl) that + * will switch back to the original user as identified by the SWITCH_USER_GRANTED_AUTHORITY.

+ *

To configure the Switch User Processing Filter, create a bean definition for the Switch User processing + * filter and add to the filterChainProxy.
+ * Example:

  * <bean id="switchUserProcessingFilter" class="org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter">
  *    <property name="authenticationDao" ref="jdbcDaoImpl" />
  *    <property name="switchUserUrl"><value>/j_acegi_switch_user</value></property>
  *    <property name="exitUserUrl"><value>/j_acegi_exit_user</value></property>
- *    <property name="targetUrl"><value>/index.jsp</value></property>
- * </bean>
- * 
- *

+ * <property name="targetUrl"><value>/index.jsp</value></property></bean>

* * @author Mark St.Godard * @version $Id$ * * @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority */ -public class SwitchUserProcessingFilter implements Filter, InitializingBean, - ApplicationEventPublisherAware, MessageSourceAware { - //~ Static fields/initializers ============================================= +public class SwitchUserProcessingFilter implements Filter, InitializingBean, ApplicationEventPublisherAware, + MessageSourceAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class); @@ -131,7 +107,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, public static final String ACEGI_SECURITY_SWITCH_USERNAME_KEY = "j_username"; public static final String ROLE_PREVIOUS_ADMINISTRATOR = "ROLE_PREVIOUS_ADMINISTRATOR"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationEventPublisher eventPublisher; private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); @@ -144,7 +120,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, // ======================================================== private UserDetailsService userDetailsService; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(switchUserUrl, "switchUserUrl must be specified"); @@ -159,22 +135,19 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, * * @param request The http servlet request * - * @return The original Authentication object or - * null otherwise. + * @return The original Authentication object or null otherwise. * - * @throws AuthenticationCredentialsNotFoundException If no - * Authentication associated with this request. + * @throws AuthenticationCredentialsNotFoundException If no Authentication associated with this + * request. */ protected Authentication attemptExitUser(HttpServletRequest request) throws AuthenticationCredentialsNotFoundException { // need to check to see if the current user has a SwitchUserGrantedAuthority - Authentication current = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication current = SecurityContextHolder.getContext().getAuthentication(); if (null == current) { - throw new AuthenticationCredentialsNotFoundException(messages - .getMessage("SwitchUserProcessingFilter.noCurrentUser", - "No current user associated with this request")); + throw new AuthenticationCredentialsNotFoundException(messages.getMessage( + "SwitchUserProcessingFilter.noCurrentUser", "No current user associated with this request")); } // check to see if the current user did actual switch to another user @@ -183,8 +156,8 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, if (original == null) { logger.error("Could not find original user Authentication object!"); - throw new AuthenticationCredentialsNotFoundException(messages - .getMessage("SwitchUserProcessingFilter.noOriginalAuthentication", + throw new AuthenticationCredentialsNotFoundException(messages.getMessage( + "SwitchUserProcessingFilter.noOriginalAuthentication", "Could not find original Authentication object")); } @@ -198,29 +171,26 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, // publish event if (this.eventPublisher != null) { - eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( - current, originalUser)); + eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(current, originalUser)); } return original; } /** - * Attempt to switch to another user. If the user does not exist or is not - * active, return null. + * Attempt to switch to another user. If the user does not exist or is not active, return null. * * @param request The http request * - * @return The new Authentication request if successfully - * switched to another user, null otherwise. + * @return The new Authentication request if successfully switched to another user, null + * otherwise. * * @throws AuthenticationException * @throws UsernameNotFoundException If the target user is not found. * @throws LockedException DOCUMENT ME! * @throws DisabledException If the target user is disabled. * @throws AccountExpiredException If the target user account is expired. - * @throws CredentialsExpiredException If the target user credentials are - * expired. + * @throws CredentialsExpiredException If the target user credentials are expired. */ protected Authentication attemptSwitchUser(HttpServletRequest request) throws AuthenticationException { @@ -241,35 +211,29 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, // user not found if (targetUser == null) { - throw new UsernameNotFoundException(messages.getMessage( - "SwitchUserProcessingFilter.usernameNotFound", + throw new UsernameNotFoundException(messages.getMessage("SwitchUserProcessingFilter.usernameNotFound", new Object[] {username}, "Username {0} not found")); } // account is expired if (!targetUser.isAccountNonLocked()) { - throw new LockedException(messages.getMessage( - "SwitchUserProcessingFilter.locked", - "User account is locked")); + throw new LockedException(messages.getMessage("SwitchUserProcessingFilter.locked", "User account is locked")); } // user is disabled if (!targetUser.isEnabled()) { - throw new DisabledException(messages.getMessage( - "SwitchUserProcessingFilter.disabled", "User is disabled")); + throw new DisabledException(messages.getMessage("SwitchUserProcessingFilter.disabled", "User is disabled")); } // account is expired if (!targetUser.isAccountNonExpired()) { - throw new AccountExpiredException(messages.getMessage( - "SwitchUserProcessingFilter.expired", + throw new AccountExpiredException(messages.getMessage("SwitchUserProcessingFilter.expired", "User account has expired")); } // credentials expired if (!targetUser.isCredentialsNonExpired()) { - throw new CredentialsExpiredException(messages.getMessage( - "SwitchUserProcessingFilter.credentialsExpired", + throw new CredentialsExpiredException(messages.getMessage("SwitchUserProcessingFilter.credentialsExpired", "User credentials have expired")); } @@ -283,17 +247,15 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, // publish event if (this.eventPublisher != null) { eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( - SecurityContextHolder.getContext().getAuthentication(), - targetUser)); + SecurityContextHolder.getContext().getAuthentication(), targetUser)); } return targetUserRequest; } /** - * Create a switch user token that contains an additional - * GrantedAuthority that contains the original - * Authentication object. + * Create a switch user token that contains an additional GrantedAuthority that contains the + * original Authentication object. * * @param request The http servlet request. * @param username The username of target user @@ -303,16 +265,14 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, * * @see SwitchUserGrantedAuthority */ - private UsernamePasswordAuthenticationToken createSwitchUserToken( - HttpServletRequest request, String username, UserDetails targetUser) { + private UsernamePasswordAuthenticationToken createSwitchUserToken(HttpServletRequest request, String username, + UserDetails targetUser) { UsernamePasswordAuthenticationToken targetUserRequest; // grant an additional authority that contains the original Authentication object // which will be used to 'exit' from the current switched user. - Authentication currentAuth = SecurityContextHolder.getContext() - .getAuthentication(); - GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR, - currentAuth); + Authentication currentAuth = SecurityContextHolder.getContext().getAuthentication(); + GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR, currentAuth); // get the original authorities List orig = Arrays.asList(targetUser.getAuthorities()); @@ -325,12 +285,10 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, authorities = (GrantedAuthority[]) newAuths.toArray(authorities); // create the new authentication token - targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser, - targetUser.getPassword(), authorities); + targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser, targetUser.getPassword(), authorities); // set details - targetUserRequest.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + targetUserRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); return targetUserRequest; } @@ -338,10 +296,11 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, public void destroy() {} /** + * * @see javax.servlet.Filter#doFilter */ - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { Assert.isInstanceOf(HttpServletRequest.class, request); Assert.isInstanceOf(HttpServletResponse.class, response); @@ -357,8 +316,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, SecurityContextHolder.getContext().setAuthentication(targetUser); // redirect to target url - httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest - .getContextPath() + targetUrl)); + httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest.getContextPath() + targetUrl)); return; } else if (requiresExitUser(httpRequest)) { @@ -369,8 +327,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, SecurityContextHolder.getContext().setAuthentication(originalUser); // redirect to target url - httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest - .getContextPath() + targetUrl)); + httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest.getContextPath() + targetUrl)); return; } @@ -379,15 +336,13 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, } /** - * Find the original Authentication object from the current - * user's granted authorities. A successfully switched user should have a - * SwitchUserGrantedAuthority that contains the original + * Find the original Authentication object from the current user's granted authorities. A + * successfully switched user should have a SwitchUserGrantedAuthority that contains the original * source user Authentication object. * * @param current The current Authentication object * - * @return The source user Authentication object or - * null otherwise. + * @return The source user Authentication object or null otherwise. */ private Authentication getSourceAuthentication(Authentication current) { Authentication original = null; @@ -398,10 +353,8 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, for (int i = 0; i < authorities.length; i++) { // check for switch user type of authority if (authorities[i] instanceof SwitchUserGrantedAuthority) { - original = ((SwitchUserGrantedAuthority) authorities[i]) - .getSource(); - logger.debug("Found original switch user granted authority [" - + original + "]"); + original = ((SwitchUserGrantedAuthority) authorities[i]).getSource(); + logger.debug("Found original switch user granted authority [" + original + "]"); } } @@ -415,8 +368,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, * * @param request The http servlet request * - * @return true if the request requires a exit user, - * false otherwise. + * @return true if the request requires a exit user, false otherwise. * * @see SwitchUserProcessingFilter#exitUserUrl */ @@ -431,8 +383,7 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, * * @param request The http servlet request * - * @return true if the request requires a switch, - * false otherwise. + * @return true if the request requires a switch, false otherwise. * * @see SwitchUserProcessingFilter#switchUserUrl */ @@ -442,15 +393,13 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, return uri.endsWith(request.getContextPath() + switchUserUrl); } - public void setApplicationEventPublisher( - ApplicationEventPublisher eventPublisher) throws BeansException { + public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) + throws BeansException { this.eventPublisher = eventPublisher; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java index e6f1e2d655..05c17a9ed7 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java @@ -28,33 +28,24 @@ import javax.servlet.http.HttpServletRequest; /** - * Processes an authentication form. - * - *

- * Login forms must present two parameters to this filter: a username and - * password. The parameter names to use are contained in the static fields - * {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} and {@link - * #ACEGI_SECURITY_FORM_PASSWORD_KEY}. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Processes an authentication form.

Login forms must present two parameters to this filter: a username and + * password. The parameter names to use are contained in the static fields {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} + * and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Ben Alex * @author Colin Sampaleanu * @version $Id$ */ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "j_username"; public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password"; public static final String ACEGI_SECURITY_LAST_USERNAME_KEY = "ACEGI_SECURITY_LAST_USERNAME"; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { @@ -69,12 +60,10 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { password = ""; } - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, - password); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Place the last username attempted into HttpSession for views - request.getSession() - .setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); + request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); // Allow subclasses to set the "details" property setDetails(request, authRequest); @@ -94,21 +83,14 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { public void init(FilterConfig filterConfig) throws ServletException {} /** - * Enables subclasses to override the composition of the password, such as - * by including additional values and a separator. - * - *

- * This might be used for example if a postcode/zipcode was required in - * addition to the password. A delimiter such as a pipe (|) should be used - * to separate the password and extended value(s). The - * AuthenticationDao will need to generate the expected - * password in a corresponding manner. - *

+ * Enables subclasses to override the composition of the password, such as by including additional values + * and a separator.

This might be used for example if a postcode/zipcode was required in addition to the + * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The + * AuthenticationDao will need to generate the expected password in a corresponding manner.

* * @param request so that request attributes can be retrieved * - * @return the password that will be presented in the - * Authentication request token to the + * @return the password that will be presented in the Authentication request token to the * AuthenticationManager */ protected String obtainPassword(HttpServletRequest request) { @@ -116,13 +98,12 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { } /** - * Enables subclasses to override the composition of the username, such as - * by including additional values and a separator. + * Enables subclasses to override the composition of the username, such as by including additional values + * and a separator. * * @param request so that request attributes can be retrieved * - * @return the username that will be presented in the - * Authentication request token to the + * @return the username that will be presented in the Authentication request token to the * AuthenticationManager */ protected String obtainUsername(HttpServletRequest request) { @@ -130,15 +111,13 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { } /** - * Provided so that subclasses may configure what is put into the - * authentication request's details property. + * Provided so that subclasses may configure what is put into the authentication request's details + * property. * * @param request that an authentication request is being created for - * @param authRequest the authentication request object that should have - * its details set + * @param authRequest the authentication request object that should have its details set */ - protected void setDetails(HttpServletRequest request, - UsernamePasswordAuthenticationToken authRequest) { + protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); } } diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java index 286ba748f1..cdf8e79503 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java @@ -41,42 +41,33 @@ import javax.servlet.http.HttpServletResponse; /** - *

- * Used by the SecurityEnforcementFilter to commence - * authentication via the {@link AuthenticationProcessingFilter}. This object - * holds the location of the login form, relative to the web app context path, - * and is used to commence a redirect to that form. - *

- * - *

- * By setting the forceHttps property to true, you may configure the - * class to force the protocol used for the login form to be - * HTTPS, even if the original intercepted request for a resource - * used the HTTP protocol. When this happens, after a successful - * login (via HTTPS), the original resource will still be accessed as HTTP, - * via the original request URL. For the forced HTTPS feature to work, the - * {@link PortMapper} is consulted to determine the HTTP:HTTPS pairs. - *

+ *

Used by the SecurityEnforcementFilter to commence authentication via the {@link + * AuthenticationProcessingFilter}. This object holds the location of the login form, relative to the web app context + * path, and is used to commence a redirect to that form.

+ *

By setting the forceHttps property to true, you may configure the class to force the protocol used + * for the login form to be HTTPS, even if the original intercepted request for a resource used the + * HTTP protocol. When this happens, after a successful login (via HTTPS), the original resource will + * still be accessed as HTTP, via the original request URL. For the forced HTTPS feature to work, the {@link + * PortMapper} is consulted to determine the HTTP:HTTPS pairs.

* * @author Ben Alex * @author colin sampaleanu * @author Omri Spector * @version $Id$ */ -public class AuthenticationProcessingFilterEntryPoint - implements AuthenticationEntryPoint, InitializingBean { - //~ Static fields/initializers ============================================= +public class AuthenticationProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private PortMapper portMapper = new PortMapperImpl(); private PortResolver portResolver = new PortResolverImpl(); private String loginFormUrl; private boolean forceHttps = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.hasLength(loginFormUrl, "loginFormUrl must be specified"); @@ -84,8 +75,7 @@ public class AuthenticationProcessingFilterEntryPoint Assert.notNull(portResolver, "portResolver must be specified"); } - public void commence(ServletRequest request, ServletResponse response, - AuthenticationException authException) + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String scheme = request.getScheme(); @@ -104,13 +94,11 @@ public class AuthenticationProcessingFilterEntryPoint includePort = false; } - String redirectUrl = scheme + "://" + serverName - + ((includePort) ? (":" + serverPort) : "") + contextPath + String redirectUrl = scheme + "://" + serverName + ((includePort) ? (":" + serverPort) : "") + contextPath + loginFormUrl; if (forceHttps && inHttp) { - Integer httpsPort = (Integer) portMapper.lookupHttpsPort(new Integer( - serverPort)); + Integer httpsPort = (Integer) portMapper.lookupHttpsPort(new Integer(serverPort)); if (httpsPort != null) { if (httpsPort.intValue() == 443) { @@ -119,8 +107,7 @@ public class AuthenticationProcessingFilterEntryPoint includePort = true; } - redirectUrl = "https://" + serverName - + ((includePort) ? (":" + httpsPort) : "") + contextPath + redirectUrl = "https://" + serverName + ((includePort) ? (":" + httpsPort) : "") + contextPath + loginFormUrl; } } @@ -129,8 +116,7 @@ public class AuthenticationProcessingFilterEntryPoint logger.debug("Redirecting to: " + redirectUrl); } - ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response) - .encodeRedirectURL(redirectUrl)); + ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response).encodeRedirectURL(redirectUrl)); } public boolean getForceHttps() { @@ -150,9 +136,8 @@ public class AuthenticationProcessingFilterEntryPoint } /** - * Set to true to force login form access to be via https. If this value is - * ture (the default is false), and the incoming request for the protected - * resource which triggered the interceptor was not already + * Set to true to force login form access to be via https. If this value is ture (the default is false), + * and the incoming request for the protected resource which triggered the interceptor was not already * https, then * * @param forceHttps @@ -162,9 +147,8 @@ public class AuthenticationProcessingFilterEntryPoint } /** - * The URL where the AuthenticationProcessingFilter login page - * can be found. Should be relative to the web-app context path, and - * include a leading / + * The URL where the AuthenticationProcessingFilter login page can be found. Should be + * relative to the web-app context path, and include a leading / * * @param loginFormUrl */ diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java index 6a79920df7..2f3ce4573f 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,57 +15,42 @@ package org.acegisecurity.ui.webapp; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.context.HttpSessionContextIntegrationFilter; import org.acegisecurity.context.SecurityContext; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + /** - * Extends Acegi's AuthenticationProcessingFilter to pick up CA/Netegrity - * Siteminder headers. - * - *

- * Also provides a backup form-based authentication and the ability set source - * key names. - *

- * - *

- * Siteminder must present two headers to this filter, a username - * and password. You must set the header keys before this filter is used for - * authentication, otherwise Siteminder checks will be skipped. If the - * Siteminder check is unsuccessful (i.e. if the headers are not found), then - * the form parameters will be checked (see next paragraph). This allows - * applications to optionally function even when their Siteminder - * infrastructure is unavailable, as is often the case during development. - *

- * - *

- * Login forms must present two parameters to this filter: a - * username and password. If not specified, the parameter names to use are - * contained in the static fields {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} - * and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}. - *

- * - *

- * Do not use this class directly. Instead, configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Extends Acegi's AuthenticationProcessingFilter to pick up CA/Netegrity Siteminder headers.

Also provides a + * backup form-based authentication and the ability set source key names.

+ *

Siteminder must present two headers to this filter, a username and password. You must set the + * header keys before this filter is used for authentication, otherwise Siteminder checks will be skipped. If the + * Siteminder check is unsuccessful (i.e. if the headers are not found), then the form parameters will be checked (see + * next paragraph). This allows applications to optionally function even when their Siteminder infrastructure is + * unavailable, as is often the case during development.

+ *

Login forms must present two parameters to this filter: a username and password. If not + * specified, the parameter names to use are contained in the static fields {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} + * and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}.

+ *

Do not use this class directly. Instead, configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

*/ -public class SiteminderAuthenticationProcessingFilter - extends AuthenticationProcessingFilter { - - //~ Instance fields ======================================================== - - /** Log instance for debugging */ - private static final Log logger = LogFactory.getLog(SiteminderAuthenticationProcessingFilter.class); +public class SiteminderAuthenticationProcessingFilter extends AuthenticationProcessingFilter { + //~ Static fields/initializers ===================================================================================== + + /** Log instance for debugging */ + private static final Log logger = LogFactory.getLog(SiteminderAuthenticationProcessingFilter.class); + + //~ Instance fields ================================================================================================ /** Form password request key. */ private String formPasswordParameterKey = null; @@ -79,18 +64,19 @@ public class SiteminderAuthenticationProcessingFilter /** Siteminder username header key. */ private String siteminderUsernameHeaderKey = null; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Basic constructor. */ public SiteminderAuthenticationProcessingFilter() { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** + * * @see org.acegisecurity.ui.AbstractProcessingFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest) */ public Authentication attemptAuthentication(HttpServletRequest request) @@ -99,25 +85,20 @@ public class SiteminderAuthenticationProcessingFilter String password = null; // Check the Siteminder headers for authentication info - if ((siteminderUsernameHeaderKey != null) - && (siteminderUsernameHeaderKey.length() > 0) - && (siteminderPasswordHeaderKey != null) - && (siteminderPasswordHeaderKey.length() > 0)) { + if ((siteminderUsernameHeaderKey != null) && (siteminderUsernameHeaderKey.length() > 0) + && (siteminderPasswordHeaderKey != null) && (siteminderPasswordHeaderKey.length() > 0)) { username = request.getHeader(siteminderUsernameHeaderKey); password = request.getHeader(siteminderPasswordHeaderKey); } // If the Siteminder authentication info wasn't available, then get it // from the form parameters - if ((username == null) || (username.length() == 0) - || (password == null) || (password.length() == 0)) { + if ((username == null) || (username.length() == 0) || (password == null) || (password.length() == 0)) { if (logger.isDebugEnabled()) { - logger.debug( - "Siteminder headers not found for authentication, so trying to use form values"); + logger.debug("Siteminder headers not found for authentication, so trying to use form values"); } - if ((formUsernameParameterKey != null) - && (formUsernameParameterKey.length() > 0)) { + if ((formUsernameParameterKey != null) && (formUsernameParameterKey.length() > 0)) { username = request.getParameter(formUsernameParameterKey); } else { username = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY); @@ -143,15 +124,13 @@ public class SiteminderAuthenticationProcessingFilter password = ""; } - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, - password); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); // Place the last username attempted into HttpSession for views - request.getSession() - .setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); + request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); return this.getAuthenticationManager().authenticate(authRequest); } @@ -193,73 +172,64 @@ public class SiteminderAuthenticationProcessingFilter } /** - * Overridden method to obtain different value depending on whether - * Siteminder or form validation is being performed. + * Overridden method to obtain different value depending on whether Siteminder or form validation is being + * performed. * * @param request so that request attributes can be retrieved * - * @return the password that will be presented in the - * Authentication request token to the + * @return the password that will be presented in the Authentication request token to the * AuthenticationManager */ protected String obtainPassword(HttpServletRequest request) { - if ((formPasswordParameterKey != null) - && (formPasswordParameterKey.length() > 0)) { + if ((formPasswordParameterKey != null) && (formPasswordParameterKey.length() > 0)) { return request.getParameter(formPasswordParameterKey); } else { return request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY); } } - /** - * Overridden to perform authentication not only on j_security_check, but also on - * requests for the default target URL when the user isn't already authenticated. - * - *

Thank you Paul Garvey for providing a straightforward solution (and code) for this!

- * - * @see org.acegisecurity.ui.AbstractProcessingFilter#requiresAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + /** + * Overridden to perform authentication not only on j_security_check, but also on requests for the default + * target URL when the user isn't already authenticated.

Thank you Paul Garvey for providing a + * straightforward solution (and code) for this!

+ * + * @see org.acegisecurity.ui.AbstractProcessingFilter#requiresAuthentication(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) */ - protected boolean requiresAuthentication(final HttpServletRequest request, - final HttpServletResponse response) { - - String uri = request.getRequestURI(); - int pathParamIndex = uri.indexOf(';'); + protected boolean requiresAuthentication(final HttpServletRequest request, final HttpServletResponse response) { + String uri = request.getRequestURI(); + int pathParamIndex = uri.indexOf(';'); - if (pathParamIndex > 0) { - // strip everything after the first semi-colon - uri = uri.substring(0, pathParamIndex); - } - - //attempt authentication if j_secuity_check is present or if the getDefaultTargetUrl() - //is present and user is not already authenticated. - boolean bAuthenticated = false; - SecurityContext context = (SecurityContext) request - .getSession() - .getAttribute( - HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); - if (context != null) { - Authentication auth = context.getAuthentication(); - if (auth != null - && auth instanceof UsernamePasswordAuthenticationToken) { - UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth; - bAuthenticated = token.isAuthenticated(); - } - } - - // if true is returned then authentication will be attempted. - boolean bAttemptAuthentication = (uri.endsWith(request.getContextPath() - + getFilterProcessesUrl())) - || ((getDefaultTargetUrl() != null - && uri.endsWith(getDefaultTargetUrl()) && !bAuthenticated)); - - if (logger.isDebugEnabled()) { - logger.debug("Authentication attempted for the following URI ==> " - + uri + " is " + bAttemptAuthentication); - } - - return bAttemptAuthentication; - - } + if (pathParamIndex > 0) { + // strip everything after the first semi-colon + uri = uri.substring(0, pathParamIndex); + } + + //attempt authentication if j_secuity_check is present or if the getDefaultTargetUrl() + //is present and user is not already authenticated. + boolean bAuthenticated = false; + SecurityContext context = (SecurityContext) request.getSession() + .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); + + if (context != null) { + Authentication auth = context.getAuthentication(); + + if ((auth != null) && auth instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth; + bAuthenticated = token.isAuthenticated(); + } + } + + // if true is returned then authentication will be attempted. + boolean bAttemptAuthentication = (uri.endsWith(request.getContextPath() + getFilterProcessesUrl())) + || ((getDefaultTargetUrl() != null) && uri.endsWith(getDefaultTargetUrl()) && !bAuthenticated); + + if (logger.isDebugEnabled()) { + logger.debug("Authentication attempted for the following URI ==> " + uri + " is " + bAttemptAuthentication); + } + + return bAttemptAuthentication; + } /** * Sets the form password parameter key. @@ -288,7 +258,6 @@ public class SiteminderAuthenticationProcessingFilter this.siteminderPasswordHeaderKey = key; } - /** * Sets the Siteminder username header key. * @@ -296,6 +265,5 @@ public class SiteminderAuthenticationProcessingFilter */ public void setSiteminderUsernameHeaderKey(final String key) { this.siteminderUsernameHeaderKey = key; - } - + } } diff --git a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilter.java index 1afaa00e6b..fcd1272f84 100644 --- a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilter.java @@ -49,76 +49,47 @@ import javax.servlet.http.HttpServletResponse; /** - * Processes the X.509 certificate submitted by a client browser when HTTPS is - * used with client-authentication enabled. - * - *

- * An {@link X509AuthenticationToken} is created with the certificate as the - * credentials. - *

- * - *

- * The configured authentication manager is expected to supply a provider which - * can handle this token (usually an instance of {@link - * org.acegisecurity.providers.x509.X509AuthenticationProvider}). - *

- * - *

- * If authentication is successful, an {@link - * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} - * will be published to the application context. No events will be published - * if authentication was unsuccessful, because this would generally be - * recorded via an AuthenticationManager-specific application - * event. - *

- * - *

- * Do not use this class directly. Instead configure - * web.xml to use the {@link - * org.acegisecurity.util.FilterToBeanProxy}. - *

+ * Processes the X.509 certificate submitted by a client browser when HTTPS is used with client-authentication + * enabled.

An {@link X509AuthenticationToken} is created with the certificate as the credentials.

+ *

The configured authentication manager is expected to supply a provider which can handle this token (usually + * an instance of {@link org.acegisecurity.providers.x509.X509AuthenticationProvider}).

+ *

If authentication is successful, an {@link + * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be published to the application + * context. No events will be published if authentication was unsuccessful, because this would generally be recorded + * via an AuthenticationManager-specific application event.

+ *

Do not use this class directly. Instead configure web.xml to use the {@link + * org.acegisecurity.util.FilterToBeanProxy}.

* * @author Luke Taylor * @version $Id$ */ -public class X509ProcessingFilter implements Filter, InitializingBean, - ApplicationEventPublisherAware { - //~ Static fields/initializers ============================================= +public class X509ProcessingFilter implements Filter, InitializingBean, ApplicationEventPublisherAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(X509ProcessingFilter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationEventPublisher eventPublisher; private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); private AuthenticationManager authenticationManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(authenticationManager, - "An AuthenticationManager must be set"); + Assert.notNull(authenticationManager, "An AuthenticationManager must be set"); } public void destroy() {} /** - * This method first checks for an existing, non-null authentication in the - * secure context. If one is found it does nothing. - * - *

- * If no authentication object exists, it attempts to obtain the client - * authentication certificate from the request. If there is no certificate - * present then authentication is skipped. Otherwise a new authentication - * request containing the certificate will be passed to the configured - * {@link AuthenticationManager}. - *

- * - *

- * If authentication is successful the returned token will be stored in the - * secure context. Otherwise it will be set to null. In either case, the - * request proceeds through the filter chain. - *

+ * This method first checks for an existing, non-null authentication in the secure context. If one is found + * it does nothing.

If no authentication object exists, it attempts to obtain the client authentication + * certificate from the request. If there is no certificate present then authentication is skipped. Otherwise a + * new authentication request containing the certificate will be passed to the configured {@link + * AuthenticationManager}.

+ *

If authentication is successful the returned token will be stored in the secure context. Otherwise + * it will be set to null. In either case, the request proceeds through the filter chain.

* * @param request DOCUMENT ME! * @param response DOCUMENT ME! @@ -127,8 +98,8 @@ public class X509ProcessingFilter implements Filter, InitializingBean, * @throws IOException DOCUMENT ME! * @throws ServletException DOCUMENT ME! */ - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain filterChain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } @@ -141,8 +112,7 @@ public class X509ProcessingFilter implements Filter, InitializingBean, HttpServletResponse httpResponse = (HttpServletResponse) response; if (logger.isDebugEnabled()) { - logger.debug("Checking secure context token: " - + SecurityContextHolder.getContext().getAuthentication()); + logger.debug("Checking secure context token: " + SecurityContextHolder.getContext().getAuthentication()); } if (SecurityContextHolder.getContext().getAuthentication() == null) { @@ -152,8 +122,7 @@ public class X509ProcessingFilter implements Filter, InitializingBean, try { X509AuthenticationToken authRequest = new X509AuthenticationToken(clientCertificate); - authRequest.setDetails(authenticationDetailsSource.buildDetails( - (HttpServletRequest) request)); + authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request)); authResult = authenticationManager.authenticate(authRequest); successfulAuthentication(httpRequest, httpResponse, authResult); } catch (AuthenticationException failed) { @@ -165,8 +134,7 @@ public class X509ProcessingFilter implements Filter, InitializingBean, } private X509Certificate extractClientCertificate(HttpServletRequest request) { - X509Certificate[] certs = (X509Certificate[]) request.getAttribute( - "javax.servlet.request.X509Certificate"); + X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); if ((certs != null) && (certs.length > 0)) { return certs[0]; @@ -185,21 +153,18 @@ public class X509ProcessingFilter implements Filter, InitializingBean, this.eventPublisher = context; } - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, - "AuthenticationDetailsSource required"); + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); this.authenticationDetailsSource = authenticationDetailsSource; } - public void setAuthenticationManager( - AuthenticationManager authenticationManager) { + public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } /** - * Puts the Authentication instance returned by the - * authentication manager into the secure context. + * Puts the Authentication instance returned by the authentication manager into the secure + * context. * * @param request DOCUMENT ME! * @param response DOCUMENT ME! @@ -207,9 +172,8 @@ public class X509ProcessingFilter implements Filter, InitializingBean, * * @throws IOException DOCUMENT ME! */ - protected void successfulAuthentication(HttpServletRequest request, - HttpServletResponse response, Authentication authResult) - throws IOException { + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, + Authentication authResult) throws IOException { if (logger.isDebugEnabled()) { logger.debug("Authentication success: " + authResult); } @@ -218,30 +182,25 @@ public class X509ProcessingFilter implements Filter, InitializingBean, // Fire event if (this.eventPublisher != null) { - eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent( - authResult, this.getClass())); + eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); } } /** - * Ensures the authentication object in the secure context is set to null - * when authentication fails. + * Ensures the authentication object in the secure context is set to null when authentication fails. * * @param request DOCUMENT ME! * @param response DOCUMENT ME! * @param failed DOCUMENT ME! */ - protected void unsuccessfulAuthentication(HttpServletRequest request, - HttpServletResponse response, AuthenticationException failed) { + protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, + AuthenticationException failed) { SecurityContextHolder.getContext().setAuthentication(null); if (logger.isDebugEnabled()) { - logger.debug( - "Updated SecurityContextHolder to contain null Authentication"); + logger.debug("Updated SecurityContextHolder to contain null Authentication"); } - request.getSession() - .setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, - failed); + request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed); } } diff --git a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java index 16b5f321d9..fe81905cf7 100644 --- a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,48 +15,59 @@ package org.acegisecurity.ui.x509; -import org.acegisecurity.ui.AuthenticationEntryPoint; import org.acegisecurity.AuthenticationException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import org.acegisecurity.ui.AuthenticationEntryPoint; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + + /** - * In the X.509 authentication case (unlike CAS, for example) the certificate will already - * have been extracted from the request and a secure context established by the time - * the security-enforcement filter is invoked. - *

- * Therefore this class isn't actually responsible for the commencement of authentication, as it - * is in the case of other providers. It will be called if the certificate was rejected by - * Acegi's X509AuthenticationProvider, resulting in a null authentication. - *

- * The commence method will always return an - * HttpServletResponse.SC_FORBIDDEN (403 error). - * + * In the X.509 authentication case (unlike CAS, for example) the certificate will already have been extracted from + * the request and a secure context established by the time the security-enforcement filter is invoked.

Therefore + * this class isn't actually responsible for the commencement of authentication, as it is in the case of other + * providers. It will be called if the certificate was rejected by Acegi's X509AuthenticationProvider, resulting in a + * null authentication.

+ * The commence method will always return an HttpServletResponse.SC_FORBIDDEN (403 + * error). * * @author Luke Taylor * @version $Id$ + * * @see org.acegisecurity.ui.ExceptionTranslationFilter */ public class X509ProcessingFilterEntryPoint implements AuthenticationEntryPoint { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(X509ProcessingFilterEntryPoint.class); - //~ Methods ================================================================ - + //~ Methods ======================================================================================================== + /** * Returns a 403 error code to the client. + * + * @param request DOCUMENT ME! + * @param response DOCUMENT ME! + * @param authException DOCUMENT ME! + * + * @throws IOException DOCUMENT ME! + * @throws ServletException DOCUMENT ME! */ - public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { - logger.debug("X509 entry point called. Rejecting access"); - HttpServletResponse httpResponse = (HttpServletResponse)response; + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) + throws IOException, ServletException { + if (logger.isDebugEnabled()) { + logger.debug("X509 entry point called. Rejecting access"); + } + + HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/User.java b/core/src/main/java/org/acegisecurity/userdetails/User.java index 0ca42645a9..b6ecd6fe14 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/User.java +++ b/core/src/main/java/org/acegisecurity/userdetails/User.java @@ -21,19 +21,15 @@ import org.springframework.util.Assert; /** - * Models core user information retieved by an {@link UserDetailsService}. - * - *

- * Implemented with value object semantics (immutable after construction, like - * a String). Developers may use this class directly, subclass - * it, or write their own {@link UserDetails} implementation from scratch. - *

+ * Models core user information retieved by an {@link UserDetailsService}.

Implemented with value object + * semantics (immutable after construction, like a String). Developers may use this class directly, + * subclass it, or write their own {@link UserDetails} implementation from scratch.

* * @author Ben Alex * @version $Id$ */ public class User implements UserDetails { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String password; private String username; @@ -43,9 +39,9 @@ public class User implements UserDetails { private boolean credentialsNonExpired; private boolean enabled; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Construct the User with the details required by {@link * DaoAuthenticationProvider}. * @@ -65,12 +61,12 @@ public class User implements UserDetails { * @deprecated use new constructor with extended properties (this * constructor will be removed from release 1.0.0) */ - public User(String username, String password, boolean enabled, - GrantedAuthority[] authorities) throws IllegalArgumentException { + public User(String username, String password, boolean enabled, GrantedAuthority[] authorities) + throws IllegalArgumentException { this(username, password, enabled, true, true, authorities); } - /** +/** * Construct the User with the details required by {@link * DaoAuthenticationProvider}. * @@ -94,14 +90,13 @@ public class User implements UserDetails { * @deprecated use new constructor with extended properties (this * constructor will be removed from release 1.0.0) */ - public User(String username, String password, boolean enabled, - boolean accountNonExpired, boolean credentialsNonExpired, - GrantedAuthority[] authorities) throws IllegalArgumentException { - this(username, password, enabled, accountNonExpired, - credentialsNonExpired, true, authorities); + public User(String username, String password, boolean enabled, boolean accountNonExpired, + boolean credentialsNonExpired, GrantedAuthority[] authorities) + throws IllegalArgumentException { + this(username, password, enabled, accountNonExpired, credentialsNonExpired, true, authorities); } - /** +/** * Construct the User with the details required by {@link * DaoAuthenticationProvider}. * @@ -124,13 +119,11 @@ public class User implements UserDetails { * either as a parameter or as an element in the * GrantedAuthority[] array */ - public User(String username, String password, boolean enabled, - boolean accountNonExpired, boolean credentialsNonExpired, - boolean accountNonLocked, GrantedAuthority[] authorities) + public User(String username, String password, boolean enabled, boolean accountNonExpired, + boolean credentialsNonExpired, boolean accountNonLocked, GrantedAuthority[] authorities) throws IllegalArgumentException { if (((username == null) || "".equals(username)) || (password == null)) { - throw new IllegalArgumentException( - "Cannot pass null or empty values to constructor"); + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); } this.username = username; @@ -142,7 +135,7 @@ public class User implements UserDetails { setAuthorities(authorities); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object rhs) { if (!(rhs instanceof User) || (rhs == null)) { @@ -164,12 +157,10 @@ public class User implements UserDetails { } // We rely on constructor to guarantee non-null username and password - return (this.getPassword().equals(user.getPassword()) - && this.getUsername().equals(user.getUsername()) + return (this.getPassword().equals(user.getPassword()) && this.getUsername().equals(user.getUsername()) && (this.isAccountNonExpired() == user.isAccountNonExpired()) && (this.isAccountNonLocked() == user.isAccountNonLocked()) - && (this.isCredentialsNonExpired() == user.isCredentialsNonExpired()) - && (this.isEnabled() == user.isEnabled())); + && (this.isCredentialsNonExpired() == user.isCredentialsNonExpired()) && (this.isEnabled() == user.isEnabled())); } public GrantedAuthority[] getAuthorities() { @@ -241,8 +232,7 @@ public class User implements UserDetails { for (int i = 0; i < authorities.length; i++) { Assert.notNull(authorities[i], - "Granted authority element " + i - + " is null - GrantedAuthority[] cannot contain any null elements"); + "Granted authority element " + i + " is null - GrantedAuthority[] cannot contain any null elements"); } this.authorities = authorities; diff --git a/core/src/main/java/org/acegisecurity/userdetails/UserDetails.java b/core/src/main/java/org/acegisecurity/userdetails/UserDetails.java index 016cff9353..bca2aebf82 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/UserDetails.java +++ b/core/src/main/java/org/acegisecurity/userdetails/UserDetails.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,11 @@ package org.acegisecurity.userdetails; -import java.io.Serializable; - import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; +import java.io.Serializable; + /** * Provides core user information. @@ -43,67 +43,57 @@ import org.acegisecurity.GrantedAuthority; * @version $Id$ */ public interface UserDetails extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Indicates whether the user's account has expired. An expired account - * cannot be authenticated. - * - * @return true if the user's account is valid (ie - * non-expired), false if no longer valid (ie - * expired) - */ - public boolean isAccountNonExpired(); - - /** - * Indicates whether the user is locked or unlocked. A locked user cannot - * be authenticated. - * - * @return true if the user is not locked, false - * otherwise - */ - public boolean isAccountNonLocked(); - - /** - * Returns the authorities granted to the user. Cannot return - * null. + * Returns the authorities granted to the user. Cannot return null. * * @return the authorities (never null) */ public GrantedAuthority[] getAuthorities(); /** - * Indicates whether the user's credentials (password) has expired. Expired - * credentials prevent authentication. - * - * @return true if the user's credentials are valid (ie - * non-expired), false if no longer valid (ie - * expired) - */ - public boolean isCredentialsNonExpired(); - - /** - * Indicates whether the user is enabled or disabled. A disabled user - * cannot be authenticated. - * - * @return true if the user is enabled, false - * otherwise - */ - public boolean isEnabled(); - - /** - * Returns the password used to authenticate the user. Cannot return - * null. + * Returns the password used to authenticate the user. Cannot return null. * * @return the password (never null) */ public String getPassword(); /** - * Returns the username used to authenticate the user. Cannot return - * null. + * Returns the username used to authenticate the user. Cannot return null. * * @return the username (never null) */ public String getUsername(); + + /** + * Indicates whether the user's account has expired. An expired account cannot be authenticated. + * + * @return true if the user's account is valid (ie non-expired), false if no longer valid + * (ie expired) + */ + public boolean isAccountNonExpired(); + + /** + * Indicates whether the user is locked or unlocked. A locked user cannot be authenticated. + * + * @return true if the user is not locked, false otherwise + */ + public boolean isAccountNonLocked(); + + /** + * Indicates whether the user's credentials (password) has expired. Expired credentials prevent + * authentication. + * + * @return true if the user's credentials are valid (ie non-expired), false if no longer + * valid (ie expired) + */ + public boolean isCredentialsNonExpired(); + + /** + * Indicates whether the user is enabled or disabled. A disabled user cannot be authenticated. + * + * @return true if the user is enabled, false otherwise + */ + public boolean isEnabled(); } diff --git a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java index f01938e463..36a23d6ed4 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java +++ b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsService.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.userdetails; import org.acegisecurity.providers.dao.DaoAuthenticationProvider; + import org.springframework.dao.DataAccessException; @@ -32,24 +33,20 @@ import org.springframework.dao.DataAccessException; * @version $Id$ */ public interface UserDetailsService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Locates the user based on the username. In the actual implementation, - * the search may possibly be case insensitive, or case insensitive - * depending on how the implementaion instance is configured. In this - * case, the UserDetails object that comes back may have a - * username that is of a different case than what was actually requested.. + * Locates the user based on the username. In the actual implementation, the search may possibly be case + * insensitive, or case insensitive depending on how the implementaion instance is configured. In this case, the + * UserDetails object that comes back may have a username that is of a different case than what was + * actually requested.. * - * @param username the username presented to the {@link - * DaoAuthenticationProvider} + * @param username the username presented to the {@link DaoAuthenticationProvider} * * @return a fully populated user record (never null) * - * @throws UsernameNotFoundException if the user could not be found or the - * user has no GrantedAuthority - * @throws DataAccessException if user could not be found for a - * repository-specific reason + * @throws UsernameNotFoundException if the user could not be found or the user has no GrantedAuthority + * @throws DataAccessException if user could not be found for a repository-specific reason */ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException; diff --git a/core/src/main/java/org/acegisecurity/userdetails/UsernameNotFoundException.java b/core/src/main/java/org/acegisecurity/userdetails/UsernameNotFoundException.java index 9009c97754..c5db5ce159 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/UsernameNotFoundException.java +++ b/core/src/main/java/org/acegisecurity/userdetails/UsernameNotFoundException.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,15 @@ import org.acegisecurity.BadCredentialsException; /** - * Thrown if an {@link UserDetailsService} implementation cannot locate a {@link - * User} by its username. + * Thrown if an {@link UserDetailsService} implementation cannot locate a {@link User} by its username. * * @author Ben Alex * @version $Id$ */ public class UsernameNotFoundException extends BadCredentialsException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a UsernameNotFoundException with the specified * message. * @@ -38,7 +37,7 @@ public class UsernameNotFoundException extends BadCredentialsException { super(msg); } - /** +/** * Constructs a UsernameNotFoundException with the specified * message and root cause. * diff --git a/core/src/main/java/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.java b/core/src/main/java/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.java index 75788e4398..d561940aec 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.java +++ b/core/src/main/java/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,58 +17,51 @@ package org.acegisecurity.userdetails.jdbc; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.context.ApplicationContextException; + import org.springframework.dao.DataAccessException; + import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.jdbc.object.MappingSqlQuery; -import javax.sql.DataSource; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; + import java.util.List; +import javax.sql.DataSource; + /** - *

- * Retrieves user details (username, password, enabled flag, and authorities) - * from a JDBC location. - *

- * - *

- * A default database structure is assumed, (see {@link - * #DEF_USERS_BY_USERNAME_QUERY} and {@link - * #DEF_AUTHORITIES_BY_USERNAME_QUERY}, which most users of this class will - * need to override, if using an existing scheme. This may be done by setting - * the default query strings used. If this does not provide enough - * flexibility, another strategy would be to subclass this class and override - * the {@link MappingSqlQuery} instances used, via the {@link - * #initMappingSqlQueries()} extension point. - *

- * - *

- * In order to minimise backward compatibility issues, this DAO does not - * recognise the expiration of user accounts or the expiration of user - * credentials. However, it does recognise and honour the user - * enabled/disabled column. - *

+ *

Retrieves user details (username, password, enabled flag, and authorities) from a JDBC location.

+ *

A default database structure is assumed, (see {@link #DEF_USERS_BY_USERNAME_QUERY} and {@link + * #DEF_AUTHORITIES_BY_USERNAME_QUERY}, which most users of this class will need to override, if using an existing + * scheme. This may be done by setting the default query strings used. If this does not provide enough flexibility, + * another strategy would be to subclass this class and override the {@link MappingSqlQuery} instances used, via the + * {@link #initMappingSqlQueries()} extension point.

+ *

In order to minimise backward compatibility issues, this DAO does not recognise the expiration of user + * accounts or the expiration of user credentials. However, it does recognise and honour the user enabled/disabled + * column.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String DEF_USERS_BY_USERNAME_QUERY = "SELECT username,password,enabled FROM users WHERE username = ?"; public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "SELECT username,authority FROM authorities WHERE username = ?"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected MappingSqlQuery authoritiesByUsernameMapping; protected MappingSqlQuery usersByUsernameMapping; @@ -77,95 +70,53 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService { private String usersByUsernameQuery; private boolean usernameBasedPrimaryKey = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcDaoImpl() { usersByUsernameQuery = DEF_USERS_BY_USERNAME_QUERY; authoritiesByUsernameQuery = DEF_AUTHORITIES_BY_USERNAME_QUERY; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Allows the default query string used to retrieve authorities based on - * username to be overriden, if default table or column names need to be - * changed. The default query is {@link - * #DEF_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure - * that all returned columns are mapped back to the same column names as - * in the default query. + * Allows subclasses to add their own granted authorities to the list to be returned in the + * User. * - * @param queryString The query string to set + * @param username the username, for use by finder methods + * @param authorities the current granted authorities, as populated from the authoritiesByUsername + * mapping */ - public void setAuthoritiesByUsernameQuery(String queryString) { - authoritiesByUsernameQuery = queryString; - } + protected void addCustomAuthorities(String username, List authorities) {} public String getAuthoritiesByUsernameQuery() { return authoritiesByUsernameQuery; } - /** - * Allows a default role prefix to be specified. If this is set to a - * non-empty value, then it is automatically prepended to any roles read - * in from the db. This may for example be used to add the - * ROLE_ prefix expected to exist in role names (by default) - * by some other Acegi Security framework classes, in the case that the - * prefix is not already present in the db. - * - * @param rolePrefix the new prefix - */ - public void setRolePrefix(String rolePrefix) { - this.rolePrefix = rolePrefix; - } - public String getRolePrefix() { return rolePrefix; } + public String getUsersByUsernameQuery() { + return usersByUsernameQuery; + } + + protected void initDao() throws ApplicationContextException { + initMappingSqlQueries(); + } + /** - * If true (the default), indicates the {@link - * #getUsersByUsernameMapping()} returns a username in response to a - * query. If false, indicates that a primary key is used - * instead. If set to true, the class will use the - * database-derived username in the returned UserDetails. If - * false, the class will use the {@link - * #loadUserByUsername(String)} derived username in the returned - * UserDetails. - * - * @param usernameBasedPrimaryKey true if the mapping queries - * return the username String, or false - * if the mapping returns a database primary key. + * Extension point to allow other MappingSqlQuery objects to be substituted in a subclass */ - public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) { - this.usernameBasedPrimaryKey = usernameBasedPrimaryKey; + protected void initMappingSqlQueries() { + this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource()); + this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource()); } public boolean isUsernameBasedPrimaryKey() { return usernameBasedPrimaryKey; } - /** - * Allows the default query string used to retrieve users based on username - * to be overriden, if default table or column names need to be changed. - * The default query is {@link #DEF_USERS_BY_USERNAME_QUERY}; when - * modifying this query, ensure that all returned columns are mapped back - * to the same column names as in the default query. If the 'enabled' - * column does not exist in the source db, a permanent true value for this - * column may be returned by using a query similar to
- *
-     * "SELECT username,password,'true' as enabled FROM users WHERE username = ?"
-     * 
- * - * @param usersByUsernameQueryString The query string to set - */ - public void setUsersByUsernameQuery(String usersByUsernameQueryString) { - this.usersByUsernameQuery = usersByUsernameQueryString; - } - - public String getUsersByUsernameQuery() { - return usersByUsernameQuery; - } - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { List users = usersByUsernameMapping.execute(username); @@ -184,8 +135,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService { throw new UsernameNotFoundException("User has no GrantedAuthority"); } - GrantedAuthority[] arrayAuths = - (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]); + GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]); String returnUsername = user.getUsername(); @@ -193,34 +143,62 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService { returnUsername = username; } - return new User(returnUsername, user.getPassword(), user.isEnabled(), - true, true, true, arrayAuths); + return new User(returnUsername, user.getPassword(), user.isEnabled(), true, true, true, arrayAuths); } /** - * Allows subclasses to add their own granted authorities to the list to be - * returned in the User. + * Allows the default query string used to retrieve authorities based on username to be overriden, if + * default table or column names need to be changed. The default query is {@link + * #DEF_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure that all returned columns are mapped + * back to the same column names as in the default query. * - * @param username the username, for use by finder methods - * @param authorities the current granted authorities, as populated from - * the authoritiesByUsername mapping + * @param queryString The query string to set */ - protected void addCustomAuthorities(String username, List authorities) {} - - protected void initDao() throws ApplicationContextException { - initMappingSqlQueries(); + public void setAuthoritiesByUsernameQuery(String queryString) { + authoritiesByUsernameQuery = queryString; } /** - * Extension point to allow other MappingSqlQuery objects to be substituted - * in a subclass + * Allows a default role prefix to be specified. If this is set to a non-empty value, then it is + * automatically prepended to any roles read in from the db. This may for example be used to add the + * ROLE_ prefix expected to exist in role names (by default) by some other Acegi Security framework + * classes, in the case that the prefix is not already present in the db. + * + * @param rolePrefix the new prefix */ - protected void initMappingSqlQueries() { - this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource()); - this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource()); + public void setRolePrefix(String rolePrefix) { + this.rolePrefix = rolePrefix; } - //~ Inner Classes ========================================================== + /** + * If true (the default), indicates the {@link #getUsersByUsernameMapping()} returns a + * username in response to a query. If false, indicates that a primary key is used instead. If set to + * true, the class will use the database-derived username in the returned UserDetails. + * If false, the class will use the {@link #loadUserByUsername(String)} derived username in the + * returned UserDetails. + * + * @param usernameBasedPrimaryKey true if the mapping queries return the username String, + * or false if the mapping returns a database primary key. + */ + public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) { + this.usernameBasedPrimaryKey = usernameBasedPrimaryKey; + } + + /** + * Allows the default query string used to retrieve users based on username to be overriden, if default + * table or column names need to be changed. The default query is {@link #DEF_USERS_BY_USERNAME_QUERY}; when + * modifying this query, ensure that all returned columns are mapped back to the same column names as in the + * default query. If the 'enabled' column does not exist in the source db, a permanent true value for this column + * may be returned by using a query similar to
+     * "SELECT username,password,'true' as enabled FROM users WHERE username = ?"
+ * + * @param usersByUsernameQueryString The query string to set + */ + public void setUsersByUsernameQuery(String usersByUsernameQueryString) { + this.usersByUsernameQuery = usersByUsernameQueryString; + } + + //~ Inner Classes ================================================================================================== /** * Query object to look up a user's authorities. @@ -256,8 +234,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService { String username = rs.getString(1); String password = rs.getString(2); boolean enabled = rs.getBoolean(3); - UserDetails user = new User(username, password, enabled, true, - true, true, + UserDetails user = new User(username, password, enabled, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")}); return user; diff --git a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetails.java b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetails.java index 5b2fcb5ae6..0124a21c8e 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetails.java +++ b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetails.java @@ -1,30 +1,54 @@ -package org.acegisecurity.userdetails.ldap; - -import org.acegisecurity.userdetails.UserDetails; - -import javax.naming.directory.Attributes; -import javax.naming.ldap.Control; - +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.userdetails.ldap; + +import org.acegisecurity.userdetails.UserDetails; + +import javax.naming.directory.Attributes; +import javax.naming.ldap.Control; + + /** * @author Luke Taylor * @version $Id$ - */ -public interface LdapUserDetails extends UserDetails { - /** - * @return the DN of the entry for this user's account. - */ - String getDn(); - - /** - * @return the attributes for the user's entry in the directory (or a subset of them, - * depending on what was retrieved). - */ - Attributes getAttributes(); - - /** - * Returns any LDAP response controls (as part of a user authentication process, for example). - * - * @return an array of LDAP Control instances, never null - */ - Control[] getControls(); -} + */ +public interface LdapUserDetails extends UserDetails { + //~ Methods ======================================================================================================== + + /** + * + DOCUMENT ME! + * + * @return the attributes for the user's entry in the directory (or a subset of them, depending on what was + * retrieved). + */ + Attributes getAttributes(); + + /** + * Returns any LDAP response controls (as part of a user authentication process, for example). + * + * @return an array of LDAP Control instances, never null + */ + Control[] getControls(); + + /** + * + DOCUMENT ME! + * + * @return the DN of the entry for this user's account. + */ + String getDn(); +} diff --git a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsImpl.java b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsImpl.java index fd69e3814a..491f6189a9 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsImpl.java +++ b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsImpl.java @@ -1,195 +1,211 @@ -package org.acegisecurity.userdetails.ldap; - -import org.acegisecurity.GrantedAuthority; -import org.springframework.util.Assert; - -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttributes; -import javax.naming.ldap.Control; -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * A UserDetails implementation which is used internally by the Ldap services. - * - * It also contains the user's distinguished name and a set of attributes that - * have been retrieved from the Ldap server. - *

- * An instance may be created as the result of a search, or when user information - * is retrieved during authentication. - *

- *

- * An instance of this class will be used by the LdapAuthenticationProvider - * to construct the final user details object that it returns. - *

- * - * @author Luke Taylor - * @version $Id$ - */ -public class LdapUserDetailsImpl implements LdapUserDetails { - - private static final GrantedAuthority[] NO_AUTHORITIES = new GrantedAuthority[0]; - private static final Control[] NO_CONTROLS = new Control[0]; - - //~ Instance fields ======================================================== - - private String dn; - private Attributes attributes = new BasicAttributes(); - private String username; - private String password; - private boolean enabled = true; - private boolean accountNonExpired = true; - private boolean credentialsNonExpired = true; - private boolean accountNonLocked = true; - private GrantedAuthority[] authorities = NO_AUTHORITIES; - private Control[] controls = NO_CONTROLS; - - //~ Constructors =========================================================== - - protected LdapUserDetailsImpl() { - } - - //~ Methods ================================================================ - - public String getDn() { - return dn; - } - - public Attributes getAttributes() { - return attributes; - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - public boolean isEnabled() { - return enabled; - } - - public boolean isAccountNonExpired() { - return accountNonExpired; - } - - public boolean isCredentialsNonExpired() { - return credentialsNonExpired; - } - - public boolean isAccountNonLocked() { - return accountNonLocked; - } - - public GrantedAuthority[] getAuthorities() { - return authorities; - } - - public Control[] getControls() { - return controls; - } - - //~ Inner classes ========================================================== - - /** - * Variation of essence pattern. Used to create mutable intermediate object - */ - public static class Essence { - - LdapUserDetailsImpl instance = new LdapUserDetailsImpl(); - - List mutableAuthorities = new ArrayList(); - - public Essence() { - } - - public Essence(LdapUserDetails copyMe) { - setDn(copyMe.getDn()); - setAttributes(copyMe.getAttributes()); - setUsername(copyMe.getUsername()); - setPassword(copyMe.getPassword()); - setEnabled(copyMe.isEnabled()); - setAccountNonExpired(copyMe.isAccountNonExpired()); - setCredentialsNonExpired(copyMe.isCredentialsNonExpired()); - setAccountNonLocked(copyMe.isAccountNonLocked()); - setControls(copyMe.getControls()); - setAuthorities(copyMe.getAuthorities()); - } - - public Essence setDn(String dn) { - instance.dn = dn; - return this; - } - - public Essence setAttributes(Attributes attributes) { - instance.attributes = attributes; - return this; - } - - public Essence setUsername(String username) { - instance.username = username; - return this; - } - - public Essence setPassword(String password) { - instance.password = password; - return this; - } - - public Essence setEnabled(boolean enabled) { - instance.enabled = enabled; - return this; - } - - public Essence setAccountNonExpired(boolean accountNonExpired) { - instance.accountNonExpired = accountNonExpired; - return this; - } - - public Essence setCredentialsNonExpired(boolean credentialsNonExpired) { - instance.credentialsNonExpired = credentialsNonExpired; - return this; - } - - public Essence setAccountNonLocked(boolean accountNonLocked) { - instance.accountNonLocked = accountNonLocked; - return this; - } - - public Essence setAuthorities(GrantedAuthority[] authorities) { - mutableAuthorities = new ArrayList(Arrays.asList(authorities)); - return this; - } - - public Essence addAuthority(GrantedAuthority a) { - mutableAuthorities.add(a); - - return this; - } - - public GrantedAuthority[] getGrantedAuthorities() { - return (GrantedAuthority[])mutableAuthorities.toArray(new GrantedAuthority[0]); - } - - public void setControls(Control[] controls) { - instance.controls = controls; - } - - public LdapUserDetails createUserDetails() { - //TODO: Validation of properties - - Assert.notNull(instance, "Essence can only be used to create a single instance"); - - instance.authorities = getGrantedAuthorities(); - - LdapUserDetails newInstance = instance; - - instance = null; - - return newInstance; - } - } -} +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.userdetails.ldap; + +import org.acegisecurity.GrantedAuthority; + +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttributes; +import javax.naming.ldap.Control; + + +/** + * A UserDetails implementation which is used internally by the Ldap services. It also contains the user's + * distinguished name and a set of attributes that have been retrieved from the Ldap server.

An instance may be + * created as the result of a search, or when user information is retrieved during authentication.

+ *

An instance of this class will be used by the LdapAuthenticationProvider to construct the final + * user details object that it returns.

+ * + * @author Luke Taylor + * @version $Id$ + */ +public class LdapUserDetailsImpl implements LdapUserDetails { + //~ Static fields/initializers ===================================================================================== + + private static final GrantedAuthority[] NO_AUTHORITIES = new GrantedAuthority[0]; + private static final Control[] NO_CONTROLS = new Control[0]; + + //~ Instance fields ================================================================================================ + + private Attributes attributes = new BasicAttributes(); + private String dn; + private String password; + private String username; + private GrantedAuthority[] authorities = NO_AUTHORITIES; + private Control[] controls = NO_CONTROLS; + private boolean accountNonExpired = true; + private boolean accountNonLocked = true; + private boolean credentialsNonExpired = true; + private boolean enabled = true; + + //~ Constructors =================================================================================================== + + protected LdapUserDetailsImpl() {} + + //~ Methods ======================================================================================================== + + public Attributes getAttributes() { + return attributes; + } + + public GrantedAuthority[] getAuthorities() { + return authorities; + } + + public Control[] getControls() { + return controls; + } + + public String getDn() { + return dn; + } + + public String getPassword() { + return password; + } + + public String getUsername() { + return username; + } + + public boolean isAccountNonExpired() { + return accountNonExpired; + } + + public boolean isAccountNonLocked() { + return accountNonLocked; + } + + public boolean isCredentialsNonExpired() { + return credentialsNonExpired; + } + + public boolean isEnabled() { + return enabled; + } + + //~ Inner Classes ================================================================================================== + + /** + * Variation of essence pattern. Used to create mutable intermediate object + */ + public static class Essence { + LdapUserDetailsImpl instance = new LdapUserDetailsImpl(); + List mutableAuthorities = new ArrayList(); + + public Essence() {} + + public Essence(LdapUserDetails copyMe) { + setDn(copyMe.getDn()); + setAttributes(copyMe.getAttributes()); + setUsername(copyMe.getUsername()); + setPassword(copyMe.getPassword()); + setEnabled(copyMe.isEnabled()); + setAccountNonExpired(copyMe.isAccountNonExpired()); + setCredentialsNonExpired(copyMe.isCredentialsNonExpired()); + setAccountNonLocked(copyMe.isAccountNonLocked()); + setControls(copyMe.getControls()); + setAuthorities(copyMe.getAuthorities()); + } + + public Essence addAuthority(GrantedAuthority a) { + mutableAuthorities.add(a); + + return this; + } + + public LdapUserDetails createUserDetails() { + //TODO: Validation of properties + Assert.notNull(instance, "Essence can only be used to create a single instance"); + + instance.authorities = getGrantedAuthorities(); + + LdapUserDetails newInstance = instance; + + instance = null; + + return newInstance; + } + + public GrantedAuthority[] getGrantedAuthorities() { + return (GrantedAuthority[]) mutableAuthorities.toArray(new GrantedAuthority[0]); + } + + public Essence setAccountNonExpired(boolean accountNonExpired) { + instance.accountNonExpired = accountNonExpired; + + return this; + } + + public Essence setAccountNonLocked(boolean accountNonLocked) { + instance.accountNonLocked = accountNonLocked; + + return this; + } + + public Essence setAttributes(Attributes attributes) { + instance.attributes = attributes; + + return this; + } + + public Essence setAuthorities(GrantedAuthority[] authorities) { + mutableAuthorities = new ArrayList(Arrays.asList(authorities)); + + return this; + } + + public void setControls(Control[] controls) { + instance.controls = controls; + } + + public Essence setCredentialsNonExpired(boolean credentialsNonExpired) { + instance.credentialsNonExpired = credentialsNonExpired; + + return this; + } + + public Essence setDn(String dn) { + instance.dn = dn; + + return this; + } + + public Essence setEnabled(boolean enabled) { + instance.enabled = enabled; + + return this; + } + + public Essence setPassword(String password) { + instance.password = password; + + return this; + } + + public Essence setUsername(String username) { + instance.username = username; + + return this; + } + } +} diff --git a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java index 5ade7e94f7..2f0ec2d687 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java +++ b/core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java @@ -1,109 +1,111 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.acegisecurity.userdetails.ldap; - -import org.acegisecurity.ldap.LdapEntryMapper; -import org.acegisecurity.GrantedAuthorityImpl; -import org.springframework.util.Assert; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.naming.directory.Attributes; -import javax.naming.directory.Attribute; -import javax.naming.NamingException; -import javax.naming.NamingEnumeration; - -/** - * The entry mapper used by the authenticators to create an ldap user - * object. - * - * - * @author Luke Taylor - * @version $Id$ - */ -public class LdapUserDetailsMapper implements LdapEntryMapper { - private final Log logger = LogFactory.getLog(LdapUserDetailsMapper.class); - - private String passwordAttributeName = "userPassword"; - - private String[] roleAttributes = null; - - private String rolePrefix = "ROLE_"; - - private boolean convertToUpperCase = true; - - public void setPasswordAttributeName(String passwordAttributeName) { - this.passwordAttributeName = passwordAttributeName; - } - - public void setRoleAttributes(String[] roleAttributes) { - Assert.notNull(roleAttributes, "roleAttributes array cannot be null"); - this.roleAttributes = roleAttributes; - } - - public void setConvertToUpperCase(boolean convertToUpperCase) { - this.convertToUpperCase = convertToUpperCase; - } - - public void setRolePrefix(String rolePrefix) { - this.rolePrefix = rolePrefix; - } - - public Object mapAttributes(String dn, Attributes attributes) throws NamingException { - LdapUserDetailsImpl.Essence essence = new LdapUserDetailsImpl.Essence(); - - essence.setDn(dn); - essence.setAttributes(attributes); - - Attribute passwordAttribute = attributes.get(passwordAttributeName); - - if(passwordAttribute != null) { - Object retrievedPassword = passwordAttribute.get(); - - if (!(retrievedPassword instanceof String)) { - // Assume it's binary - retrievedPassword = new String((byte[])retrievedPassword); - } - - essence.setPassword((String)retrievedPassword); - } - - // Map the roles - - for(int i=0; roleAttributes != null && i < roleAttributes.length; i++) { - Attribute roleAttribute = attributes.get(roleAttributes[i]); - - NamingEnumeration attributeRoles = roleAttribute.getAll(); - - while(attributeRoles.hasMore()) { - Object role = attributeRoles.next(); - - // We only handle Strings for the time being - if(role instanceof String) { - if(convertToUpperCase) { - role = ((String)role).toUpperCase(); - } - - essence.addAuthority(new GrantedAuthorityImpl(rolePrefix + role)); - } else { - logger.warn("Non-String value found for role attribute " + roleAttribute.getID()); - } - } - } - - return essence; - } -} +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.userdetails.ldap; + +import org.acegisecurity.GrantedAuthorityImpl; + +import org.acegisecurity.ldap.LdapEntryMapper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.util.Assert; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; + + +/** + * The entry mapper used by the authenticators to create an ldap user object. + * + * @author Luke Taylor + * @version $Id$ + */ +public class LdapUserDetailsMapper implements LdapEntryMapper { + //~ Instance fields ================================================================================================ + + private final Log logger = LogFactory.getLog(LdapUserDetailsMapper.class); + private String passwordAttributeName = "userPassword"; + private String rolePrefix = "ROLE_"; + private String[] roleAttributes = null; + private boolean convertToUpperCase = true; + + //~ Methods ======================================================================================================== + + public Object mapAttributes(String dn, Attributes attributes) + throws NamingException { + LdapUserDetailsImpl.Essence essence = new LdapUserDetailsImpl.Essence(); + + essence.setDn(dn); + essence.setAttributes(attributes); + + Attribute passwordAttribute = attributes.get(passwordAttributeName); + + if (passwordAttribute != null) { + Object retrievedPassword = passwordAttribute.get(); + + if (!(retrievedPassword instanceof String)) { + // Assume it's binary + retrievedPassword = new String((byte[]) retrievedPassword); + } + + essence.setPassword((String) retrievedPassword); + } + + // Map the roles + for (int i = 0; (roleAttributes != null) && (i < roleAttributes.length); i++) { + Attribute roleAttribute = attributes.get(roleAttributes[i]); + + NamingEnumeration attributeRoles = roleAttribute.getAll(); + + while (attributeRoles.hasMore()) { + Object role = attributeRoles.next(); + + // We only handle Strings for the time being + if (role instanceof String) { + if (convertToUpperCase) { + role = ((String) role).toUpperCase(); + } + + essence.addAuthority(new GrantedAuthorityImpl(rolePrefix + role)); + } else { + logger.warn("Non-String value found for role attribute " + roleAttribute.getID()); + } + } + } + + return essence; + } + + public void setConvertToUpperCase(boolean convertToUpperCase) { + this.convertToUpperCase = convertToUpperCase; + } + + public void setPasswordAttributeName(String passwordAttributeName) { + this.passwordAttributeName = passwordAttributeName; + } + + public void setRoleAttributes(String[] roleAttributes) { + Assert.notNull(roleAttributes, "roleAttributes array cannot be null"); + this.roleAttributes = roleAttributes; + } + + public void setRolePrefix(String rolePrefix) { + this.rolePrefix = rolePrefix; + } +} diff --git a/core/src/main/java/org/acegisecurity/userdetails/memory/InMemoryDaoImpl.java b/core/src/main/java/org/acegisecurity/userdetails/memory/InMemoryDaoImpl.java index 6b06396257..38ad2d695d 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/memory/InMemoryDaoImpl.java +++ b/core/src/main/java/org/acegisecurity/userdetails/memory/InMemoryDaoImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,18 @@ package org.acegisecurity.userdetails.memory; -import java.util.Properties; - import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.dao.DataAccessException; + import org.springframework.util.Assert; +import java.util.Properties; + /** * Retrieves user details from an in-memory list created by the bean context. @@ -32,40 +35,38 @@ import org.springframework.util.Assert; * @version $Id$ */ public class InMemoryDaoImpl implements UserDetailsService, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private UserMap userMap; - //~ Methods ================================================================ - - public void setUserMap(UserMap userMap) { - this.userMap = userMap; - } - - public UserMap getUserMap() { - return userMap; - } - - /** - * Modifies the internal UserMap to reflect the - * Properties instance passed. This helps externalise user - * information to another file etc. - * - * @param props the account information in a Properties object - * format - */ - public void setUserProperties(Properties props) { - UserMap userMap = new UserMap(); - this.userMap = UserMapEditor.addUsersFromProperties(userMap, props); - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(this.userMap, "A list of users, passwords, enabled/disabled status and their granted authorities must be set"); } + public UserMap getUserMap() { + return userMap; + } + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { return userMap.getUser(username); } + + public void setUserMap(UserMap userMap) { + this.userMap = userMap; + } + + /** + * Modifies the internal UserMap to reflect the Properties instance passed. This + * helps externalise user information to another file etc. + * + * @param props the account information in a Properties object format + */ + public void setUserProperties(Properties props) { + UserMap userMap = new UserMap(); + this.userMap = UserMapEditor.addUsersFromProperties(userMap, props); + } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttribute.java b/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttribute.java index ce015bdbbf..a6e4fbcbd5 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttribute.java +++ b/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttribute.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,34 +15,37 @@ package org.acegisecurity.userdetails.memory; -import java.util.List; -import java.util.Vector; - import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; +import java.util.List; +import java.util.Vector; + /** - * Used by {@link InMemoryDaoImpl} to temporarily store the attributes - * associated with a user. + * Used by {@link InMemoryDaoImpl} to temporarily store the attributes associated with a user. * * @author Ben Alex * @version $Id$ */ public class UserAttribute { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List authorities = new Vector(); private String password; private boolean enabled = true; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UserAttribute() { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void addAuthority(GrantedAuthority newAuthority) { + this.authorities.add(newAuthority); + } public GrantedAuthority[] getAuthorities() { GrantedAuthority[] toReturn = {new GrantedAuthorityImpl("demo")}; @@ -50,22 +53,14 @@ public class UserAttribute { return (GrantedAuthority[]) this.authorities.toArray(toReturn); } - public void setEnabled(boolean enabled) { - this.enabled = enabled; + public String getPassword() { + return password; } public boolean isEnabled() { return enabled; } - public void setPassword(String password) { - this.password = password; - } - - public String getPassword() { - return password; - } - public boolean isValid() { if ((this.password != null) && (authorities.size() > 0)) { return true; @@ -74,7 +69,11 @@ public class UserAttribute { } } - public void addAuthority(GrantedAuthority newAuthority) { - this.authorities.add(newAuthority); + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public void setPassword(String password) { + this.password = password; } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttributeEditor.java b/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttributeEditor.java index 05029322df..80d7d8bacc 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttributeEditor.java +++ b/core/src/main/java/org/acegisecurity/userdetails/memory/UserAttributeEditor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,21 +15,21 @@ package org.acegisecurity.userdetails.memory; -import java.beans.PropertyEditorSupport; - import org.acegisecurity.GrantedAuthorityImpl; + import org.springframework.util.StringUtils; +import java.beans.PropertyEditorSupport; + /** - * Property editor that creates a {@link UserAttribute} from a comma separated - * list of values. + * Property editor that creates a {@link UserAttribute} from a comma separated list of values. * * @author Ben Alex * @version $Id$ */ public class UserAttributeEditor extends PropertyEditorSupport { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void setAsText(String s) throws IllegalArgumentException { if (StringUtils.hasText(s)) { @@ -47,8 +47,7 @@ public class UserAttributeEditor extends PropertyEditorSupport { } else if (currentToken.toLowerCase().equals("disabled")) { userAttrib.setEnabled(false); } else { - userAttrib.addAuthority(new GrantedAuthorityImpl( - currentToken)); + userAttrib.addAuthority(new GrantedAuthorityImpl(currentToken)); } } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/memory/UserMap.java b/core/src/main/java/org/acegisecurity/userdetails/memory/UserMap.java index 0e072f647b..1444c15683 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/memory/UserMap.java +++ b/core/src/main/java/org/acegisecurity/userdetails/memory/UserMap.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,64 +15,35 @@ package org.acegisecurity.userdetails.memory; -import java.util.HashMap; -import java.util.Map; - import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; +import java.util.HashMap; +import java.util.Map; + /** - * Used by {@link InMemoryDaoImpl} to store a list of users and their - * corresponding granted authorities. + * Used by {@link InMemoryDaoImpl} to store a list of users and their corresponding granted authorities. * * @author Ben Alex * @version $Id$ */ public class UserMap { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(UserMap.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Map userMap = new HashMap(); - //~ Methods ================================================================ - - /** - * Locates the specified user by performing a case insensitive search by - * username. - * - * @param username to find - * - * @return the located user - * - * @throws UsernameNotFoundException if the user could not be found - */ - public User getUser(String username) throws UsernameNotFoundException { - User result = (User) this.userMap.get(username.toLowerCase()); - - if (result == null) { - throw new UsernameNotFoundException("Could not find user: " - + username); - } - - return result; - } - - /** - * Indicates the size of the user map. - * - * @return the number of users in the map - */ - public int getUserCount() { - return this.userMap.size(); - } + //~ Methods ======================================================================================================== /** * Adds a user to the in-memory map. @@ -87,4 +58,32 @@ public class UserMap { logger.info("Adding user [" + user + "]"); this.userMap.put(user.getUsername().toLowerCase(), user); } + + /** + * Locates the specified user by performing a case insensitive search by username. + * + * @param username to find + * + * @return the located user + * + * @throws UsernameNotFoundException if the user could not be found + */ + public User getUser(String username) throws UsernameNotFoundException { + User result = (User) this.userMap.get(username.toLowerCase()); + + if (result == null) { + throw new UsernameNotFoundException("Could not find user: " + username); + } + + return result; + } + + /** + * Indicates the size of the user map. + * + * @return the number of users in the map + */ + public int getUserCount() { + return this.userMap.size(); + } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/memory/UserMapEditor.java b/core/src/main/java/org/acegisecurity/userdetails/memory/UserMapEditor.java index b8f3dc6800..6a582b6224 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/memory/UserMapEditor.java +++ b/core/src/main/java/org/acegisecurity/userdetails/memory/UserMapEditor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,57 +15,59 @@ package org.acegisecurity.userdetails.memory; +import org.acegisecurity.userdetails.User; +import org.acegisecurity.userdetails.UserDetails; + +import org.springframework.beans.propertyeditors.PropertiesEditor; + import java.beans.PropertyEditorSupport; + import java.util.Iterator; import java.util.Properties; -import org.acegisecurity.userdetails.User; -import org.acegisecurity.userdetails.UserDetails; -import org.springframework.beans.propertyeditors.PropertiesEditor; - /** - * Property editor to assist with the setup of a {@link UserMap}. - * - *

- * The format of entries should be: - *

- * - *

- * - * username=password,grantedAuthority[,grantedAuthority][,enabled|disabled] - * - *

- * - *

- * The password must always be the first entry after the equals. - * The enabled or disabled keyword can appear - * anywhere (apart from the first entry reserved for the password). If neither - * enabled or disabled appear, the default is - * enabled. At least one granted authority must be listed. - *

- * - *

- * The username represents the key and duplicates are handled the - * same was as duplicates would be in Java Properties files. - *

- * - *

- * If the above requirements are not met, the invalid entry will be silently - * ignored. - *

- * - *

- * This editor always assumes each entry has a non-expired account and - * non-expired credentials. However, it does honour the user enabled/disabled - * flag as described above. - *

+ * Property editor to assist with the setup of a {@link UserMap}.

The format of entries should be:

+ *

username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]

+ *

The password must always be the first entry after the equals. The enabled or + * disabled keyword can appear anywhere (apart from the first entry reserved for the password). If + * neither enabled or disabled appear, the default is enabled. At least one + * granted authority must be listed.

+ *

The username represents the key and duplicates are handled the same was as duplicates would be + * in Java Properties files.

+ *

If the above requirements are not met, the invalid entry will be silently ignored.

+ *

This editor always assumes each entry has a non-expired account and non-expired credentials. However, it + * does honour the user enabled/disabled flag as described above.

* * @author Ben Alex * @version $Id$ */ public class UserMapEditor extends PropertyEditorSupport { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public static UserMap addUsersFromProperties(UserMap userMap, Properties props) { + // Now we have properties, process each one individually + UserAttributeEditor configAttribEd = new UserAttributeEditor(); + + for (Iterator iter = props.keySet().iterator(); iter.hasNext();) { + String username = (String) iter.next(); + String value = props.getProperty(username); + + // Convert value to a password, enabled setting, and list of granted authorities + configAttribEd.setAsText(value); + + UserAttribute attr = (UserAttribute) configAttribEd.getValue(); + + // Make a user object, assuming the properties were properly provided + if (attr != null) { + UserDetails user = new User(username, attr.getPassword(), attr.isEnabled(), true, true, true, + attr.getAuthorities()); + userMap.addUser(user); + } + } + + return userMap; + } public void setAsText(String s) throws IllegalArgumentException { UserMap userMap = new UserMap(); @@ -83,30 +85,4 @@ public class UserMapEditor extends PropertyEditorSupport { setValue(userMap); } - - public static UserMap addUsersFromProperties(UserMap userMap, - Properties props) { - // Now we have properties, process each one individually - UserAttributeEditor configAttribEd = new UserAttributeEditor(); - - for (Iterator iter = props.keySet().iterator(); iter.hasNext();) { - String username = (String) iter.next(); - String value = props.getProperty(username); - - // Convert value to a password, enabled setting, and list of granted authorities - configAttribEd.setAsText(value); - - UserAttribute attr = (UserAttribute) configAttribEd.getValue(); - - // Make a user object, assuming the properties were properly provided - if (attr != null) { - UserDetails user = new User(username, attr.getPassword(), - attr.isEnabled(), true, true, true, - attr.getAuthorities()); - userMap.addUser(user); - } - } - - return userMap; - } } diff --git a/core/src/main/java/org/acegisecurity/util/FilterChainProxy.java b/core/src/main/java/org/acegisecurity/util/FilterChainProxy.java index 91f6d07516..38433ab5ba 100644 --- a/core/src/main/java/org/acegisecurity/util/FilterChainProxy.java +++ b/core/src/main/java/org/acegisecurity/util/FilterChainProxy.java @@ -49,88 +49,56 @@ import javax.servlet.ServletResponse; /** - * Delegates Filter requests to a list of Spring-managed beans. - * - *

- * The FilterChainProxy is loaded via a standard {@link - * org.acegisecurity.util.FilterToBeanProxy} declaration in - * web.xml. FilterChainProxy will then pass {@link - * #init(FilterConfig)}, {@link #destroy()}, {@link #doInit()} and {@link - * #doFilter(ServletRequest, ServletResponse, FilterChain)} invocations - * through to each Filter defined against - * FilterChainProxy. - *

- * - *

- * FilterChainProxy is configured using a standard {@link - * org.acegisecurity.intercept.web.FilterInvocationDefinitionSource}. Each - * possible URI pattern that FilterChainProxy should service must - * be entered. The first matching URI pattern located by - * FilterInvocationDefinitionSource for a given request will be - * used to define all of the Filters that apply to that request. - * NB: This means you must put most specific URI patterns at the top of the - * list, and ensure all Filters that should apply for a given URI - * pattern are entered against the respective entry. The - * FilterChainProxy will not iterate the remainder of the URI - * patterns to locate additional Filters. The - * FilterInvocationDefinitionSource described the applicable URI - * pattern to fire the filter chain, followed by a list of configuration - * attributes. Each configuration attribute's {@link - * org.acegisecurity.ConfigAttribute#getAttribute()} corresponds to a bean - * name that is available from the application context. - *

- * - *

- * FilterChainProxy respects normal handling of - * Filters that elect not to call {@link - * javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, - * javax.servlet.ServletResponse, javax.servlet.FilterChain)}, in that the - * remainder of the origial or FilterChainProxy-declared filter - * chain will not be called. - *

- * - *

- * It is particularly noted the Filter lifecycle mismatch between - * the servlet container and IoC container. As per {@link - * org.acegisecurity.util.FilterToBeanProxy} JavaDocs, we recommend you allow - * the IoC container to manage lifecycle instead of the servlet container. By - * default the FilterToBeanProxy will never call this class' - * {@link #init(FilterConfig)} and {@link #destroy()} methods, meaning each of - * the filters defined against FilterInvocationDefinitionSource - * will not be called. If you do need your filters to be initialized and - * destroyed, please set the lifecycle initialization parameter - * against the FilterToBeanProxy to specify servlet container - * lifecycle management. - *

- * - *

- * If a filter name of {@link #TOKEN_NONE} is used, this allows specification - * of a filter pattern which should never cause any filters to fire. - *

+ * Delegates Filter requests to a list of Spring-managed beans.

The FilterChainProxy is + * loaded via a standard {@link org.acegisecurity.util.FilterToBeanProxy} declaration in web.xml. + * FilterChainProxy will then pass {@link #init(FilterConfig)}, {@link #destroy()}, {@link #doInit()} and + * {@link #doFilter(ServletRequest, ServletResponse, FilterChain)} invocations through to each Filter + * defined against FilterChainProxy.

+ *

FilterChainProxy is configured using a standard {@link + * org.acegisecurity.intercept.web.FilterInvocationDefinitionSource}. Each possible URI pattern that + * FilterChainProxy should service must be entered. The first matching URI pattern located by + * FilterInvocationDefinitionSource for a given request will be used to define all of the + * Filters that apply to that request. NB: This means you must put most specific URI patterns at the top + * of the list, and ensure all Filters that should apply for a given URI pattern are entered against the + * respective entry. The FilterChainProxy will not iterate the remainder of the URI patterns to locate + * additional Filters. The FilterInvocationDefinitionSource described the applicable URI + * pattern to fire the filter chain, followed by a list of configuration attributes. Each configuration attribute's + * {@link org.acegisecurity.ConfigAttribute#getAttribute()} corresponds to a bean name that is available from the + * application context.

+ *

FilterChainProxy respects normal handling of Filters that elect not to call {@link + * javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, + * javax.servlet.FilterChain)}, in that the remainder of the origial or FilterChainProxy-declared filter + * chain will not be called.

+ *

It is particularly noted the Filter lifecycle mismatch between the servlet container and IoC + * container. As per {@link org.acegisecurity.util.FilterToBeanProxy} JavaDocs, we recommend you allow the IoC + * container to manage lifecycle instead of the servlet container. By default the FilterToBeanProxy will + * never call this class' {@link #init(FilterConfig)} and {@link #destroy()} methods, meaning each of the filters + * defined against FilterInvocationDefinitionSource will not be called. If you do need your filters to be + * initialized and destroyed, please set the lifecycle initialization parameter against the + * FilterToBeanProxy to specify servlet container lifecycle management.

+ *

If a filter name of {@link #TOKEN_NONE} is used, this allows specification of a filter pattern which should + * never cause any filters to fire.

* * @author Carlos Sanchez * @author Ben Alex * @version $Id$ */ -public class FilterChainProxy implements Filter, InitializingBean, - ApplicationContextAware { - //~ Static fields/initializers ============================================= +public class FilterChainProxy implements Filter, InitializingBean, ApplicationContextAware { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(FilterChainProxy.class); public static final String TOKEN_NONE = "#NONE#"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext applicationContext; private FilterInvocationDefinitionSource filterInvocationDefinitionSource; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(filterInvocationDefinitionSource, - "filterInvocationDefinitionSource must be specified"); - Assert.notNull(this.filterInvocationDefinitionSource - .getConfigAttributeDefinitions(), + Assert.notNull(filterInvocationDefinitionSource, "filterInvocationDefinitionSource must be specified"); + Assert.notNull(this.filterInvocationDefinitionSource.getConfigAttributeDefinitions(), "FilterChainProxy requires the FilterInvocationDefinitionSource to return a non-null response to getConfigAttributeDefinitions()"); } @@ -140,9 +108,7 @@ public class FilterChainProxy implements Filter, InitializingBean, for (int i = 0; i < filters.length; i++) { if (filters[i] != null) { if (logger.isDebugEnabled()) { - logger.debug( - "Destroying Filter defined in ApplicationContext: '" - + filters[i].toString() + "'"); + logger.debug("Destroying Filter defined in ApplicationContext: '" + filters[i].toString() + "'"); } filters[i].destroy(); @@ -150,12 +116,11 @@ public class FilterChainProxy implements Filter, InitializingBean, } } - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); - ConfigAttributeDefinition cad = this.filterInvocationDefinitionSource - .getAttributes(fi); + ConfigAttributeDefinition cad = this.filterInvocationDefinitionSource.getAttributes(fi); if (cad == null) { if (logger.isDebugEnabled()) { @@ -169,7 +134,7 @@ public class FilterChainProxy implements Filter, InitializingBean, Filter[] filters = obtainAllDefinedFilters(cad); - if(filters.length == 0) { + if (filters.length == 0) { if (logger.isDebugEnabled()) { logger.debug(fi.getRequestUrl() + " has an empty filter list"); } @@ -177,11 +142,9 @@ public class FilterChainProxy implements Filter, InitializingBean, chain.doFilter(request, response); return; - } - VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, - filters); + VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters); virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse()); } @@ -195,9 +158,7 @@ public class FilterChainProxy implements Filter, InitializingBean, for (int i = 0; i < filters.length; i++) { if (filters[i] != null) { if (logger.isDebugEnabled()) { - logger.debug( - "Initializing Filter defined in ApplicationContext: '" - + filters[i].toString() + "'"); + logger.debug("Initializing Filter defined in ApplicationContext: '" + filters[i].toString() + "'"); } filters[i].init(filterConfig); @@ -206,30 +167,21 @@ public class FilterChainProxy implements Filter, InitializingBean, } /** - * Obtains all of the uniqueFilter instances registered - * against the FilterInvocationDefinitionSource. - * - *

- * This is useful in ensuring a Filter is not initialized or - * destroyed twice. - *

+ * Obtains all of the uniqueFilter instances registered against the + * FilterInvocationDefinitionSource.

This is useful in ensuring a Filter is not + * initialized or destroyed twice.

* - * @return all of the Filter instances in the application - * context for which there has been an entry against the - * FilterInvocationDefinitionSource (only one entry - * is included in the array for each Filter that - * actually exists in application context, even if a given - * Filter is defined multiples times by the - * FilterInvocationDefinitionSource) + * @return all of the Filter instances in the application context for which there has been an entry + * against the FilterInvocationDefinitionSource (only one entry is included in the array for + * each Filter that actually exists in application context, even if a given + * Filter is defined multiples times by the FilterInvocationDefinitionSource) */ private Filter[] obtainAllDefinedFilters() { - Iterator cads = this.filterInvocationDefinitionSource - .getConfigAttributeDefinitions(); + Iterator cads = this.filterInvocationDefinitionSource.getConfigAttributeDefinitions(); Set list = new LinkedHashSet(); while (cads.hasNext()) { - ConfigAttributeDefinition attribDef = (ConfigAttributeDefinition) cads - .next(); + ConfigAttributeDefinition attribDef = (ConfigAttributeDefinition) cads.next(); Filter[] filters = obtainAllDefinedFilters(attribDef); for (int i = 0; i < filters.length; i++) { @@ -241,18 +193,17 @@ public class FilterChainProxy implements Filter, InitializingBean, } /** - * Obtains all of the Filter instances registered against the - * specified ConfigAttributeDefinition. + * Obtains all of the Filter instances registered against the specified + * ConfigAttributeDefinition. * - * @param configAttributeDefinition for which we want to obtain associated - * Filters + * @param configAttributeDefinition for which we want to obtain associated Filters * - * @return the Filters against the specified - * ConfigAttributeDefinition (never + * @return the Filters against the specified ConfigAttributeDefinition (never * null) + * + * @throws IllegalArgumentException DOCUMENT ME! */ - private Filter[] obtainAllDefinedFilters( - ConfigAttributeDefinition configAttributeDefinition) { + private Filter[] obtainAllDefinedFilters(ConfigAttributeDefinition configAttributeDefinition) { List list = new Vector(); Iterator attributes = configAttributeDefinition.getConfigAttributes(); @@ -260,14 +211,13 @@ public class FilterChainProxy implements Filter, InitializingBean, ConfigAttribute attr = (ConfigAttribute) attributes.next(); String filterName = attr.getAttribute(); - if(filterName == null) { + if (filterName == null) { throw new IllegalArgumentException("Configuration attribute: '" + attr - + "' returned null to the getAttribute() method, which is invalid when used with FilterChainProxy"); + + "' returned null to the getAttribute() method, which is invalid when used with FilterChainProxy"); } if (!filterName.equals(TOKEN_NONE)) { - list.add(this.applicationContext.getBean(filterName, - Filter.class)); + list.add(this.applicationContext.getBean(filterName, Filter.class)); } } @@ -279,30 +229,24 @@ public class FilterChainProxy implements Filter, InitializingBean, this.applicationContext = applicationContext; } - public void setFilterInvocationDefinitionSource( - FilterInvocationDefinitionSource filterInvocationDefinitionSource) { + public void setFilterInvocationDefinitionSource(FilterInvocationDefinitionSource filterInvocationDefinitionSource) { this.filterInvocationDefinitionSource = filterInvocationDefinitionSource; } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** * A FilterChain that records whether or not {@link - * FilterChain#doFilter(javax.servlet.ServletRequest, - * javax.servlet.ServletResponse)} is called. - * - *

- * This FilterChain is used by FilterChainProxy - * to determine if the next Filter should be called or not. - *

+ * FilterChain#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} is called.

This + * FilterChain is used by FilterChainProxy to determine if the next Filter + * should be called or not.

*/ private class VirtualFilterChain implements FilterChain { private FilterInvocation fi; private Filter[] additionalFilters; private int currentPosition = 0; - public VirtualFilterChain(FilterInvocation filterInvocation, - Filter[] additionalFilters) { + public VirtualFilterChain(FilterInvocation filterInvocation, Filter[] additionalFilters) { this.fi = filterInvocation; this.additionalFilters = additionalFilters; } @@ -322,14 +266,12 @@ public class FilterChainProxy implements Filter, InitializingBean, currentPosition++; if (logger.isDebugEnabled()) { - logger.debug(fi.getRequestUrl() + " at position " - + currentPosition + " of " + additionalFilters.length - + " in additional filter chain; firing Filter: '" + logger.debug(fi.getRequestUrl() + " at position " + currentPosition + " of " + + additionalFilters.length + " in additional filter chain; firing Filter: '" + additionalFilters[currentPosition - 1] + "'"); } - additionalFilters[currentPosition - 1].doFilter(request, - response, this); + additionalFilters[currentPosition - 1].doFilter(request, response, this); } } } diff --git a/core/src/main/java/org/acegisecurity/util/FilterInvocationUtils.java b/core/src/main/java/org/acegisecurity/util/FilterInvocationUtils.java index eed8ad8b6d..8d63fb7c40 100644 --- a/core/src/main/java/org/acegisecurity/util/FilterInvocationUtils.java +++ b/core/src/main/java/org/acegisecurity/util/FilterInvocationUtils.java @@ -31,37 +31,28 @@ import javax.servlet.ServletResponse; /** - * Static utility methods for creating FilterInvocations usable - * within Acegi Security. - * - *

- * The generated FilterInvocation objects are not intended for use - * with AbstractSecurityInterceptor subclasses. Instead they are - * generally used by WebInvocationPrivilegeEvaluator. - *

+ * Static utility methods for creating FilterInvocations usable within Acegi Security.

The generated + * FilterInvocation objects are not intended for use with AbstractSecurityInterceptor + * subclasses. Instead they are generally used by WebInvocationPrivilegeEvaluator.

* * @author Ben Alex * @version $Id$ */ public class FilterInvocationUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Creates a FilterInvocation for the specified - * contextPath and Uri. Note the normal - * subclasses of AbstractFilterInvocationDefinitionSource - * disregard the contextPath when evaluating which secure - * object metadata applies to a given FilterInvocation, so - * generally the contextPath is unimportant unless you are - * using a custom FilterInvocationDefinitionSource. + * Creates a FilterInvocation for the specified contextPath and Uri. + * Note the normal subclasses of AbstractFilterInvocationDefinitionSource disregard the + * contextPath when evaluating which secure object metadata applies to a given + * FilterInvocation, so generally the contextPath is unimportant unless you are using a + * custom FilterInvocationDefinitionSource. * - * @param contextPath the contextPath that will be contained - * within the + * @param contextPath the contextPath that will be contained within the * FilterInvocationHttpServletRequest * @param uri the URI of the request, such as /foo/default.jsp * - * @return a fully-formed FilterInvocation (never - * null) + * @return a fully-formed FilterInvocation (never null) * * @throws UnsupportedOperationException DOCUMENT ME! */ @@ -74,11 +65,9 @@ public class FilterInvocationUtils { req.setContextPath(contextPath); req.setServletPath(null); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new FilterChain() { - public void doFilter(ServletRequest arg0, - ServletResponse arg1) + public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { throw new UnsupportedOperationException( "WebInvocationPrivilegeEvaluator does not support filter chains"); @@ -89,14 +78,12 @@ public class FilterInvocationUtils { } /** - * Creates a FilterInvocation for the specified - * Uri. The contextPath is set to a default - * value. + * Creates a FilterInvocation for the specified Uri. The contextPath + * is set to a default value. * * @param uri the URI of the request, such as /foo/default.jsp * - * @return a fully-formed FilterInvocation (never - * null) + * @return a fully-formed FilterInvocation (never null) */ public static FilterInvocation create(String uri) { return create("/notused", uri); diff --git a/core/src/main/java/org/acegisecurity/util/FilterToBeanProxy.java b/core/src/main/java/org/acegisecurity/util/FilterToBeanProxy.java index 5d9cf1cb96..3d77aea5a3 100644 --- a/core/src/main/java/org/acegisecurity/util/FilterToBeanProxy.java +++ b/core/src/main/java/org/acegisecurity/util/FilterToBeanProxy.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.util; import org.springframework.beans.factory.BeanFactoryUtils; @@ -33,86 +34,55 @@ import javax.servlet.ServletResponse; /** - * Delegates Filter requests to a Spring-managed bean. - * - *

- * This class acts as a proxy on behalf of a target Filter that is - * defined in the Spring bean context. It is necessary to specify which target - * Filter should be proxied as a filter initialization parameter. - *

- * - *

- * On filter initialisation, the class will use Spring's {@link - * WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)} - * method to obtain an ApplicationContext instance. It will - * expect to find the target Filter in this - * ApplicationContext. - *

- * - *

- * To use this filter, it is necessary to specify one of the following - * filter initialization parameters: - *

- * - *
    - *
  • - * targetClass indicates the class of the target - * Filter defined in the bean context. The only requirements are - * that this target class implements the javax.servlet.Filter - * interface and at least one instance is available in the - * ApplicationContext. - *
  • - *
  • - * targetBean indicates the bean name of the target class. - *
  • - *
- * - * If both initialization parameters are specified, targetBean - * takes priority. - * - *

- * An additional initialization parameter, init, is also - * supported. If set to "lazy" the initialization will take place - * on the first HTTP request, rather than at filter creation time. This makes - * it possible to use FilterToBeanProxy with the Spring - * ContextLoaderServlet. Where possible you should not use this - * initialization parameter, instead using ContextLoaderListener. - *

- * - *

- * A final optional initialization parameter, lifecycle, - * determines whether the servlet container or the IoC container manages the - * lifecycle of the proxied filter. When possible you should write your - * filters to be managed via the IoC container interfaces such as {@link - * org.springframework.beans.factory.InitializingBean} and {@link - * org.springframework.beans.factory.DisposableBean}. If you cannot control - * the filters you wish to proxy (eg you do not have their source code) you - * might need to allow the servlet container to manage lifecycle via the - * {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and {@link - * javax.servlet.Filter#destroy()} methods. If this case, set the - * lifecycle initialization parameter to - * servlet-container-managed. If the parameter is any other - * value, servlet container lifecycle methods will not be delegated through to - * the proxy. - *

+ * Delegates Filter requests to a Spring-managed bean.

This class acts as a proxy on behalf of a + * target Filter that is defined in the Spring bean context. It is necessary to specify which target + * Filter should be proxied as a filter initialization parameter.

+ *

On filter initialisation, the class will use Spring's {@link + * WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)} method to obtain an + * ApplicationContext instance. It will expect to find the target Filter in this + * ApplicationContext.

+ *

To use this filter, it is necessary to specify one of the following filter initialization parameters:

+ *
    + *
  • targetClass indicates the class of the target Filter defined in the bean + * context. The only requirements are that this target class implements the javax.servlet.Filter + * interface and at least one instance is available in the ApplicationContext.
  • + *
  • targetBean indicates the bean name of the target class.
  • + *
+ * If both initialization parameters are specified, targetBean takes priority.

An additional + * initialization parameter, init, is also supported. If set to "lazy" the initialization + * will take place on the first HTTP request, rather than at filter creation time. This makes it possible to use + * FilterToBeanProxy with the Spring ContextLoaderServlet. Where possible you should not use + * this initialization parameter, instead using ContextLoaderListener.

+ *

A final optional initialization parameter, lifecycle, determines whether the servlet container + * or the IoC container manages the lifecycle of the proxied filter. When possible you should write your filters to be + * managed via the IoC container interfaces such as {@link org.springframework.beans.factory.InitializingBean} and + * {@link org.springframework.beans.factory.DisposableBean}. If you cannot control the filters you wish to proxy (eg + * you do not have their source code) you might need to allow the servlet container to manage lifecycle via the {@link + * javax.servlet.Filter#init(javax.servlet.FilterConfig)} and {@link javax.servlet.Filter#destroy()} methods. If this + * case, set the lifecycle initialization parameter to servlet-container-managed. If the + * parameter is any other value, servlet container lifecycle methods will not be delegated through to the proxy.

* * @author Ben Alex * @version $Id$ */ public class FilterToBeanProxy implements Filter { + //~ Instance fields ================================================================================================ + private Filter delegate; private FilterConfig filterConfig; private boolean initialized = false; private boolean servletContainerManaged = false; + //~ Methods ======================================================================================================== + public void destroy() { if ((delegate != null) && servletContainerManaged) { delegate.destroy(); } } - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { if (!initialized) { doInit(); } @@ -120,30 +90,6 @@ public class FilterToBeanProxy implements Filter { delegate.doFilter(request, response, chain); } - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - - String strategy = filterConfig.getInitParameter("init"); - - if ((strategy != null) && strategy.toLowerCase().equals("lazy")) { - return; - } - - doInit(); - } - - /** - * Allows test cases to override where application context obtained from. - * - * @param filterConfig which can be used to find the - * ServletContext - * - * @return the Spring application context - */ - protected ApplicationContext getContext(FilterConfig filterConfig) { - return WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()); - } - private synchronized void doInit() throws ServletException { if (initialized) { // already initialized, so don't re-initialize @@ -169,34 +115,26 @@ public class FilterToBeanProxy implements Filter { if ((targetBean != null) && ctx.containsBean(targetBean)) { beanName = targetBean; } else if (targetBean != null) { - throw new ServletException("targetBean '" + targetBean + - "' not found in context"); + throw new ServletException("targetBean '" + targetBean + "' not found in context"); } else { - String targetClassString = filterConfig.getInitParameter( - "targetClass"); + String targetClassString = filterConfig.getInitParameter("targetClass"); if ((targetClassString == null) || "".equals(targetClassString)) { - throw new ServletException( - "targetClass or targetBean must be specified"); + throw new ServletException("targetClass or targetBean must be specified"); } Class targetClass; try { - targetClass = Thread.currentThread().getContextClassLoader() - .loadClass(targetClassString); + targetClass = Thread.currentThread().getContextClassLoader().loadClass(targetClassString); } catch (ClassNotFoundException ex) { - throw new ServletException("Class of type " + - targetClassString + " not found in classloader"); + throw new ServletException("Class of type " + targetClassString + " not found in classloader"); } - Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, - targetClass, true, true); + Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, targetClass, true, true); if (beans.size() == 0) { - throw new ServletException( - "Bean context must contain at least one bean of type " + - targetClassString); + throw new ServletException("Bean context must contain at least one bean of type " + targetClassString); } beanName = (String) beans.keySet().iterator().next(); @@ -205,8 +143,7 @@ public class FilterToBeanProxy implements Filter { Object object = ctx.getBean(beanName); if (!(object instanceof Filter)) { - throw new ServletException("Bean '" + beanName + - "' does not implement javax.servlet.Filter"); + throw new ServletException("Bean '" + beanName + "' does not implement javax.servlet.Filter"); } delegate = (Filter) object; @@ -220,4 +157,27 @@ public class FilterToBeanProxy implements Filter { // cause NullPointerException initialized = true; } + + /** + * Allows test cases to override where application context obtained from. + * + * @param filterConfig which can be used to find the ServletContext + * + * @return the Spring application context + */ + protected ApplicationContext getContext(FilterConfig filterConfig) { + return WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()); + } + + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + + String strategy = filterConfig.getInitParameter("init"); + + if ((strategy != null) && strategy.toLowerCase().equals("lazy")) { + return; + } + + doInit(); + } } diff --git a/core/src/main/java/org/acegisecurity/util/InMemoryResource.java b/core/src/main/java/org/acegisecurity/util/InMemoryResource.java index 55f323390c..381dd1ab9e 100644 --- a/core/src/main/java/org/acegisecurity/util/InMemoryResource.java +++ b/core/src/main/java/org/acegisecurity/util/InMemoryResource.java @@ -1,26 +1,42 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.util; import org.springframework.core.io.AbstractResource; import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; + /** - * An in memory implementation of Spring's {@link org.springframework.core.io.Resource} interface. - *

- * Used by the "Acegifier" web application to create a - * bean factory from an XML string, rather than a file. - *

+ * An in memory implementation of Spring's {@link org.springframework.core.io.Resource} interface.

Used by the + * "Acegifier" web application to create a bean factory from an XML string, rather than a file.

* * @author Luke Taylor * @version $Id$ */ public class InMemoryResource extends AbstractResource { + //~ Instance fields ================================================================================================ ByteArrayInputStream in; String description; + //~ Constructors =================================================================================================== + public InMemoryResource(byte[] source) { this(source, null); } @@ -30,8 +46,10 @@ public class InMemoryResource extends AbstractResource { this.description = description; } + //~ Methods ======================================================================================================== + public String getDescription() { - return description == null ? in.toString() : description; + return (description == null) ? in.toString() : description; } public InputStream getInputStream() throws IOException { diff --git a/core/src/main/java/org/acegisecurity/util/MethodInvocationUtils.java b/core/src/main/java/org/acegisecurity/util/MethodInvocationUtils.java index 96fcf67474..b4e4883f6f 100644 --- a/core/src/main/java/org/acegisecurity/util/MethodInvocationUtils.java +++ b/core/src/main/java/org/acegisecurity/util/MethodInvocationUtils.java @@ -26,50 +26,38 @@ import java.util.List; /** - * Static utility methods for creating MethodInvocations usable - * within Acegi Security. - * - *

- * All methods of this class return a {@link - * org.acegisecurity.util.SimpleMethodInvocation}. - *

+ * Static utility methods for creating MethodInvocations usable within Acegi Security.

All methods + * of this class return a {@link org.acegisecurity.util.SimpleMethodInvocation}.

* * @author Ben Alex * @version $Id$ */ public class MethodInvocationUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Generates a MethodInvocation for specified - * methodName on the passed object. + * Generates a MethodInvocation for specified methodName on the passed object. * - * @param object the object that will be used to find the relevant - * Method + * @param object the object that will be used to find the relevant Method * @param methodName the name of the method to find * - * @return a MethodInvocation, or null if there - * was a problem + * @return a MethodInvocation, or null if there was a problem */ public static MethodInvocation create(Object object, String methodName) { return create(object, methodName, null); } /** - * Generates a MethodInvocation for specified - * methodName on the passed object, using the - * args to locate the method. + * Generates a MethodInvocation for specified methodName on the passed object, + * using the args to locate the method. * - * @param object the object that will be used to find the relevant - * Method + * @param object the object that will be used to find the relevant Method * @param methodName the name of the method to find * @param args arguments that are required as part of the method signature * - * @return a MethodInvocation, or null if there - * was a problem + * @return a MethodInvocation, or null if there was a problem */ - public static MethodInvocation create(Object object, String methodName, - Object[] args) { + public static MethodInvocation create(Object object, String methodName, Object[] args) { Assert.notNull(object, "Object required"); Class[] classArgs = null; @@ -88,36 +76,28 @@ public class MethodInvocationUtils { } /** - * Generates a MethodInvocation for specified - * methodName on the passed class. + * Generates a MethodInvocation for specified methodName on the passed class. * - * @param clazz the class of object that will be used to find the relevant - * Method + * @param clazz the class of object that will be used to find the relevant Method * @param methodName the name of the method to find * - * @return a MethodInvocation, or null if there - * was a problem + * @return a MethodInvocation, or null if there was a problem */ - public static MethodInvocation createFromClass(Class clazz, - String methodName) { + public static MethodInvocation createFromClass(Class clazz, String methodName) { return createFromClass(clazz, methodName, null); } /** - * Generates a MethodInvocation for specified - * methodName on the passed class, using the - * args to locate the method. + * Generates a MethodInvocation for specified methodName on the passed class, + * using the args to locate the method. * - * @param clazz the class of object that will be used to find the relevant - * Method + * @param clazz the class of object that will be used to find the relevant Method * @param methodName the name of the method to find * @param args arguments that are required as part of the method signature * - * @return a MethodInvocation, or null if there - * was a problem + * @return a MethodInvocation, or null if there was a problem */ - public static MethodInvocation createFromClass(Class clazz, - String methodName, Class[] args) { + public static MethodInvocation createFromClass(Class clazz, String methodName, Class[] args) { Assert.notNull(clazz, "Class required"); Assert.hasText(methodName, "MethodName required"); diff --git a/core/src/main/java/org/acegisecurity/util/PortMapper.java b/core/src/main/java/org/acegisecurity/util/PortMapper.java index e5590c3aa9..0951bcf03d 100644 --- a/core/src/main/java/org/acegisecurity/util/PortMapper.java +++ b/core/src/main/java/org/acegisecurity/util/PortMapper.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,14 +24,10 @@ package org.acegisecurity.util; * @version $Id$ */ public interface PortMapper { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Locates the HTTP port associated with the specified HTTPS port. - * - *

- * Returns null if unknown. - *

+ * Locates the HTTP port associated with the specified HTTPS port.

Returns null if unknown.

* * @param httpsPort * @@ -40,11 +36,7 @@ public interface PortMapper { public Integer lookupHttpPort(Integer httpsPort); /** - * Locates the HTTPS port associated with the specified HTTP port. - * - *

- * Returns null if unknown. - *

+ * Locates the HTTPS port associated with the specified HTTP port.

Returns null if unknown.

* * @param httpPort * diff --git a/core/src/main/java/org/acegisecurity/util/PortMapperImpl.java b/core/src/main/java/org/acegisecurity/util/PortMapperImpl.java index e5cc1723b7..de18f77a33 100644 --- a/core/src/main/java/org/acegisecurity/util/PortMapperImpl.java +++ b/core/src/main/java/org/acegisecurity/util/PortMapperImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,25 +23,20 @@ import java.util.Map; /** - * Concrete implementation of {@link PortMapper} that obtains HTTP:HTTPS pairs - * from the application context. - * - *

- * By default the implementation will assume 80:443 and 8080:8443 are - * HTTP:HTTPS pairs respectively. If different pairs are required, use {@link - * #setPortMappings(Map)}. - *

+ * Concrete implementation of {@link PortMapper} that obtains HTTP:HTTPS pairs from the application context.

By + * default the implementation will assume 80:443 and 8080:8443 are HTTP:HTTPS pairs respectively. If different pairs + * are required, use {@link #setPortMappings(Map)}.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class PortMapperImpl implements PortMapper { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Map httpsPortMappings; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PortMapperImpl() { httpsPortMappings = new HashMap(); @@ -49,62 +44,11 @@ public class PortMapperImpl implements PortMapper { httpsPortMappings.put(new Integer(8080), new Integer(8443)); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - *

- * Set to override the default HTTP port to HTTPS port mappings of 80:443, - * and 8080:8443. - *

- * In a Spring XML ApplicationContext, a definition would look something - * like this: - *
-     *   <property name="portMappings">
-     *     <map>
-     *       <entry key="80"><value>443</value></entry>
-     *       <entry key="8080"><value>8443</value></entry>
-     *     </map>
-     *   </property>
-     * 
- * - * @param newMappings A Map consisting of String keys and String values, - * where for each entry the key is the string representation of an - * integer HTTP port number, and the value is the string - * representation of the corresponding integer HTTPS port number. - * - * @throws IllegalArgumentException if input map does not consist of String - * keys and values, each representing an integer port number in - * the range 1-65535 for that mapping. - */ - public void setPortMappings(Map newMappings) { - Assert.notNull(newMappings, "A valid list of HTTPS port mappings must be provided"); - - httpsPortMappings.clear(); - - Iterator it = newMappings.entrySet().iterator(); - - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - Integer httpPort = new Integer((String) entry.getKey()); - Integer httpsPort = new Integer((String) entry.getValue()); - - if ((httpPort.intValue() < 1) || (httpPort.intValue() > 65535) - || (httpsPort.intValue() < 1) || (httpsPort.intValue() > 65535)) { - throw new IllegalArgumentException("one or both ports out of legal range: " + httpPort + ", " - + httpsPort); - } - - httpsPortMappings.put(httpPort, httpsPort); - } - - if (httpsPortMappings.size() < 1) { - throw new IllegalArgumentException("must map at least one port"); - } - } - - /** - * Returns the translated (Integer -> Integer) version of the original port - * mapping specified via setHttpsPortMapping() + * Returns the translated (Integer -> Integer) version of the original port mapping specified via + * setHttpsPortMapping() * * @return DOCUMENT ME! */ @@ -129,4 +73,43 @@ public class PortMapperImpl implements PortMapper { public Integer lookupHttpsPort(Integer httpPort) { return (Integer) httpsPortMappings.get(httpPort); } + + /** + *

Set to override the default HTTP port to HTTPS port mappings of 80:443, and 8080:8443.

+ * In a Spring XML ApplicationContext, a definition would look something like this:
+     *   <property name="portMappings">    <map>      <entry key="80"><value>443</value></entry>
+     *       <entry key="8080"><value>8443</value></entry>    </map>  </property>
+ * + * @param newMappings A Map consisting of String keys and String values, where for each entry the key is the string + * representation of an integer HTTP port number, and the value is the string representation of the + * corresponding integer HTTPS port number. + * + * @throws IllegalArgumentException if input map does not consist of String keys and values, each representing an + * integer port number in the range 1-65535 for that mapping. + */ + public void setPortMappings(Map newMappings) { + Assert.notNull(newMappings, "A valid list of HTTPS port mappings must be provided"); + + httpsPortMappings.clear(); + + Iterator it = newMappings.entrySet().iterator(); + + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Integer httpPort = new Integer((String) entry.getKey()); + Integer httpsPort = new Integer((String) entry.getValue()); + + if ((httpPort.intValue() < 1) || (httpPort.intValue() > 65535) || (httpsPort.intValue() < 1) + || (httpsPort.intValue() > 65535)) { + throw new IllegalArgumentException("one or both ports out of legal range: " + httpPort + ", " + + httpsPort); + } + + httpsPortMappings.put(httpPort, httpsPort); + } + + if (httpsPortMappings.size() < 1) { + throw new IllegalArgumentException("must map at least one port"); + } + } } diff --git a/core/src/main/java/org/acegisecurity/util/PortResolver.java b/core/src/main/java/org/acegisecurity/util/PortResolver.java index 6c7d3bc880..875f1f0730 100644 --- a/core/src/main/java/org/acegisecurity/util/PortResolver.java +++ b/core/src/main/java/org/acegisecurity/util/PortResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ import javax.servlet.ServletRequest; * @version $Id$ */ public interface PortResolver { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Indicates the port the ServletRequest was received on. diff --git a/core/src/main/java/org/acegisecurity/util/PortResolverImpl.java b/core/src/main/java/org/acegisecurity/util/PortResolverImpl.java index f2a227c505..895e630563 100644 --- a/core/src/main/java/org/acegisecurity/util/PortResolverImpl.java +++ b/core/src/main/java/org/acegisecurity/util/PortResolverImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.util; import org.springframework.beans.factory.InitializingBean; + import org.springframework.util.Assert; import javax.servlet.ServletRequest; @@ -23,31 +24,25 @@ import javax.servlet.ServletRequest; /** * Concrete implementation of {@link PortResolver} that obtains the port from - * ServletRequest.getServerPort(). - * - *

- * This class is capable of handling the IE bug which results in an incorrect - * URL being presented in the header subsequent to a redirect to a different - * scheme and port where the port is not a well-known number (ie 80 or 443). - * Handling involves detecting an incorrect response from - * ServletRequest.getServerPort() for the scheme (eg a HTTP - * request on 8443) and then determining the real server port (eg HTTP request - * is really on 8080). The map of valid ports is obtained from the configured - * {@link PortMapper}. - *

+ * ServletRequest.getServerPort().

This class is capable of handling the IE bug which results in an + * incorrect URL being presented in the header subsequent to a redirect to a different scheme and port where the port + * is not a well-known number (ie 80 or 443). Handling involves detecting an incorrect response from + * ServletRequest.getServerPort() for the scheme (eg a HTTP request on 8443) and then determining the + * real server port (eg HTTP request is really on 8080). The map of valid ports is obtained from the configured {@link + * PortMapper}.

* * @author Ben Alex * @version $Id$ */ public class PortResolverImpl implements InitializingBean, PortResolver { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private PortMapper portMapper = new PortMapperImpl(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setPortMapper(PortMapper portMapper) { - this.portMapper = portMapper; + public void afterPropertiesSet() throws Exception { + Assert.notNull(portMapper, "portMapper required"); } public PortMapper getPortMapper() { @@ -78,7 +73,7 @@ public class PortResolverImpl implements InitializingBean, PortResolver { return result; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(portMapper, "portMapper required"); + public void setPortMapper(PortMapper portMapper) { + this.portMapper = portMapper; } } diff --git a/core/src/main/java/org/acegisecurity/util/SimpleMethodInvocation.java b/core/src/main/java/org/acegisecurity/util/SimpleMethodInvocation.java index c31428acb3..2a6aeeb878 100644 --- a/core/src/main/java/org/acegisecurity/util/SimpleMethodInvocation.java +++ b/core/src/main/java/org/acegisecurity/util/SimpleMethodInvocation.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +28,12 @@ import java.lang.reflect.Method; * @version $Id$ */ public class SimpleMethodInvocation implements MethodInvocation { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Method method; private Object[] arguments; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SimpleMethodInvocation(Method method, Object[] arguments) { this.method = method; @@ -42,7 +42,7 @@ public class SimpleMethodInvocation implements MethodInvocation { public SimpleMethodInvocation() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object[] getArguments() { return arguments; diff --git a/core/src/main/java/org/acegisecurity/util/StringSplitUtils.java b/core/src/main/java/org/acegisecurity/util/StringSplitUtils.java index 60792e8dbe..bb96d67a05 100644 --- a/core/src/main/java/org/acegisecurity/util/StringSplitUtils.java +++ b/core/src/main/java/org/acegisecurity/util/StringSplitUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,32 +29,26 @@ import java.util.Map; * @version $Id$ */ public class StringSplitUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Splits a String at the first instance of the delimiter. - * - *

- * Does not include the delimiter in the response. - *

+ * Splits a String at the first instance of the delimiter.

Does not include the delimiter in + * the response.

* * @param toSplit the string to split * @param delimiter to split the string up with * - * @return a two element array with index 0 being before the delimiter, and - * index 1 being after the delimiter (neither element includes the - * delimiter) + * @return a two element array with index 0 being before the delimiter, and index 1 being after the delimiter + * (neither element includes the delimiter) * * @throws IllegalArgumentException if an argument was invalid */ public static String[] split(String toSplit, String delimiter) { Assert.hasLength(toSplit, "Cannot split a null or empty string"); - Assert.hasLength(delimiter, - "Cannot use a null or empty delimiter to split a string"); + Assert.hasLength(delimiter, "Cannot use a null or empty delimiter to split a string"); if (delimiter.length() != 1) { - throw new IllegalArgumentException( - "Delimiter can only be one character in length"); + throw new IllegalArgumentException("Delimiter can only be one character in length"); } int offset = toSplit.indexOf(delimiter); @@ -70,29 +64,20 @@ public class StringSplitUtils { } /** - * Takes an array of Strings, and for each element removes any - * instances of removeCharacter, and splits the element based - * on the delimiter. A Map is then generated, - * with the left of the delimiter providing the key, and the right of the - * delimiter providing the value. - * - *

- * Will trim both the key and value before adding to the Map. - *

+ * Takes an array of Strings, and for each element removes any instances of + * removeCharacter, and splits the element based on the delimiter. A Map is + * then generated, with the left of the delimiter providing the key, and the right of the delimiter providing the + * value.

Will trim both the key and value before adding to the Map.

* * @param array the array to process - * @param delimiter to split each element using (typically the equals - * symbol) - * @param removeCharacters one or more characters to remove from each - * element prior to attempting the split operation (typically the - * quotation mark symbol) or null if no removal should - * occur + * @param delimiter to split each element using (typically the equals symbol) + * @param removeCharacters one or more characters to remove from each element prior to attempting the split + * operation (typically the quotation mark symbol) or null if no removal should occur * - * @return a Map representing the array contents, or - * null if the array to process was null or empty + * @return a Map representing the array contents, or null if the array to process was + * null or empty */ - public static Map splitEachArrayElementAndCreateMap(String[] array, - String delimiter, String removeCharacters) { + public static Map splitEachArrayElementAndCreateMap(String[] array, String delimiter, String removeCharacters) { if ((array == null) || (array.length == 0)) { return null; } @@ -114,8 +99,7 @@ public class StringSplitUtils { continue; } - map.put(splitThisArrayElement[0].trim(), - splitThisArrayElement[1].trim()); + map.put(splitThisArrayElement[0].trim(), splitThisArrayElement[1].trim()); } return map; diff --git a/core/src/main/java/org/acegisecurity/util/UrlUtils.java b/core/src/main/java/org/acegisecurity/util/UrlUtils.java index ef9cbe38f0..d910d5653b 100644 --- a/core/src/main/java/org/acegisecurity/util/UrlUtils.java +++ b/core/src/main/java/org/acegisecurity/util/UrlUtils.java @@ -16,32 +16,25 @@ package org.acegisecurity.util; import org.acegisecurity.intercept.web.FilterInvocation; + import org.acegisecurity.ui.savedrequest.SavedRequest; import javax.servlet.http.HttpServletRequest; /** - * Provides static methods for composing URLs. - * - *

- * Placed into a separate class for visibility, so that changes to URL - * formatting conventions will affect all users. - *

+ * Provides static methods for composing URLs.

Placed into a separate class for visibility, so that changes to + * URL formatting conventions will affect all users.

* * @author Ben Alex * @version $Id$ */ public class UrlUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the full URL the client used to make the request. - * - *

- * Note that the server port will not be shown if it is the default server - * port for HTTP or HTTPS (ie 80 and 443 respectively). - *

+ * Obtains the full URL the client used to make the request.

Note that the server port will not be shown + * if it is the default server port for HTTP or HTTPS (ie 80 and 443 respectively).

* * @param scheme DOCUMENT ME! * @param serverName DOCUMENT ME! @@ -55,10 +48,8 @@ public class UrlUtils { * * @return the full URL */ - private static String buildFullRequestUrl(String scheme, String serverName, - int serverPort, String contextPath, String requestUrl, - String servletPath, String requestURI, String pathInfo, - String queryString) { + private static String buildFullRequestUrl(String scheme, String serverName, int serverPort, String contextPath, + String requestUrl, String servletPath, String requestURI, String pathInfo, String queryString) { boolean includePort = true; if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) { @@ -69,10 +60,8 @@ public class UrlUtils { includePort = false; } - return scheme + "://" + serverName - + ((includePort) ? (":" + serverPort) : "") + contextPath - + buildRequestUrl(servletPath, requestURI, contextPath, pathInfo, - queryString); + return scheme + "://" + serverName + ((includePort) ? (":" + serverPort) : "") + contextPath + + buildRequestUrl(servletPath, requestURI, contextPath, pathInfo, queryString); } /** @@ -86,8 +75,7 @@ public class UrlUtils { * * @return the URL, excluding any server name, context path or servlet path */ - private static String buildRequestUrl(String servletPath, - String requestURI, String contextPath, String pathInfo, + private static String buildRequestUrl(String servletPath, String requestURI, String contextPath, String pathInfo, String queryString) { String uri = servletPath; @@ -96,35 +84,30 @@ public class UrlUtils { uri = uri.substring(contextPath.length()); } - return uri + ((pathInfo == null) ? "" : pathInfo) - + ((queryString == null) ? "" : ("?" + queryString)); + return uri + ((pathInfo == null) ? "" : pathInfo) + ((queryString == null) ? "" : ("?" + queryString)); } public static String getFullRequestUrl(FilterInvocation fi) { HttpServletRequest r = fi.getHttpRequest(); - return buildFullRequestUrl(r.getScheme(), r.getServerName(), - r.getServerPort(), r.getContextPath(), - r.getRequestURL().toString(), r.getServletPath(), - r.getRequestURI(), r.getPathInfo(), r.getQueryString()); + return buildFullRequestUrl(r.getScheme(), r.getServerName(), r.getServerPort(), r.getContextPath(), + r.getRequestURL().toString(), r.getServletPath(), r.getRequestURI(), r.getPathInfo(), r.getQueryString()); } public static String getFullRequestUrl(SavedRequest sr) { - return buildFullRequestUrl(sr.getScheme(), sr.getServerName(), - sr.getServerPort(), sr.getContextPath(), sr.getRequestURL(), - sr.getServletPath(), sr.getRequestURI(), sr.getPathInfo(), - sr.getQueryString()); + return buildFullRequestUrl(sr.getScheme(), sr.getServerName(), sr.getServerPort(), sr.getContextPath(), + sr.getRequestURL(), sr.getServletPath(), sr.getRequestURI(), sr.getPathInfo(), sr.getQueryString()); } public static String getRequestUrl(FilterInvocation fi) { HttpServletRequest r = fi.getHttpRequest(); - return buildRequestUrl(r.getServletPath(), r.getRequestURI(), - r.getContextPath(), r.getPathInfo(), r.getQueryString()); + return buildRequestUrl(r.getServletPath(), r.getRequestURI(), r.getContextPath(), r.getPathInfo(), + r.getQueryString()); } public static String getRequestUrl(SavedRequest sr) { - return buildRequestUrl(sr.getServletPath(), sr.getRequestURI(), - sr.getContextPath(), sr.getPathInfo(), sr.getQueryString()); + return buildRequestUrl(sr.getServletPath(), sr.getRequestURI(), sr.getContextPath(), sr.getPathInfo(), + sr.getQueryString()); } } diff --git a/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java b/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java index 16bd3147f6..2854291c23 100644 --- a/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java +++ b/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,48 +15,53 @@ package org.acegisecurity.vote; -import java.util.Iterator; -import java.util.List; - import org.acegisecurity.AccessDecisionManager; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.ConfigAttribute; + import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; + import org.springframework.util.Assert; +import java.util.Iterator; +import java.util.List; + /** - * Abstract implementation of {@link AccessDecisionManager}. - * - *

- * Handles configuration of a bean context defined list of {@link - * AccessDecisionVoter}s and the access control behaviour if all voters - * abstain from voting (defaults to deny access). - *

+ * Abstract implementation of {@link AccessDecisionManager}.

Handles configuration of a bean context defined list + * of {@link AccessDecisionVoter}s and the access control behaviour if all voters abstain from voting (defaults to + * deny access).

*/ -public abstract class AbstractAccessDecisionManager - implements AccessDecisionManager, InitializingBean, MessageSourceAware { - //~ Instance fields ======================================================== +public abstract class AbstractAccessDecisionManager implements AccessDecisionManager, InitializingBean, + MessageSourceAware { + //~ Instance fields ================================================================================================ private List decisionVoters; protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private boolean allowIfAllAbstainDecisions = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { checkIfValidList(this.decisionVoters); Assert.notNull(this.messages, "A message source must be set"); } + protected final void checkAllowIfAllAbstainDecisions() { + if (!this.isAllowIfAllAbstainDecisions()) { + throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", + "Access is denied")); + } + } + private void checkIfValidList(List listToCheck) { if ((listToCheck == null) || (listToCheck.size() == 0)) { - throw new IllegalArgumentException( - "A list of AccessDecisionVoters is required"); + throw new IllegalArgumentException("A list of AccessDecisionVoters is required"); } } @@ -68,8 +73,7 @@ public abstract class AbstractAccessDecisionManager return allowIfAllAbstainDecisions; } - public void setAllowIfAllAbstainDecisions( - boolean allowIfAllAbstainDecisions) { + public void setAllowIfAllAbstainDecisions(boolean allowIfAllAbstainDecisions) { this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions; } @@ -86,8 +90,7 @@ public abstract class AbstractAccessDecisionManager AccessDecisionVoter attemptToCast = (AccessDecisionVoter) currentObject; } catch (ClassCastException cce) { - throw new IllegalArgumentException("AccessDecisionVoter " - + currentObject.getClass().getName() + throw new IllegalArgumentException("AccessDecisionVoter " + currentObject.getClass().getName() + " must implement AccessDecisionVoter"); } } @@ -114,13 +117,8 @@ public abstract class AbstractAccessDecisionManager } /** - * Iterates through all AccessDecisionVoters and ensures each - * can support the presented class. - * - *

- * If one or more voters cannot support the presented class, - * false is returned. - *

+ * Iterates through all AccessDecisionVoters and ensures each can support the presented class.

If + * one or more voters cannot support the presented class, false is returned.

* * @param clazz DOCUMENT ME! * @@ -139,12 +137,4 @@ public abstract class AbstractAccessDecisionManager return true; } - - protected final void checkAllowIfAllAbstainDecisions() { - if (!this.isAllowIfAllAbstainDecisions()) { - throw new AccessDeniedException(messages.getMessage( - "AbstractAccessDecisionManager.accessDenied", - "Access is denied")); - } - } } diff --git a/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java b/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java index 25fc8f964b..751299288c 100644 --- a/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java @@ -30,98 +30,52 @@ import org.springframework.util.Assert; /** - *

- * Given a domain object instance passed as a method argument, ensures the - * principal has appropriate permission as defined by the {@link AclManager}. - *

- * - *

- * The AclManager is used to retrieve the access control list - * (ACL) permissions associated with a domain object instance for the current - * Authentication object. This class is designed to process - * {@link AclEntry}s that are subclasses of {@link - * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are - * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}. - *

- * - *

- * The voter will vote if any {@link ConfigAttribute#getAttribute()} matches - * the {@link #processConfigAttribute}. The provider will then locate the - * first method argument of type {@link #processDomainObjectClass}. Assuming - * that method argument is non-null, the provider will then lookup the ACLs - * from the AclManager and ensure the principal is {@link - * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least - * one of the {@link #requirePermission}s. - *

- * - *

- * If the method argument is null, the voter will abstain from - * voting. If the method argument could not be found, an {@link - * org.acegisecurity.AuthorizationServiceException} will be thrown. - *

- * - *

- * In practical terms users will typically setup a number of - * BasicAclEntryVoters. Each will have a different {@link - * #processDomainObjectClass}, {@link #processConfigAttribute} and {@link - * #requirePermission} combination. For example, a small application might - * employ the following instances of BasicAclEntryVoter: - * - *

    - *
  • - * Process domain object class BankAccount, configuration - * attribute VOTE_ACL_BANK_ACCONT_READ, require permission - * SimpleAclEntry.READ - *
  • - *
  • - * Process domain object class BankAccount, configuration - * attribute VOTE_ACL_BANK_ACCOUNT_WRITE, require permission list - * SimpleAclEntry.WRITE and SimpleAclEntry.CREATE - * (allowing the principal to have either of these two permissions - *
  • - *
  • - * Process domain object class Customer, configuration attribute - * VOTE_ACL_CUSTOMER_READ, require permission - * SimpleAclEntry.READ - *
  • - *
  • - * Process domain object class Customer, configuration attribute - * VOTE_ACL_CUSTOMER_WRITE, require permission list - * SimpleAclEntry.WRITE and SimpleAclEntry.CREATE - *
  • - *
- * - * Alternatively, you could have used a common superclass or interface for the - * {@link #processDomainObjectClass} if both BankAccount and - * Customer had common parents. - *

- * - *

- * If the principal does not have sufficient permissions, the voter will vote - * to deny access. - *

- * - *

- * The AclManager is allowed to return any implementations of - * AclEntry it wishes. However, this provider will only be able - * to validate against AbstractBasicAclEntrys, and thus a vote to - * deny access will be made if no AclEntry is of type - * AbstractBasicAclEntry. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Given a domain object instance passed as a method argument, ensures the principal has appropriate permission + * as defined by the {@link AclManager}.

+ *

The AclManager is used to retrieve the access control list (ACL) permissions associated with a + * domain object instance for the current Authentication object. This class is designed to process {@link + * AclEntry}s that are subclasses of {@link org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are + * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.

+ *

The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link + * #processConfigAttribute}. The provider will then locate the first method argument of type {@link + * #processDomainObjectClass}. Assuming that method argument is non-null, the provider will then lookup the ACLs from + * the AclManager and ensure the principal is {@link + * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link #requirePermission}s.

+ *

If the method argument is null, the voter will abstain from voting. If the method argument + * could not be found, an {@link org.acegisecurity.AuthorizationServiceException} will be thrown.

+ *

In practical terms users will typically setup a number of BasicAclEntryVoters. Each will have a + * different {@link #processDomainObjectClass}, {@link #processConfigAttribute} and {@link #requirePermission} + * combination. For example, a small application might employ the following instances of + * BasicAclEntryVoter: + *

    + *
  • Process domain object class BankAccount, configuration attribute + * VOTE_ACL_BANK_ACCONT_READ, require permission SimpleAclEntry.READ
  • + *
  • Process domain object class BankAccount, configuration attribute + * VOTE_ACL_BANK_ACCOUNT_WRITE, require permission list SimpleAclEntry.WRITE and + * SimpleAclEntry.CREATE (allowing the principal to have either of these two permissions
  • + *
  • Process domain object class Customer, configuration attribute + * VOTE_ACL_CUSTOMER_READ, require permission SimpleAclEntry.READ
  • + *
  • Process domain object class Customer, configuration attribute + * VOTE_ACL_CUSTOMER_WRITE, require permission list SimpleAclEntry.WRITE and + * SimpleAclEntry.CREATE
  • + *
+ * Alternatively, you could have used a common superclass or interface for the {@link #processDomainObjectClass} + * if both BankAccount and Customer had common parents.

+ *

If the principal does not have sufficient permissions, the voter will vote to deny access.

+ *

The AclManager is allowed to return any implementations of AclEntry it wishes. + * However, this provider will only be able to validate against AbstractBasicAclEntrys, and thus a vote + * to deny access will be made if no AclEntry is of type AbstractBasicAclEntry.

+ *

All comparisons and prefixes are case sensitive.

* * @author Ben Alex * @version $Id$ */ public abstract class AbstractAclVoter implements AccessDecisionVoter { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Class processDomainObjectClass; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected Object getDomainObjectInstance(Object secureObject) { Object[] args; @@ -133,8 +87,7 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter { args = invocation.getArguments(); } else { JoinPoint jp = (JoinPoint) secureObject; - params = ((CodeSignature) jp.getStaticPart().getSignature()) - .getParameterTypes(); + params = ((CodeSignature) jp.getStaticPart().getSignature()).getParameterTypes(); args = jp.getArgs(); } @@ -144,9 +97,8 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter { } } - throw new AuthorizationServiceException("Secure object: " - + secureObject + " did not provide any argument of type: " - + processDomainObjectClass); + throw new AuthorizationServiceException("Secure object: " + secureObject + + " did not provide any argument of type: " + processDomainObjectClass); } public Class getProcessDomainObjectClass() { @@ -154,20 +106,17 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter { } public void setProcessDomainObjectClass(Class processDomainObjectClass) { - Assert.notNull(processDomainObjectClass, - "processDomainObjectClass cannot be set to null"); + Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null"); this.processDomainObjectClass = processDomainObjectClass; } /** - * This implementation supports only - * MethodSecurityInterceptor, because it queries the + * This implementation supports only MethodSecurityInterceptor, because it queries the * presented MethodInvocation. * * @param clazz the secure object * - * @return true if the secure object is - * MethodInvocation, false otherwise + * @return true if the secure object is MethodInvocation, false otherwise */ public boolean supports(Class clazz) { if (MethodInvocation.class.isAssignableFrom(clazz)) { diff --git a/core/src/main/java/org/acegisecurity/vote/AccessDecisionVoter.java b/core/src/main/java/org/acegisecurity/vote/AccessDecisionVoter.java index 3646cc3f7c..3e32e37d2c 100644 --- a/core/src/main/java/org/acegisecurity/vote/AccessDecisionVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/AccessDecisionVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,37 +33,30 @@ import org.acegisecurity.ConfigAttributeDefinition; * @version $Id$ */ public interface AccessDecisionVoter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final int ACCESS_GRANTED = 1; public static final int ACCESS_ABSTAIN = 0; public static final int ACCESS_DENIED = -1; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Indicates whether this AccessDecisionVoter is able to vote - * on the passed ConfigAttribute. - * - *

- * This allows the AbstractSecurityInterceptor to check every - * configuration attribute can be consumed by the configured - * AccessDecisionManager and/or RunAsManager - * and/or AfterInvocationManager. - *

- * - * @param attribute a configuration attribute that has been configured - * against the AbstractSecurityInterceptor + * Indicates whether this AccessDecisionVoter is able to vote on the passed + * ConfigAttribute.

This allows the AbstractSecurityInterceptor to check every + * configuration attribute can be consumed by the configured AccessDecisionManager and/or + * RunAsManager and/or AfterInvocationManager.

* - * @return true if this AccessDecisionVoter can support the - * passed configuration attribute + * @param attribute a configuration attribute that has been configured against the + * AbstractSecurityInterceptor + * + * @return true if this AccessDecisionVoter can support the passed configuration attribute */ public boolean supports(ConfigAttribute attribute); /** - * Indicates whether the AccessDecisionVoter implementation is - * able to provide access control votes for the indicated secured object - * type. + * Indicates whether the AccessDecisionVoter implementation is able to provide access control + * votes for the indicated secured object type. * * @param clazz the class that is being queried * @@ -72,42 +65,25 @@ public interface AccessDecisionVoter { public boolean supports(Class clazz); /** - * Indicates whether or not access is granted. - * - *

- * The decision must be affirmative (ACCESS_GRANTED), negative - * (ACCESS_DENIED) or the AccessDecisionVoter - * can abstain (ACCESS_ABSTAIN) from voting. Under no - * circumstances should implementing classes return any other value. If a - * weighting of results is desired, this should be handled in a custom - * {@link org.acegisecurity.AccessDecisionManager} instead. - *

- * - *

- * Unless an AccessDecisionVoter is specifically intended to - * vote on an access control decision due to a passed method invocation or - * configuration attribute parameter, it must return - * ACCESS_ABSTAIN. This prevents the coordinating - * AccessDecisionManager from counting votes from those - * AccessDecisionVoters without a legitimate interest in the - * access control decision. - *

- * - *

- * Whilst the method invocation is passed as a parameter to maximise - * flexibility in making access control decisions, implementing classes - * must never modify the behaviour of the method invocation (such as - * calling MethodInvocation.proceed()). - *

+ * Indicates whether or not access is granted.

The decision must be affirmative + * (ACCESS_GRANTED), negative (ACCESS_DENIED) or the AccessDecisionVoter + * can abstain (ACCESS_ABSTAIN) from voting. Under no circumstances should implementing classes + * return any other value. If a weighting of results is desired, this should be handled in a custom {@link + * org.acegisecurity.AccessDecisionManager} instead.

+ *

Unless an AccessDecisionVoter is specifically intended to vote on an access control + * decision due to a passed method invocation or configuration attribute parameter, it must return + * ACCESS_ABSTAIN. This prevents the coordinating AccessDecisionManager from counting + * votes from those AccessDecisionVoters without a legitimate interest in the access control + * decision.

+ *

Whilst the method invocation is passed as a parameter to maximise flexibility in making access + * control decisions, implementing classes must never modify the behaviour of the method invocation (such as + * calling MethodInvocation.proceed()).

* * @param authentication the caller invoking the method * @param object the secured object - * @param config the configuration attributes associated with the method - * being invoked + * @param config the configuration attributes associated with the method being invoked * - * @return either {@link #ACCESS_GRANTED}, {@link #ACCESS_ABSTAIN} or - * {@link #ACCESS_DENIED} + * @return either {@link #ACCESS_GRANTED}, {@link #ACCESS_ABSTAIN} or {@link #ACCESS_DENIED} */ - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config); + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config); } diff --git a/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java b/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java index c113632f7c..d32cdaf961 100644 --- a/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java +++ b/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,42 +15,34 @@ package org.acegisecurity.vote; -import java.util.Iterator; - import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.acegisecurity.ConfigAttributeDefinition; +import java.util.Iterator; + /** - * Simple concrete implementation of {@link - * org.acegisecurity.AccessDecisionManager} that grants access if any + * Simple concrete implementation of {@link org.acegisecurity.AccessDecisionManager} that grants access if any * AccessDecisionVoter returns an affirmative response. */ public class AffirmativeBased extends AbstractAccessDecisionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This concrete implementation simply polls all configured {@link - * AccessDecisionVoter}s and grants access if any - * AccessDecisionVoter voted affirmatively. Denies access - * only if there was a deny vote AND no affirmative votes. - * - *

- * If every AccessDecisionVoter abstained from voting, the - * decision will be based on the {@link #isAllowIfAllAbstainDecisions()} - * property (defaults to false). - *

+ * This concrete implementation simply polls all configured {@link AccessDecisionVoter}s and grants access + * if any AccessDecisionVoter voted affirmatively. Denies access only if there was a deny vote AND no + * affirmative votes.

If every AccessDecisionVoter abstained from voting, the decision will + * be based on the {@link #isAllowIfAllAbstainDecisions()} property (defaults to false).

* * @param authentication the caller invoking the method * @param object the secured object - * @param config the configuration attributes associated with the method - * being invoked + * @param config the configuration attributes associated with the method being invoked * * @throws AccessDeniedException if access is denied */ - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) + throws AccessDeniedException { Iterator iter = this.getDecisionVoters().iterator(); int deny = 0; @@ -73,8 +65,7 @@ public class AffirmativeBased extends AbstractAccessDecisionManager { } if (deny > 0) { - throw new AccessDeniedException(messages.getMessage( - "AbstractAccessDecisionManager.accessDenied", + throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied")); } diff --git a/core/src/main/java/org/acegisecurity/vote/AuthenticatedVoter.java b/core/src/main/java/org/acegisecurity/vote/AuthenticatedVoter.java index 78432dc80e..2e16b0d6de 100644 --- a/core/src/main/java/org/acegisecurity/vote/AuthenticatedVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/AuthenticatedVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,51 +27,40 @@ import java.util.Iterator; /** - *

- * Votes if a {@link ConfigAttribute#getAttribute()} of - * IS_AUTHENTICATED_FULLY or - * IS_AUTHENTICATED_REMEMBERED or - * IS_AUTHENTICATED_ANONYMOUSLY is present. This list is in order - * of most strict checking to least strict checking. - *

- * - *

- * The current Authentication will be inspected to determine if - * the principal has a particular level of authentication. The "FULLY" - * authenticated option means the user is authenticated fully (ie {@link - * org.acegisecurity.AuthenticationTrustResolver#isAnonymous(Authentication)} - * is false and {@link - * org.acegisecurity.AuthenticationTrustResolver#isRememberMe(Authentication)} - * is false. The "REMEMBERED" will grant access if the principal was either - * authenticated via remember-me OR is fully authenticated. The "ANONYMOUSLY" - * will grant access if the principal was authenticated via remember-me, OR - * anonymously, OR via full authentication. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Votes if a {@link ConfigAttribute#getAttribute()} of IS_AUTHENTICATED_FULLY or + * IS_AUTHENTICATED_REMEMBERED or IS_AUTHENTICATED_ANONYMOUSLY is present. This list is in + * order of most strict checking to least strict checking.

+ *

The current Authentication will be inspected to determine if the principal has a particular + * level of authentication. The "FULLY" authenticated option means the user is authenticated fully (ie {@link + * org.acegisecurity.AuthenticationTrustResolver#isAnonymous(Authentication)} is false and {@link + * org.acegisecurity.AuthenticationTrustResolver#isRememberMe(Authentication)} is false. The "REMEMBERED" will grant + * access if the principal was either authenticated via remember-me OR is fully authenticated. The "ANONYMOUSLY" will + * grant access if the principal was authenticated via remember-me, OR anonymously, OR via full authentication.

+ *

All comparisons and prefixes are case sensitive.

* * @author Ben Alex * @version $Id$ */ public class AuthenticatedVoter implements AccessDecisionVoter { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String IS_AUTHENTICATED_FULLY = "IS_AUTHENTICATED_FULLY"; public static final String IS_AUTHENTICATED_REMEMBERED = "IS_AUTHENTICATED_REMEMBERED"; public static final String IS_AUTHENTICATED_ANONYMOUSLY = "IS_AUTHENTICATED_ANONYMOUSLY"; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setAuthenticationTrustResolver( - AuthenticationTrustResolver authenticationTrustResolver) { - Assert.notNull(authenticationTrustResolver, - "AuthenticationTrustResolver cannot be set to null"); + private boolean isFullyAuthenticated(Authentication authentication) { + return (!authenticationTrustResolver.isAnonymous(authentication) + && !authenticationTrustResolver.isRememberMe(authentication)); + } + + public void setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) { + Assert.notNull(authenticationTrustResolver, "AuthenticationTrustResolver cannot be set to null"); this.authenticationTrustResolver = authenticationTrustResolver; } @@ -87,8 +76,7 @@ public class AuthenticatedVoter implements AccessDecisionVoter { } /** - * This implementation supports any type of class, because it does not - * query the presented secure object. + * This implementation supports any type of class, because it does not query the presented secure object. * * @param clazz the secure object * @@ -98,8 +86,7 @@ public class AuthenticatedVoter implements AccessDecisionVoter { return true; } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { int result = ACCESS_ABSTAIN; Iterator iter = config.getConfigAttributes(); @@ -122,12 +109,9 @@ public class AuthenticatedVoter implements AccessDecisionVoter { } } - if (IS_AUTHENTICATED_ANONYMOUSLY.equals( - attribute.getAttribute())) { - if (authenticationTrustResolver.isAnonymous(authentication) - || isFullyAuthenticated(authentication) - || authenticationTrustResolver.isRememberMe( - authentication)) { + if (IS_AUTHENTICATED_ANONYMOUSLY.equals(attribute.getAttribute())) { + if (authenticationTrustResolver.isAnonymous(authentication) || isFullyAuthenticated(authentication) + || authenticationTrustResolver.isRememberMe(authentication)) { return ACCESS_GRANTED; } } @@ -136,9 +120,4 @@ public class AuthenticatedVoter implements AccessDecisionVoter { return result; } - - private boolean isFullyAuthenticated(Authentication authentication) { - return (!authenticationTrustResolver.isAnonymous(authentication) - && !authenticationTrustResolver.isRememberMe(authentication)); - } } diff --git a/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java b/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java index d529e2ad70..867b530a71 100644 --- a/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java @@ -38,115 +38,66 @@ import java.util.Iterator; /** - *

- * Given a domain object instance passed as a method argument, ensures the - * principal has appropriate permission as defined by the {@link AclManager}. - *

- * - *

- * The AclManager is used to retrieve the access control list - * (ACL) permissions associated with a domain object instance for the current - * Authentication object. This class is designed to process - * {@link AclEntry}s that are subclasses of {@link - * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are - * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}. - *

- * - *

- * The voter will vote if any {@link ConfigAttribute#getAttribute()} matches - * the {@link #processConfigAttribute}. The provider will then locate the - * first method argument of type {@link #processDomainObjectClass}. Assuming - * that method argument is non-null, the provider will then lookup the ACLs - * from the AclManager and ensure the principal is {@link - * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least - * one of the {@link #requirePermission}s. - *

- * - *

- * If the method argument is null, the voter will abstain from - * voting. If the method argument could not be found, an {@link - * org.acegisecurity.AuthorizationServiceException} will be thrown. - *

- * - *

- * In practical terms users will typically setup a number of - * BasicAclEntryVoters. Each will have a different {@link - * #processDomainObjectClass}, {@link #processConfigAttribute} and {@link - * #requirePermission} combination. For example, a small application might - * employ the following instances of BasicAclEntryVoter: - * - *

    - *
  • - * Process domain object class BankAccount, configuration - * attribute VOTE_ACL_BANK_ACCONT_READ, require permission - * SimpleAclEntry.READ - *
  • - *
  • - * Process domain object class BankAccount, configuration - * attribute VOTE_ACL_BANK_ACCOUNT_WRITE, require permission list - * SimpleAclEntry.WRITE and SimpleAclEntry.CREATE - * (allowing the principal to have either of these two permissions - *
  • - *
  • - * Process domain object class Customer, configuration attribute - * VOTE_ACL_CUSTOMER_READ, require permission - * SimpleAclEntry.READ - *
  • - *
  • - * Process domain object class Customer, configuration attribute - * VOTE_ACL_CUSTOMER_WRITE, require permission list - * SimpleAclEntry.WRITE and SimpleAclEntry.CREATE - *
  • - *
- * - * Alternatively, you could have used a common superclass or interface for the - * {@link #processDomainObjectClass} if both BankAccount and - * Customer had common parents. - *

- * - *

- * If the principal does not have sufficient permissions, the voter will vote - * to deny access. - *

- * - *

- * The AclManager is allowed to return any implementations of - * AclEntry it wishes. However, this provider will only be able - * to validate against AbstractBasicAclEntrys, and thus a vote to - * deny access will be made if no AclEntry is of type - * AbstractBasicAclEntry. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Given a domain object instance passed as a method argument, ensures the principal has appropriate permission + * as defined by the {@link AclManager}.

+ *

The AclManager is used to retrieve the access control list (ACL) permissions associated with a + * domain object instance for the current Authentication object. This class is designed to process {@link + * AclEntry}s that are subclasses of {@link org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are + * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.

+ *

The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link + * #processConfigAttribute}. The provider will then locate the first method argument of type {@link + * #processDomainObjectClass}. Assuming that method argument is non-null, the provider will then lookup the ACLs from + * the AclManager and ensure the principal is {@link + * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link #requirePermission}s.

+ *

If the method argument is null, the voter will abstain from voting. If the method argument + * could not be found, an {@link org.acegisecurity.AuthorizationServiceException} will be thrown.

+ *

In practical terms users will typically setup a number of BasicAclEntryVoters. Each will have a + * different {@link #processDomainObjectClass}, {@link #processConfigAttribute} and {@link #requirePermission} + * combination. For example, a small application might employ the following instances of + * BasicAclEntryVoter: + *

    + *
  • Process domain object class BankAccount, configuration attribute + * VOTE_ACL_BANK_ACCONT_READ, require permission SimpleAclEntry.READ
  • + *
  • Process domain object class BankAccount, configuration attribute + * VOTE_ACL_BANK_ACCOUNT_WRITE, require permission list SimpleAclEntry.WRITE and + * SimpleAclEntry.CREATE (allowing the principal to have either of these two permissions
  • + *
  • Process domain object class Customer, configuration attribute + * VOTE_ACL_CUSTOMER_READ, require permission SimpleAclEntry.READ
  • + *
  • Process domain object class Customer, configuration attribute + * VOTE_ACL_CUSTOMER_WRITE, require permission list SimpleAclEntry.WRITE and + * SimpleAclEntry.CREATE
  • + *
+ * Alternatively, you could have used a common superclass or interface for the {@link #processDomainObjectClass} + * if both BankAccount and Customer had common parents.

+ *

If the principal does not have sufficient permissions, the voter will vote to deny access.

+ *

The AclManager is allowed to return any implementations of AclEntry it wishes. + * However, this provider will only be able to validate against AbstractBasicAclEntrys, and thus a vote + * to deny access will be made if no AclEntry is of type AbstractBasicAclEntry.

+ *

All comparisons and prefixes are case sensitive.

* * @author Ben Alex * @version $Id$ */ -public class BasicAclEntryVoter extends AbstractAclVoter - implements InitializingBean { - //~ Static fields/initializers ============================================= +public class BasicAclEntryVoter extends AbstractAclVoter implements InitializingBean { + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(BasicAclEntryVoter.class); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclManager aclManager; private String internalMethod; private String processConfigAttribute; private int[] requirePermission; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(processConfigAttribute, - "A processConfigAttribute is mandatory"); + Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory"); Assert.notNull(aclManager, "An aclManager is mandatory"); if ((requirePermission == null) || (requirePermission.length == 0)) { - throw new IllegalArgumentException( - "One or more requirePermission entries is mandatory"); + throw new IllegalArgumentException("One or more requirePermission entries is mandatory"); } } @@ -155,17 +106,14 @@ public class BasicAclEntryVoter extends AbstractAclVoter } /** - * Optionally specifies a method of the domain object that will be used to - * obtain a contained domain object. That contained domain object will be - * used for the ACL evaluation. This is useful if a domain object contains - * a parent that an ACL evaluation should be targeted for, instead of the - * child domain object (which perhaps is being created and as such does - * not yet have any ACL permissions) + * Optionally specifies a method of the domain object that will be used to obtain a contained domain + * object. That contained domain object will be used for the ACL evaluation. This is useful if a domain object + * contains a parent that an ACL evaluation should be targeted for, instead of the child domain object (which + * perhaps is being created and as such does not yet have any ACL permissions) * - * @return null to use the domain object, or the name of a - * method (that requires no arguments) that should be invoked to - * obtain an Object which will be the domain object - * used for ACL evaluation + * @return null to use the domain object, or the name of a method (that requires no arguments) that + * should be invoked to obtain an Object which will be the domain object used for ACL + * evaluation */ public String getInternalMethod() { return internalMethod; @@ -196,16 +144,14 @@ public class BasicAclEntryVoter extends AbstractAclVoter } public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) - && attribute.getAttribute().startsWith(getProcessConfigAttribute())) { + if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getProcessConfigAttribute())) { return true; } else { return false; } } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { @@ -229,55 +175,43 @@ public class BasicAclEntryVoter extends AbstractAclVoter if ((internalMethod != null) && !"".equals(internalMethod)) { try { Class clazz = domainObject.getClass(); - Method method = clazz.getMethod(internalMethod, - new Class[] {}); - domainObject = method.invoke(domainObject, - new Object[] {}); + Method method = clazz.getMethod(internalMethod, new Class[] {}); + domainObject = method.invoke(domainObject, new Object[] {}); } catch (NoSuchMethodException nsme) { - throw new AuthorizationServiceException( - "Object of class '" + domainObject.getClass() - + "' does not provide the requested internalMethod: " - + internalMethod); + throw new AuthorizationServiceException("Object of class '" + domainObject.getClass() + + "' does not provide the requested internalMethod: " + internalMethod); } catch (IllegalAccessException iae) { if (logger.isDebugEnabled()) { logger.debug("IllegalAccessException", iae); if (iae.getCause() != null) { - logger.debug("Cause: " - + iae.getCause().getMessage(), - iae.getCause()); + logger.debug("Cause: " + iae.getCause().getMessage(), iae.getCause()); } } - throw new AuthorizationServiceException( - "Problem invoking internalMethod: " - + internalMethod + " for object: " + domainObject); + throw new AuthorizationServiceException("Problem invoking internalMethod: " + internalMethod + + " for object: " + domainObject); } catch (InvocationTargetException ite) { if (logger.isDebugEnabled()) { logger.debug("InvocationTargetException", ite); if (ite.getCause() != null) { - logger.debug("Cause: " - + ite.getCause().getMessage(), - ite.getCause()); + logger.debug("Cause: " + ite.getCause().getMessage(), ite.getCause()); } } - throw new AuthorizationServiceException( - "Problem invoking internalMethod: " - + internalMethod + " for object: " + domainObject); + throw new AuthorizationServiceException("Problem invoking internalMethod: " + internalMethod + + " for object: " + domainObject); } } // Obtain the ACLs applicable to the domain object - AclEntry[] acls = aclManager.getAcls(domainObject, - authentication); + AclEntry[] acls = aclManager.getAcls(domainObject, authentication); // If principal has no permissions for domain object, deny if ((acls == null) || (acls.length == 0)) { if (logger.isDebugEnabled()) { - logger.debug( - "Voting to deny access - no ACLs returned for this principal"); + logger.debug("Voting to deny access - no ACLs returned for this principal"); } return AccessDecisionVoter.ACCESS_DENIED; diff --git a/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java b/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java index 333101919b..c8c821ab9e 100644 --- a/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java +++ b/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,51 +15,40 @@ package org.acegisecurity.vote; -import java.util.Iterator; - import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.acegisecurity.ConfigAttributeDefinition; +import java.util.Iterator; + /** - * Simple concrete implementation of {@link - * org.acegisecurity.AccessDecisionManager} that uses a consensus-based + * Simple concrete implementation of {@link org.acegisecurity.AccessDecisionManager} that uses a consensus-based * approach. */ public class ConsensusBased extends AbstractAccessDecisionManager { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean allowIfEqualGrantedDeniedDecisions = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This concrete implementation simply polls all configured {@link - * AccessDecisionVoter}s and upon completion determines the consensus of - * granted vs denied responses. - * - *

- * If there were an equal number of grant and deny votes, the decision will - * be based on the {@link #isAllowIfEqualGrantedDeniedDecisions()} - * property (defaults to true). - *

- * - *

- * If every AccessDecisionVoter abstained from voting, the - * decision will be based on the {@link #isAllowIfAllAbstainDecisions()} - * property (defaults to false). - *

+ * This concrete implementation simply polls all configured {@link AccessDecisionVoter}s and upon + * completion determines the consensus of granted vs denied responses.

If there were an equal number of + * grant and deny votes, the decision will be based on the {@link #isAllowIfEqualGrantedDeniedDecisions()} + * property (defaults to true).

+ *

If every AccessDecisionVoter abstained from voting, the decision will be based on the + * {@link #isAllowIfAllAbstainDecisions()} property (defaults to false).

* * @param authentication the caller invoking the method * @param object the secured object - * @param config the configuration attributes associated with the method - * being invoked + * @param config the configuration attributes associated with the method being invoked * * @throws AccessDeniedException if access is denied */ - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) + throws AccessDeniedException { Iterator iter = this.getDecisionVoters().iterator(); int grant = 0; int deny = 0; @@ -92,8 +81,7 @@ public class ConsensusBased extends AbstractAccessDecisionManager { } if (deny > grant) { - throw new AccessDeniedException(messages.getMessage( - "AbstractAccessDecisionManager.accessDenied", + throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied")); } @@ -101,8 +89,7 @@ public class ConsensusBased extends AbstractAccessDecisionManager { if (this.allowIfEqualGrantedDeniedDecisions) { return; } else { - throw new AccessDeniedException(messages.getMessage( - "AbstractAccessDecisionManager.accessDenied", + throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied")); } } @@ -115,8 +102,7 @@ public class ConsensusBased extends AbstractAccessDecisionManager { return allowIfEqualGrantedDeniedDecisions; } - public void setAllowIfEqualGrantedDeniedDecisions( - boolean allowIfEqualGrantedDeniedDecisions) { + public void setAllowIfEqualGrantedDeniedDecisions(boolean allowIfEqualGrantedDeniedDecisions) { this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions; } } diff --git a/core/src/main/java/org/acegisecurity/vote/RoleVoter.java b/core/src/main/java/org/acegisecurity/vote/RoleVoter.java index 7dab5de146..eedd85aebb 100644 --- a/core/src/main/java/org/acegisecurity/vote/RoleVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/RoleVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,53 +23,39 @@ import java.util.Iterator; /** - *

- * Votes if any {@link ConfigAttribute#getAttribute()} starts with a prefix - * indicating that it is a role. The default prefix string is - * ROLE_, but this may be overriden to any value. It may also be - * set to empty, which means that essentially any attribute will be voted on. - * As described further below, the effect of an empty prefix may not be quite - * desireable. - *

- * - *

- * Abstains from voting if no configuration attribute commences with the role - * prefix. Votes to grant access if there is an exact matching {@link - * org.acegisecurity.GrantedAuthority} to a ConfigAttribute - * starting with the role prefix. Votes to deny access if there is no exact - * matching GrantedAuthority to a ConfigAttribute - * starting with the role prefix. - *

- * - *

- * An empty role prefix means that the voter will vote for every - * ConfigAttribute. When there are different categories of ConfigAttributes - * used, this will not be optimal since the voter will be voting for - * attributes which do not represent roles. However, this option may be of - * some use when using preexisting role names without a prefix, and no ability - * exists to prefix them with a role prefix on reading them in, such as - * provided for example in {@link - * org.acegisecurity.userdetails.jdbc.JdbcDaoImpl}. - *

- * - *

- * All comparisons and prefixes are case sensitive. - *

+ *

Votes if any {@link ConfigAttribute#getAttribute()} starts with a prefix indicating that it is a role. The + * default prefix string is ROLE_, but this may be overriden to any value. It may also be set to empty, + * which means that essentially any attribute will be voted on. As described further below, the effect of an empty + * prefix may not be quite desireable.

+ *

Abstains from voting if no configuration attribute commences with the role prefix. Votes to grant access if + * there is an exact matching {@link org.acegisecurity.GrantedAuthority} to a ConfigAttribute starting + * with the role prefix. Votes to deny access if there is no exact matching GrantedAuthority to a + * ConfigAttribute starting with the role prefix.

+ *

An empty role prefix means that the voter will vote for every ConfigAttribute. When there are different + * categories of ConfigAttributes used, this will not be optimal since the voter will be voting for attributes which + * do not represent roles. However, this option may be of some use when using preexisting role names without a prefix, + * and no ability exists to prefix them with a role prefix on reading them in, such as provided for example in {@link + * org.acegisecurity.userdetails.jdbc.JdbcDaoImpl}.

+ *

All comparisons and prefixes are case sensitive.

* * @author Ben Alex * @author colin sampaleanu * @version $Id$ */ public class RoleVoter implements AccessDecisionVoter { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String rolePrefix = "ROLE_"; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public String getRolePrefix() { + return rolePrefix; + } /** - * Allows the default role prefix of ROLE_ to be overriden. - * May be set to an empty value, although this is usually not desireable. + * Allows the default role prefix of ROLE_ to be overriden. May be set to an empty value, + * although this is usually not desireable. * * @param rolePrefix the new prefix */ @@ -77,13 +63,8 @@ public class RoleVoter implements AccessDecisionVoter { this.rolePrefix = rolePrefix; } - public String getRolePrefix() { - return rolePrefix; - } - public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) - && attribute.getAttribute().startsWith(getRolePrefix())) { + if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getRolePrefix())) { return true; } else { return false; @@ -91,8 +72,7 @@ public class RoleVoter implements AccessDecisionVoter { } /** - * This implementation supports any type of class, because it does not - * query the presented secure object. + * This implementation supports any type of class, because it does not query the presented secure object. * * @param clazz the secure object * @@ -102,8 +82,7 @@ public class RoleVoter implements AccessDecisionVoter { return true; } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { int result = ACCESS_ABSTAIN; Iterator iter = config.getConfigAttributes(); @@ -114,10 +93,8 @@ public class RoleVoter implements AccessDecisionVoter { result = ACCESS_DENIED; // Attempt to find a matching granted authority - for (int i = 0; i < authentication.getAuthorities().length; - i++) { - if (attribute.getAttribute().equals(authentication - .getAuthorities()[i].getAuthority())) { + for (int i = 0; i < authentication.getAuthorities().length; i++) { + if (attribute.getAttribute().equals(authentication.getAuthorities()[i].getAuthority())) { return ACCESS_GRANTED; } } diff --git a/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java b/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java index 6c1a755ab8..6b723710c3 100644 --- a/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java +++ b/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java @@ -24,41 +24,29 @@ import java.util.Iterator; /** - * Simple concrete implementation of {@link - * org.acegisecurity.AccessDecisionManager} that requires all voters to + * Simple concrete implementation of {@link org.acegisecurity.AccessDecisionManager} that requires all voters to * abstain or grant access. */ public class UnanimousBased extends AbstractAccessDecisionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This concrete implementation polls all configured {@link - * AccessDecisionVoter}s for each {@link ConfigAttribute} and grants - * access if only grant votes were received. - * - *

- * Other voting implementations usually pass the entire list of {@link - * ConfigAttributeDefinition}s to the AccessDecisionVoter. - * This implementation differs in that each - * AccessDecisionVoter knows only about a single - * ConfigAttribute at a time. - *

- * - *

- * If every AccessDecisionVoter abstained from voting, the - * decision will be based on the {@link #isAllowIfAllAbstainDecisions()} - * property (defaults to false). - *

+ * This concrete implementation polls all configured {@link AccessDecisionVoter}s for each {@link + * ConfigAttribute} and grants access if only grant votes were received.

Other voting + * implementations usually pass the entire list of {@link ConfigAttributeDefinition}s to the + * AccessDecisionVoter. This implementation differs in that each AccessDecisionVoter + * knows only about a single ConfigAttribute at a time.

+ *

If every AccessDecisionVoter abstained from voting, the decision will be based on the + * {@link #isAllowIfAllAbstainDecisions()} property (defaults to false).

* * @param authentication the caller invoking the method * @param object the secured object - * @param config the configuration attributes associated with the method - * being invoked + * @param config the configuration attributes associated with the method being invoked * * @throws AccessDeniedException if access is denied */ - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) + throws AccessDeniedException { int grant = 0; int abstain = 0; @@ -81,8 +69,7 @@ public class UnanimousBased extends AbstractAccessDecisionManager { break; case AccessDecisionVoter.ACCESS_DENIED: - throw new AccessDeniedException(messages.getMessage( - "AbstractAccessDecisionManager.accessDenied", + throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied")); default: diff --git a/core/src/main/java/org/acegisecurity/wrapper/SavedRequestAwareWrapper.java b/core/src/main/java/org/acegisecurity/wrapper/SavedRequestAwareWrapper.java index 4271d950be..ddac3ed618 100644 --- a/core/src/main/java/org/acegisecurity/wrapper/SavedRequestAwareWrapper.java +++ b/core/src/main/java/org/acegisecurity/wrapper/SavedRequestAwareWrapper.java @@ -41,28 +41,18 @@ import javax.servlet.http.HttpSession; /** - * Provides request parameters, headers and cookies from either an original - * request or a saved request. - * - *

- * Note that not all request parameters in the original request are emulated by - * this wrapper. Nevertheless, the important data from the original request is - * emulated and this should prove adequate for most purposes (in particular - * standard HTTP GET and POST operations). - *

- * - *

- * Added into a request by {@link - * org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter}. - *

+ * Provides request parameters, headers and cookies from either an original request or a saved request.

Note that + * not all request parameters in the original request are emulated by this wrapper. Nevertheless, the important data + * from the original request is emulated and this should prove adequate for most purposes (in particular standard HTTP + * GET and POST operations).

+ *

Added into a request by {@link org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter}.

* * @author Andrey Grebnev * @author Ben Alex * @version $Id$ */ -public class SavedRequestAwareWrapper - extends SecurityContextHolderAwareRequestWrapper { - //~ Static fields/initializers ============================================= +public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestWrapper { + //~ Static fields/initializers ===================================================================================== protected static final Log logger = LogFactory.getLog(SavedRequestAwareWrapper.class); protected static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT"); @@ -70,29 +60,26 @@ public class SavedRequestAwareWrapper /** The default Locale if none are specified. */ protected static Locale defaultLocale = Locale.getDefault(); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected SavedRequest savedRequest = null; /** - * The set of SimpleDateFormat formats to use in getDateHeader(). Notice - * that because SimpleDateFormat is not thread-safe, we can't declare - * formats[] as a static variable. + * The set of SimpleDateFormat formats to use in getDateHeader(). Notice that because SimpleDateFormat is + * not thread-safe, we can't declare formats[] as a static variable. */ protected SimpleDateFormat[] formats = new SimpleDateFormat[3]; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public SavedRequestAwareWrapper(HttpServletRequest request, - PortResolver portResolver) { + public SavedRequestAwareWrapper(HttpServletRequest request, PortResolver portResolver) { super(request); HttpSession session = request.getSession(false); if (session == null) { if (logger.isDebugEnabled()) { - logger.debug( - "Wrapper not replaced; no session available for SavedRequest extraction"); + logger.debug("Wrapper not replaced; no session available for SavedRequest extraction"); } return; @@ -108,12 +95,9 @@ public class SavedRequestAwareWrapper savedRequest = saved; session.removeAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY); - formats[0] = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", - Locale.US); - formats[1] = new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", - Locale.US); - formats[2] = new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", - Locale.US); + formats[0] = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); + formats[1] = new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US); + formats[2] = new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US); formats[0].setTimeZone(GMT_ZONE); formats[1].setTimeZone(GMT_ZONE); @@ -125,11 +109,10 @@ public class SavedRequestAwareWrapper } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * The default behavior of this method is to return getCookies() on the - * wrapped request object. + * The default behavior of this method is to return getCookies() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -144,8 +127,8 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getDateHeader(String - * name) on the wrapped request object. + * The default behavior of this method is to return getDateHeader(String name) on the wrapped request + * object. * * @param name DOCUMENT ME! * @@ -175,8 +158,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getHeader(String name) - * on the wrapped request object. + * The default behavior of this method is to return getHeader(String name) on the wrapped request object. * * @param name DOCUMENT ME! * @@ -200,8 +182,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getHeaderNames() on the - * wrapped request object. + * The default behavior of this method is to return getHeaderNames() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -214,8 +195,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getHeaders(String name) - * on the wrapped request object. + * The default behavior of this method is to return getHeaders(String name) on the wrapped request object. * * @param name DOCUMENT ME! * @@ -230,8 +210,8 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getIntHeader(String - * name) on the wrapped request object. + * The default behavior of this method is to return getIntHeader(String name) on the wrapped request + * object. * * @param name DOCUMENT ME! * @@ -252,8 +232,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getLocale() on the - * wrapped request object. + * The default behavior of this method is to return getLocale() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -279,8 +258,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getLocales() on the - * wrapped request object. + * The default behavior of this method is to return getLocales() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -302,8 +280,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getMethod() on the - * wrapped request object. + * The default behavior of this method is to return getMethod() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -316,8 +293,8 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getParameter(String - * name) on the wrapped request object. + * The default behavior of this method is to return getParameter(String name) on the wrapped request + * object. * * @param name DOCUMENT ME! * @@ -364,8 +341,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getParameterMap() on - * the wrapped request object. + * The default behavior of this method is to return getParameterMap() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -378,8 +354,7 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return getParameterNames() on - * the wrapped request object. + * The default behavior of this method is to return getParameterNames() on the wrapped request object. * * @return DOCUMENT ME! */ @@ -392,8 +367,8 @@ public class SavedRequestAwareWrapper } /** - * The default behavior of this method is to return - * getParameterValues(String name) on the wrapped request object. + * The default behavior of this method is to return getParameterValues(String name) on the wrapped request + * object. * * @param name DOCUMENT ME! * diff --git a/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilter.java b/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilter.java index 4415133d58..96d1edce1d 100644 --- a/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilter.java +++ b/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilter.java @@ -35,44 +35,30 @@ import javax.servlet.http.HttpServletRequest; /** - * A Filter which populates the ServletRequest with a - * new request wrapper. - * - *

- * Several request wrappers are included with the framework. The simplest - * version is {@link SecurityContextHolderAwareRequestWrapper}. A more complex - * and powerful request wrapper is {@link - * org.acegisecurity.wrapper.SavedRequestAwareWrapper}. The latter is also the - * default. - *

- * - *

- * To modify the wrapper used, call {@link #setWrapperClass(Class)}. - *

- * - *

- * Any request wrapper configured for instantiation by this class must provide - * a public constructor that accepts two arguments, being a - * HttpServletRequest and a PortResolver. - *

+ * A Filter which populates the ServletRequest with a new request wrapper.

Several + * request wrappers are included with the framework. The simplest version is {@link + * SecurityContextHolderAwareRequestWrapper}. A more complex and powerful request wrapper is {@link + * org.acegisecurity.wrapper.SavedRequestAwareWrapper}. The latter is also the default.

+ *

To modify the wrapper used, call {@link #setWrapperClass(Class)}.

+ *

Any request wrapper configured for instantiation by this class must provide a public constructor that + * accepts two arguments, being a HttpServletRequest and a PortResolver.

* * @author Orlando Garcia Carmona * @author Ben Alex * @version $Id$ */ public class SecurityContextHolderAwareRequestFilter implements Filter { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Class wrapperClass = SavedRequestAwareWrapper.class; private Constructor constructor; private PortResolver portResolver = new PortResolverImpl(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void destroy() {} - public void doFilter(ServletRequest servletRequest, - ServletResponse servletResponse, FilterChain filterChain) + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; @@ -104,8 +90,7 @@ public class SecurityContextHolderAwareRequestFilter implements Filter { public void setWrapperClass(Class wrapperClass) { Assert.notNull(wrapperClass, "WrapperClass required"); - Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), - "Wrapper must be a HttpServletRequest"); + Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), "Wrapper must be a HttpServletRequest"); this.wrapperClass = wrapperClass; } } diff --git a/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapper.java b/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapper.java index 5447365091..ca4023e171 100644 --- a/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapper.java +++ b/core/src/main/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapper.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ package org.acegisecurity.wrapper; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationTrustResolver; import org.acegisecurity.AuthenticationTrustResolverImpl; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.userdetails.UserDetails; import java.security.Principal; @@ -28,34 +30,46 @@ import javax.servlet.http.HttpServletRequestWrapper; /** - * An Acegi Security-aware HttpServletRequestWrapper, which uses - * the SecurityContext-defined Authentication object - * for {@link SecurityContextHolderAwareRequestWrapper#isUserInRole(java.lang.String)} - * and {@link javax.servlet.http.HttpServletRequestWrapper#getRemoteUser()} - * responses. + * An Acegi Security-aware HttpServletRequestWrapper, which uses the + * SecurityContext-defined Authentication object for {@link + * SecurityContextHolderAwareRequestWrapper#isUserInRole(java.lang.String)} and {@link + * javax.servlet.http.HttpServletRequestWrapper#getRemoteUser()} responses. * * @author Orlando Garcia Carmona * @author Ben Alex * @version $Id$ */ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequestWrapper { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl(); - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityContextHolderAwareRequestWrapper(HttpServletRequest request) { super(request); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Returns the principal's name, as obtained from the - * SecurityContextHolder. Properly handles both - * String-based and UserDetails-based - * principals. + * Obtain the current active Authentication + * + * @return the authentication object or null + */ + private Authentication getAuthentication() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + if (!authenticationTrustResolver.isAnonymous(auth)) { + return auth; + } + + return null; + } + + /** + * Returns the principal's name, as obtained from the SecurityContextHolder. Properly handles + * both String-based and UserDetails-based principals. * * @return the username or null if unavailable */ @@ -74,29 +88,8 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest } /** - * Simple searches for an exactly matching {@link - * GrantedAuthority#getAuthority()}. - * - *

- * Will always return false if the SecurityContextHolder - * contains an Authentication with - * nullprincipal and/or - * GrantedAuthority[] objects. - *

- * - * @param role the GrantedAuthorityString - * representation to check for - * - * @return true if an exact (case sensitive) matching - * granted authority is located, false otherwise - */ - public boolean isUserInRole(String role) { - return isGranted(role); - } - - /** - * Returns the Authentication (which is a subclass of - * Principal), or null if unavailable. + * Returns the Authentication (which is a subclass of Principal), or + * null if unavailable. * * @return the Authentication, or null */ @@ -110,27 +103,10 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest return auth; } - /** - * Obtain the current active Authentication - * - * @return the authentication object or null - */ - private Authentication getAuthentication() { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); - - if (!authenticationTrustResolver.isAnonymous(auth)) { - return auth; - } - - return null; - } - private boolean isGranted(String role) { Authentication auth = getAuthentication(); - if ((auth == null) || (auth.getPrincipal() == null) - || (auth.getAuthorities() == null)) { + if ((auth == null) || (auth.getPrincipal() == null) || (auth.getAuthorities() == null)) { return false; } @@ -142,4 +118,18 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest return false; } + + /** + * Simple searches for an exactly matching {@link GrantedAuthority#getAuthority()}.

Will always return + * false if the SecurityContextHolder contains an Authentication with + * nullprincipal and/or GrantedAuthority[] objects.

+ * + * @param role the GrantedAuthorityString representation to check for + * + * @return true if an exact (case sensitive) matching granted authority is located, + * false otherwise + */ + public boolean isUserInRole(String role) { + return isGranted(role); + } } diff --git a/core/src/test/java/org/acegisecurity/AbstractAuthenticationManagerTests.java b/core/src/test/java/org/acegisecurity/AbstractAuthenticationManagerTests.java index 982f6f1872..143c632402 100644 --- a/core/src/test/java/org/acegisecurity/AbstractAuthenticationManagerTests.java +++ b/core/src/test/java/org/acegisecurity/AbstractAuthenticationManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,10 @@ package org.acegisecurity; import junit.framework.TestCase; + import org.acegisecurity.providers.TestingAuthenticationToken; + /** * Tests {@link AbstractAuthenticationManager}. * @@ -25,7 +27,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class AbstractAuthenticationManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractAuthenticationManagerTests() { super(); @@ -35,17 +37,29 @@ public class AbstractAuthenticationManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void testDetailsAreSetOnAuthenticationTokenIfNotAlreadySetByProvider() { - AuthenticationManager authMgr = createAuthenticationManager(null); - Object details = new Object(); + /** + * Creates an AuthenticationManager which will return a token with the given details object set on it. + * + * @param resultDetails DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private AuthenticationManager createAuthenticationManager(final Object resultDetails) { + return new AbstractAuthenticationManager() { + protected Authentication doAuthentication(Authentication authentication) + throws AuthenticationException { + TestingAuthenticationToken token = createAuthenticationToken(); + token.setDetails(resultDetails); - TestingAuthenticationToken request = createAuthenticationToken(); - request.setDetails(details); + return token; + } + }; + } - Authentication result = authMgr.authenticate(request); - assertEquals(details, result.getDetails()); + private TestingAuthenticationToken createAuthenticationToken() { + return new TestingAuthenticationToken("name", "password", new GrantedAuthorityImpl[0]); } public void testDetailsAreNotSetOnAuthenticationTokenIfAlreadySetByProvider() { @@ -60,23 +74,14 @@ public class AbstractAuthenticationManagerTests extends TestCase { assertEquals(resultDetails, result.getDetails()); } - private TestingAuthenticationToken createAuthenticationToken() { - return new TestingAuthenticationToken("name","password", new GrantedAuthorityImpl[0]); - } + public void testDetailsAreSetOnAuthenticationTokenIfNotAlreadySetByProvider() { + AuthenticationManager authMgr = createAuthenticationManager(null); + Object details = new Object(); - /** - * Creates an AuthenticationManager which will return a token with the given - * details object set on it. - */ - private AuthenticationManager createAuthenticationManager(final Object resultDetails) { - return new AbstractAuthenticationManager() { - protected Authentication doAuthentication(Authentication authentication) - throws AuthenticationException { - TestingAuthenticationToken token = createAuthenticationToken(); - token.setDetails(resultDetails); + TestingAuthenticationToken request = createAuthenticationToken(); + request.setDetails(details); - return token; - } - }; + Authentication result = authMgr.authenticate(request); + assertEquals(details, result.getDetails()); } } diff --git a/core/src/test/java/org/acegisecurity/AcegiMessageSourceTests.java b/core/src/test/java/org/acegisecurity/AcegiMessageSourceTests.java index 19fad76b05..792366638f 100644 --- a/core/src/test/java/org/acegisecurity/AcegiMessageSourceTests.java +++ b/core/src/test/java/org/acegisecurity/AcegiMessageSourceTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import java.util.Locale; * Tests {@link org.acegisecurity.AcegiMessageSource}. */ public class AcegiMessageSourceTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AcegiMessageSourceTests() { super(); @@ -37,7 +37,7 @@ public class AcegiMessageSourceTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AcegiMessageSourceTests.class); @@ -45,8 +45,7 @@ public class AcegiMessageSourceTests extends TestCase { public void testOperation() { AcegiMessageSource msgs = new AcegiMessageSource(); - assertEquals("Proxy tickets are rejected", - msgs.getMessage("RejectProxyTickets.reject", null, Locale.ENGLISH)); + assertEquals("Proxy tickets are rejected", msgs.getMessage("RejectProxyTickets.reject", null, Locale.ENGLISH)); } public void testReplacableLookup() { @@ -57,8 +56,8 @@ public class AcegiMessageSourceTests extends TestCase { // Cause a message to be generated MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); assertEquals("Missing mandatory digest value; received header FOOBAR", - messages.getMessage("DigestProcessingFilter.missingMandatory", - new Object[] {"FOOBAR"}, "ERROR - FAILED TO LOOKUP")); + messages.getMessage("DigestProcessingFilter.missingMandatory", new Object[] {"FOOBAR"}, + "ERROR - FAILED TO LOOKUP")); // Revert to original Locale LocaleContextHolder.setLocale(before); diff --git a/core/src/test/java/org/acegisecurity/AuthenticationTrustResolverImplTests.java b/core/src/test/java/org/acegisecurity/AuthenticationTrustResolverImplTests.java index 7591a1a129..d2c1856df0 100644 --- a/core/src/test/java/org/acegisecurity/AuthenticationTrustResolverImplTests.java +++ b/core/src/test/java/org/acegisecurity/AuthenticationTrustResolverImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken; * @version $Id$ */ public class AuthenticationTrustResolverImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthenticationTrustResolverImplTests() { super(); @@ -39,7 +39,7 @@ public class AuthenticationTrustResolverImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationTrustResolverImplTests.class); @@ -68,13 +68,11 @@ public class AuthenticationTrustResolverImplTests extends TestCase { public void testGettersSetters() { AuthenticationTrustResolverImpl trustResolver = new AuthenticationTrustResolverImpl(); - assertEquals(AnonymousAuthenticationToken.class, - trustResolver.getAnonymousClass()); + assertEquals(AnonymousAuthenticationToken.class, trustResolver.getAnonymousClass()); trustResolver.setAnonymousClass(String.class); assertEquals(String.class, trustResolver.getAnonymousClass()); - assertEquals(RememberMeAuthenticationToken.class, - trustResolver.getRememberMeClass()); + assertEquals(RememberMeAuthenticationToken.class, trustResolver.getRememberMeClass()); trustResolver.setRememberMeClass(String.class); assertEquals(String.class, trustResolver.getRememberMeClass()); } diff --git a/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java b/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java index 27a9da8d65..e071ec2afb 100644 --- a/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java +++ b/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,13 @@ import java.util.Iterator; /** - * Tests {@link ConfigAttributeEditor} and associated {@link - * ConfigAttributeDefinition}. + * Tests {@link ConfigAttributeEditor} and associated {@link ConfigAttributeDefinition}. * * @author Ben Alex * @version $Id$ */ public class ConfigAttributeEditorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ConfigAttributeEditorTests() { super(); @@ -39,22 +38,21 @@ public class ConfigAttributeEditorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ConfigAttributeEditorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperation() { ConfigAttributeEditor editor = new ConfigAttributeEditor(); editor.setAsText("HELLO,DOCTOR,NAME,YESTERDAY,TOMORROW"); - ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor - .getValue(); + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor.getValue(); Iterator iter = result.getConfigAttributes(); int position = 0; @@ -76,8 +74,7 @@ public class ConfigAttributeEditorTests extends TestCase { ConfigAttributeEditor editor = new ConfigAttributeEditor(); editor.setAsText(""); - ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor - .getValue(); + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor.getValue(); assertTrue(result == null); } @@ -128,8 +125,7 @@ public class ConfigAttributeEditorTests extends TestCase { ConfigAttributeEditor editor = new ConfigAttributeEditor(); editor.setAsText(null); - ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor - .getValue(); + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor.getValue(); assertTrue(result == null); } @@ -137,8 +133,7 @@ public class ConfigAttributeEditorTests extends TestCase { ConfigAttributeEditor editor = new ConfigAttributeEditor(); editor.setAsText(" HELLO, DOCTOR,NAME, YESTERDAY ,TOMORROW "); - ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor - .getValue(); + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor.getValue(); Iterator iter = result.getConfigAttributes(); ArrayList list = new ArrayList(); @@ -158,8 +153,7 @@ public class ConfigAttributeEditorTests extends TestCase { ConfigAttributeEditor editor = new ConfigAttributeEditor(); editor.setAsText("KOALA,KANGAROO,EMU,WOMBAT"); - ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor - .getValue(); + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor.getValue(); assertEquals("[KOALA, KANGAROO, EMU, WOMBAT]", result.toString()); } } diff --git a/core/src/test/java/org/acegisecurity/GrantedAuthorityImplTests.java b/core/src/test/java/org/acegisecurity/GrantedAuthorityImplTests.java index f374f87b28..46c5a571b8 100644 --- a/core/src/test/java/org/acegisecurity/GrantedAuthorityImplTests.java +++ b/core/src/test/java/org/acegisecurity/GrantedAuthorityImplTests.java @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class GrantedAuthorityImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public GrantedAuthorityImplTests() { super(); @@ -35,7 +35,7 @@ public class GrantedAuthorityImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(GrantedAuthorityImplTests.class); @@ -62,8 +62,7 @@ public class GrantedAuthorityImplTests extends TestCase { MockGrantedAuthorityImpl mock1 = new MockGrantedAuthorityImpl("TEST"); assertEquals(auth1, mock1); - MockGrantedAuthorityImpl mock2 = new MockGrantedAuthorityImpl( - "NOT_EQUAL"); + MockGrantedAuthorityImpl mock2 = new MockGrantedAuthorityImpl("NOT_EQUAL"); assertTrue(!auth1.equals(mock2)); Integer int1 = new Integer(222); @@ -75,7 +74,7 @@ public class GrantedAuthorityImplTests extends TestCase { assertEquals("TEST", auth.toString()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockGrantedAuthorityImpl implements GrantedAuthority { private String role; diff --git a/core/src/test/java/org/acegisecurity/ITargetObject.java b/core/src/test/java/org/acegisecurity/ITargetObject.java index ba4b7e8f0b..e3fcff7c50 100644 --- a/core/src/test/java/org/acegisecurity/ITargetObject.java +++ b/core/src/test/java/org/acegisecurity/ITargetObject.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ package org.acegisecurity; * @version $Id$ */ public interface ITargetObject { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Integer computeHashCode(String input); diff --git a/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java b/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java index d3ddea6872..d78d68d105 100644 --- a/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java +++ b/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,27 +19,25 @@ import java.util.Iterator; /** - * Grants access if the user holds any of the authorities listed in the - * configuration attributes starting with "MOCK_". + * Grants access if the user holds any of the authorities listed in the configuration attributes starting with + * "MOCK_". * * @author Ben Alex * @version $Id$ */ public class MockAccessDecisionManager implements AccessDecisionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) + throws AccessDeniedException { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { ConfigAttribute attr = (ConfigAttribute) iter.next(); if (this.supports(attr)) { - for (int i = 0; i < authentication.getAuthorities().length; - i++) { - if (attr.getAttribute().equals(authentication - .getAuthorities()[i].getAuthority())) { + for (int i = 0; i < authentication.getAuthorities().length; i++) { + if (attr.getAttribute().equals(authentication.getAuthorities()[i].getAuthority())) { return; } } diff --git a/core/src/test/java/org/acegisecurity/MockAclManager.java b/core/src/test/java/org/acegisecurity/MockAclManager.java index d75459d586..6f8d3cc7e4 100644 --- a/core/src/test/java/org/acegisecurity/MockAclManager.java +++ b/core/src/test/java/org/acegisecurity/MockAclManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,21 +20,20 @@ import org.acegisecurity.acl.AclManager; /** - * Returns the indicated collection of AclEntrys when the given - * Authentication principal is presented for the indicated domain - * Object instance. + * Returns the indicated collection of AclEntrys when the given Authentication principal + * is presented for the indicated domain Object instance. * * @author Ben Alex * @version $Id$ */ public class MockAclManager implements AclManager { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Object object; private Object principal; private AclEntry[] acls; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockAclManager(Object domainObject, Object principal, AclEntry[] acls) { this.object = domainObject; @@ -44,12 +43,10 @@ public class MockAclManager implements AclManager { private MockAclManager() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication) { - if (domainInstance.equals(object) - && authentication.getPrincipal().equals(principal)) { + public AclEntry[] getAcls(Object domainInstance, Authentication authentication) { + if (domainInstance.equals(object) && authentication.getPrincipal().equals(principal)) { return acls; } else { return null; diff --git a/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java b/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java index fb2935e72d..5817bff90e 100644 --- a/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java +++ b/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,16 @@ import java.util.Iterator; /** - * If there is a configuration attribute of "AFTER_INVOCATION_MOCK", modifies - * the return value to null. + * If there is a configuration attribute of "AFTER_INVOCATION_MOCK", modifies the return value to null. * * @author Ben Alex * @version $Id$ */ public class MockAfterInvocationManager implements AfterInvocationManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException { + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { diff --git a/core/src/test/java/org/acegisecurity/MockApplicationContext.java b/core/src/test/java/org/acegisecurity/MockApplicationContext.java index 8bd4c309e2..71a310b894 100644 --- a/core/src/test/java/org/acegisecurity/MockApplicationContext.java +++ b/core/src/test/java/org/acegisecurity/MockApplicationContext.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,17 +20,15 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * Simply returns an ApplicationContext which has a couple of - * ApplicationEvent listeners. + * Simply returns an ApplicationContext which has a couple of ApplicationEvent listeners. * * @author Ben Alex * @version $Id$ */ public class MockApplicationContext { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static ConfigurableApplicationContext getContext() { - return new ClassPathXmlApplicationContext( - "org/acegisecurity/applicationContext.xml"); + return new ClassPathXmlApplicationContext("org/acegisecurity/applicationContext.xml"); } } diff --git a/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java b/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java index 22ba68b03e..04f2481a3b 100644 --- a/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java +++ b/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,11 +33,11 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class MockAuthenticationEntryPoint implements AuthenticationEntryPoint { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String url; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockAuthenticationEntryPoint(String url) { this.url = url; @@ -47,12 +47,11 @@ public class MockAuthenticationEntryPoint implements AuthenticationEntryPoint { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void commence(ServletRequest request, ServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException { - ((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request) - .getContextPath() + url); + ((HttpServletResponse) response).sendRedirect(((HttpServletRequest) request).getContextPath() + url); } } diff --git a/core/src/test/java/org/acegisecurity/MockFilterChain.java b/core/src/test/java/org/acegisecurity/MockFilterChain.java index ab141e973f..ce8ba514a0 100644 --- a/core/src/test/java/org/acegisecurity/MockFilterChain.java +++ b/core/src/test/java/org/acegisecurity/MockFilterChain.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class MockFilterChain implements FilterChain { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { diff --git a/core/src/test/java/org/acegisecurity/MockFilterConfig.java b/core/src/test/java/org/acegisecurity/MockFilterConfig.java index 7f8371e470..662f57af9d 100644 --- a/core/src/test/java/org/acegisecurity/MockFilterConfig.java +++ b/core/src/test/java/org/acegisecurity/MockFilterConfig.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,11 +30,11 @@ import javax.servlet.ServletContext; * @version $Id$ */ public class MockFilterConfig implements FilterConfig { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Map map = new HashMap(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public String getFilterName() { throw new UnsupportedOperationException("mock method not implemented"); @@ -54,11 +54,11 @@ public class MockFilterConfig implements FilterConfig { throw new UnsupportedOperationException("mock method not implemented"); } - public void setInitParmeter(String parameter, String value) { - map.put(parameter, value); - } - public ServletContext getServletContext() { throw new UnsupportedOperationException("mock method not implemented"); } + + public void setInitParmeter(String parameter, String value) { + map.put(parameter, value); + } } diff --git a/core/src/test/java/org/acegisecurity/MockJoinPoint.java b/core/src/test/java/org/acegisecurity/MockJoinPoint.java index 39545a6c0e..0c185f5382 100644 --- a/core/src/test/java/org/acegisecurity/MockJoinPoint.java +++ b/core/src/test/java/org/acegisecurity/MockJoinPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,12 +30,12 @@ import java.lang.reflect.Method; * @version $Id$ */ public class MockJoinPoint implements JoinPoint { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Method beingInvoked; private Object object; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockJoinPoint(Object object, Method beingInvoked) { this.object = object; @@ -44,7 +44,7 @@ public class MockJoinPoint implements JoinPoint { private MockJoinPoint() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object[] getArgs() { throw new UnsupportedOperationException("mock not implemented"); @@ -82,7 +82,7 @@ public class MockJoinPoint implements JoinPoint { throw new UnsupportedOperationException("mock not implemented"); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockCodeSignature implements CodeSignature { private Method beingInvoked; diff --git a/core/src/test/java/org/acegisecurity/MockPortResolver.java b/core/src/test/java/org/acegisecurity/MockPortResolver.java index 18022a953d..c99db0f92b 100644 --- a/core/src/test/java/org/acegisecurity/MockPortResolver.java +++ b/core/src/test/java/org/acegisecurity/MockPortResolver.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,12 +27,12 @@ import javax.servlet.ServletRequest; * @version $Id$ */ public class MockPortResolver implements PortResolver { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private int http = 80; private int https = 443; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockPortResolver(int http, int https) { this.http = http; @@ -41,11 +41,10 @@ public class MockPortResolver implements PortResolver { private MockPortResolver() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public int getServerPort(ServletRequest request) { - if ((request.getScheme() != null) - && request.getScheme().equals("https")) { + if ((request.getScheme() != null) && request.getScheme().equals("https")) { return https; } else { return http; diff --git a/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java b/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java index 616b3fa72c..035cbe7ebe 100644 --- a/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java +++ b/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java @@ -19,20 +19,20 @@ import org.acegisecurity.providers.AbstractAuthenticationToken; /** - * Simple holder that indicates the {@link MockRunAsManager} returned a - * different Authentication object. + * Simple holder that indicates the {@link MockRunAsManager} returned a different Authentication + * object. * * @author Ben Alex * @version $Id$ */ public class MockRunAsAuthenticationToken extends AbstractAuthenticationToken { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockRunAsAuthenticationToken() { super(null); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return null; diff --git a/core/src/test/java/org/acegisecurity/MockRunAsManager.java b/core/src/test/java/org/acegisecurity/MockRunAsManager.java index e2288c6061..4e6f6f1f45 100644 --- a/core/src/test/java/org/acegisecurity/MockRunAsManager.java +++ b/core/src/test/java/org/acegisecurity/MockRunAsManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,16 @@ import java.util.Iterator; /** - * Returns a new run-as identity if configuration attribute RUN_AS is found. - * The new identity is simply an empty {@link MockRunAsAuthenticationToken}. + * Returns a new run-as identity if configuration attribute RUN_AS is found. The new identity is simply an empty + * {@link MockRunAsAuthenticationToken}. * * @author Ben Alex * @version $Id$ */ public class MockRunAsManager implements RunAsManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public Authentication buildRunAs(Authentication authentication, - Object object, ConfigAttributeDefinition config) { + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { diff --git a/core/src/test/java/org/acegisecurity/OtherTargetObject.java b/core/src/test/java/org/acegisecurity/OtherTargetObject.java index 8982430dd5..6b54b7b995 100644 --- a/core/src/test/java/org/acegisecurity/OtherTargetObject.java +++ b/core/src/test/java/org/acegisecurity/OtherTargetObject.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,27 +16,18 @@ package org.acegisecurity; /** - * Simply extends {@link TargetObject} so we have a different object to put - * configuration attributes against. - * - *

- * There is no different behaviour. We have to define each method so that - * Class.getMethod(methodName, args) returns a - * Method referencing this class rather than the parent class. - *

- * - *

- * We need to implement ITargetObject again because the - * MethodDefinitionAttributes only locates attributes on - * interfaces explicitly defined by the intercepted class (not the interfaces - * defined by its parent class or classes). - *

+ * Simply extends {@link TargetObject} so we have a different object to put configuration attributes against.

There + * is no different behaviour. We have to define each method so that Class.getMethod(methodName, args) + * returns a Method referencing this class rather than the parent class.

+ *

We need to implement ITargetObject again because the MethodDefinitionAttributes + * only locates attributes on interfaces explicitly defined by the intercepted class (not the interfaces defined by + * its parent class or classes).

* * @author Ben Alex * @version $Id$ */ public class OtherTargetObject extends TargetObject implements ITargetObject { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public int countLength(String input) { return super.countLength(input); diff --git a/core/src/test/java/org/acegisecurity/PopulatedDatabase.java b/core/src/test/java/org/acegisecurity/PopulatedDatabase.java index e4769ae3af..8dc812c597 100644 --- a/core/src/test/java/org/acegisecurity/PopulatedDatabase.java +++ b/core/src/test/java/org/acegisecurity/PopulatedDatabase.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,22 +22,21 @@ import javax.sql.DataSource; /** - * Singleton which provides a populated database connection for all - * JDBC-related unit tests. + * Singleton which provides a populated database connection for all JDBC-related unit tests. * * @author Ben Alex * @version $Id$ */ public class PopulatedDatabase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static DriverManagerDataSource dataSource = null; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== private PopulatedDatabase() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static DataSource getDataSource() { if (dataSource == null) { @@ -60,8 +59,7 @@ public class PopulatedDatabase { "CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL)"); template.execute( "CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME))"); - template.execute( - "CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY)"); + template.execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY)"); template.execute( "CREATE TABLE ACL_OBJECT_IDENTITY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,OBJECT_IDENTITY VARCHAR_IGNORECASE(250) NOT NULL,PARENT_OBJECT BIGINT,ACL_CLASS VARCHAR_IGNORECASE(250) NOT NULL,CONSTRAINT UNIQUE_OBJECT_IDENTITY UNIQUE(OBJECT_IDENTITY),CONSTRAINT SYS_FK_3 FOREIGN KEY(PARENT_OBJECT) REFERENCES ACL_OBJECT_IDENTITY(ID))"); template.execute( @@ -72,16 +70,11 @@ public class PopulatedDatabase { template.execute("INSERT INTO USERS VALUES('peter','opal',FALSE)"); template.execute("INSERT INTO USERS VALUES('scott','wombat',TRUE)"); template.execute("INSERT INTO USERS VALUES('cooper','kookaburra',TRUE)"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('marissa','ROLE_TELLER')"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR')"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('dianne','ROLE_TELLER')"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('scott','ROLE_TELLER')"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('peter','ROLE_TELLER')"); + template.execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_TELLER')"); + template.execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR')"); + template.execute("INSERT INTO AUTHORITIES VALUES('dianne','ROLE_TELLER')"); + template.execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_TELLER')"); + template.execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_TELLER')"); template.execute( "INSERT INTO acl_object_identity VALUES (1, 'org.acegisecurity.acl.DomainObject:1', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');"); template.execute( @@ -100,15 +93,10 @@ public class PopulatedDatabase { "INSERT INTO acl_object_identity VALUES (7, 'org.acegisecurity.acl.DomainObject:7', 3, 'some.invalid.acl.entry.class');"); // ----- FINISH deviation from normal sample data load script ----- - template.execute( - "INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);"); - template.execute( - "INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);"); - template.execute( - "INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);"); - template.execute( - "INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);"); - template.execute( - "INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);"); + template.execute("INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);"); + template.execute("INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);"); + template.execute("INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);"); + template.execute("INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);"); + template.execute("INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);"); } } diff --git a/core/src/test/java/org/acegisecurity/SecurityConfigTests.java b/core/src/test/java/org/acegisecurity/SecurityConfigTests.java index b5136a470b..320901effb 100644 --- a/core/src/test/java/org/acegisecurity/SecurityConfigTests.java +++ b/core/src/test/java/org/acegisecurity/SecurityConfigTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class SecurityConfigTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityConfigTests() { super(); @@ -35,26 +35,26 @@ public class SecurityConfigTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SecurityConfigTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testHashCode() { SecurityConfig config = new SecurityConfig("TEST"); assertEquals("TEST".hashCode(), config.hashCode()); } - + public void testNoArgConstructorDoesntExist() { Class clazz = SecurityConfig.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -90,7 +90,7 @@ public class SecurityConfigTests extends TestCase { assertEquals("TEST", config.toString()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockConfigAttribute implements ConfigAttribute { private String attribute; diff --git a/core/src/test/java/org/acegisecurity/TargetObject.java b/core/src/test/java/org/acegisecurity/TargetObject.java index ba2730f0b6..637485dfc1 100644 --- a/core/src/test/java/org/acegisecurity/TargetObject.java +++ b/core/src/test/java/org/acegisecurity/TargetObject.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import org.acegisecurity.context.SecurityContextHolder; * @version $Id$ */ public class TargetObject implements ITargetObject { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Integer computeHashCode(String input) { return new Integer(input.hashCode()); @@ -36,45 +36,37 @@ public class TargetObject implements ITargetObject { } /** - * Returns the lowercase string, followed by security environment - * information. + * Returns the lowercase string, followed by security environment information. * * @param input the message to make lowercase * - * @return the lowercase message, a space, the Authentication - * class that was on the SecurityContext at the time - * of method invocation, and a boolean indicating if the + * @return the lowercase message, a space, the Authentication class that was on the + * SecurityContext at the time of method invocation, and a boolean indicating if the * Authentication object is authenticated or not */ public String makeLowerCase(String input) { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth == null) { return input.toLowerCase() + " Authentication empty"; } else { - return input.toLowerCase() + " " + auth.getClass().getName() + " " - + auth.isAuthenticated(); + return input.toLowerCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated(); } } /** - * Returns the uppercase string, followed by security environment - * information. + * Returns the uppercase string, followed by security environment information. * * @param input the message to make uppercase * - * @return the uppercase message, a space, the Authentication - * class that was on the SecurityContext at the time - * of method invocation, and a boolean indicating if the + * @return the uppercase message, a space, the Authentication class that was on the + * SecurityContext at the time of method invocation, and a boolean indicating if the * Authentication object is authenticated or not */ public String makeUpperCase(String input) { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - return input.toUpperCase() + " " + auth.getClass().getName() + " " - + auth.isAuthenticated(); + return input.toUpperCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated(); } /** @@ -82,6 +74,7 @@ public class TargetObject implements ITargetObject { * * @param input the message to be made lower-case * + * @return DOCUMENT ME! */ public String publicMakeLowerCase(String input) { return this.makeLowerCase(input); diff --git a/core/src/test/java/org/acegisecurity/acl/AclProviderManagerTests.java b/core/src/test/java/org/acegisecurity/acl/AclProviderManagerTests.java index d9f411d656..0521129900 100644 --- a/core/src/test/java/org/acegisecurity/acl/AclProviderManagerTests.java +++ b/core/src/test/java/org/acegisecurity/acl/AclProviderManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,10 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.acl.basic.NamedEntityObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import java.util.List; @@ -35,7 +37,7 @@ import java.util.Vector; * @version $Id$ */ public class AclProviderManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AclProviderManagerTests() { super(); @@ -45,16 +47,27 @@ public class AclProviderManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AclProviderManagerTests.class); } + private AclProviderManager makeProviderManager() { + MockProvider provider1 = new MockProvider(); + List providers = new Vector(); + providers.add(provider1); + + AclProviderManager mgr = new AclProviderManager(); + mgr.setProviders(providers); + + return mgr; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testAclLookupFails() { AclProviderManager mgr = makeProviderManager(); assertNull(mgr.getAcls(new Integer(5))); @@ -62,8 +75,7 @@ public class AclProviderManagerTests extends TestCase { public void testAclLookupForGivenAuthenticationSuccess() { AclProviderManager mgr = makeProviderManager(); - assertNotNull(mgr.getAcls("STRING", - new UsernamePasswordAuthenticationToken("marissa", "not used"))); + assertNotNull(mgr.getAcls("STRING", new UsernamePasswordAuthenticationToken("marissa", "not used"))); } public void testAclLookupSuccess() { @@ -82,8 +94,7 @@ public class AclProviderManagerTests extends TestCase { } try { - mgr.getAcls(null, - new UsernamePasswordAuthenticationToken("marissa", "not used")); + mgr.getAcls(null, new UsernamePasswordAuthenticationToken("marissa", "not used")); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -99,8 +110,7 @@ public class AclProviderManagerTests extends TestCase { public void testReturnsNullIfNoSupportingProvider() { AclProviderManager mgr = makeProviderManager(); - assertNull(mgr.getAcls(new Integer(4), - new UsernamePasswordAuthenticationToken("marissa", "not used"))); + assertNull(mgr.getAcls(new Integer(4), new UsernamePasswordAuthenticationToken("marissa", "not used"))); assertNull(mgr.getAcls(new Integer(4))); } @@ -149,35 +159,21 @@ public class AclProviderManagerTests extends TestCase { assertEquals(1, mgr.getProviders().size()); } - private AclProviderManager makeProviderManager() { - MockProvider provider1 = new MockProvider(); - List providers = new Vector(); - providers.add(provider1); - - AclProviderManager mgr = new AclProviderManager(); - mgr.setProviders(providers); - - return mgr; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockProvider implements AclProvider { private UsernamePasswordAuthenticationToken marissa = new UsernamePasswordAuthenticationToken("marissa", "not used", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO"), new GrantedAuthorityImpl("ROLE_BAR")}); - private SimpleAclEntry entry100Marissa = new SimpleAclEntry(marissa - .getPrincipal(), + private SimpleAclEntry entry100Marissa = new SimpleAclEntry(marissa.getPrincipal(), new NamedEntityObjectIdentity("OBJECT", "100"), null, 2); private UsernamePasswordAuthenticationToken scott = new UsernamePasswordAuthenticationToken("scott", "not used", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO"), new GrantedAuthorityImpl("ROLE_MANAGER")}); - private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott - .getPrincipal(), + private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott.getPrincipal(), new NamedEntityObjectIdentity("OBJECT", "100"), null, 4); - public AclEntry[] getAcls(Object domainInstance, - Authentication authentication) { + public AclEntry[] getAcls(Object domainInstance, Authentication authentication) { if (authentication.getPrincipal().equals(scott.getPrincipal())) { return new AclEntry[] {entry100Scott}; } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java index 024e17e540..ff73886367 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java @@ -38,11 +38,11 @@ import java.util.Map; * @version $Id$ */ public class BasicAclProviderTests extends TestCase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String OBJECT_IDENTITY = "org.acegisecurity.acl.DomainObject"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicAclProviderTests() { super(); @@ -52,7 +52,7 @@ public class BasicAclProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(BasicAclProviderTests.class); @@ -175,16 +175,14 @@ public class BasicAclProviderTests extends TestCase { assertEquals(14, ((BasicAclEntry) acls[0]).getMask()); assertEquals("ROLE_SUPERVISOR", ((BasicAclEntry) acls[1]).getRecipient()); assertEquals(1, ((BasicAclEntry) acls[1]).getMask()); - assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, - ((BasicAclEntry) acls[2]).getRecipient()); + assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, ((BasicAclEntry) acls[2]).getRecipient()); } public void testGetAclsWithAuthentication() throws Exception { BasicAclProvider provider = new BasicAclProvider(); provider.setBasicAclDao(makePopulatedJdbcDao()); - Authentication scott = new UsernamePasswordAuthenticationToken("scott", - "unused"); + Authentication scott = new UsernamePasswordAuthenticationToken("scott", "unused"); Object object = new MockDomain(6); AclEntry[] acls = provider.getAcls(object, scott); @@ -195,12 +193,9 @@ public class BasicAclProviderTests extends TestCase { public void testGettersSetters() { BasicAclProvider provider = new BasicAclProvider(); - assertEquals(NullAclEntryCache.class, - provider.getBasicAclEntryCache().getClass()); - assertEquals(NamedEntityObjectIdentity.class, - provider.getDefaultAclObjectIdentityClass()); - assertEquals(GrantedAuthorityEffectiveAclsResolver.class, - provider.getEffectiveAclsResolver().getClass()); + assertEquals(NullAclEntryCache.class, provider.getBasicAclEntryCache().getClass()); + assertEquals(NamedEntityObjectIdentity.class, provider.getDefaultAclObjectIdentityClass()); + assertEquals(GrantedAuthorityEffectiveAclsResolver.class, provider.getEffectiveAclsResolver().getClass()); provider.setBasicAclEntryCache(null); assertNull(provider.getBasicAclEntryCache()); @@ -326,7 +321,7 @@ public class BasicAclProviderTests extends TestCase { assertFalse(provider.supports(new Integer(34))); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockCache implements BasicAclEntryCache { private Map map = new HashMap(); @@ -338,8 +333,7 @@ public class BasicAclProviderTests extends TestCase { return map; } - public BasicAclEntry[] getEntriesFromCache( - AclObjectIdentity aclObjectIdentity) { + public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) { gets++; Object result = map.get(aclObjectIdentity); @@ -391,8 +385,7 @@ public class BasicAclProviderTests extends TestCase { } public AclObjectIdentity getAclObjectIdentity() { - return new NamedEntityObjectIdentity(OBJECT_IDENTITY, - new Integer(id).toString()); + return new NamedEntityObjectIdentity(OBJECT_IDENTITY, new Integer(id).toString()); } } } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolverTests.java b/core/src/test/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolverTests.java index 8bc18aa2e2..cd69e3cdbf 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolverTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/GrantedAuthorityEffectiveAclsResolverTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,11 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.acl.AclEntry; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.userdetails.User; @@ -31,7 +34,7 @@ import org.acegisecurity.userdetails.User; * @version $Id$ */ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private SimpleAclEntry entry100RoleEverybody = new SimpleAclEntry("ROLE_EVERYBODY", new NamedEntityObjectIdentity("OBJECT", "100"), null, 14); @@ -39,31 +42,27 @@ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase { new NamedEntityObjectIdentity("OBJECT", "100"), null, 0); private SimpleAclEntry entry100RoleTwo = new SimpleAclEntry("ROLE_TWO", new NamedEntityObjectIdentity("OBJECT", "100"), null, 2); - private UsernamePasswordAuthenticationToken scott = new UsernamePasswordAuthenticationToken("scott", - "not used", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott - .getPrincipal(), new NamedEntityObjectIdentity("OBJECT", "100"), - null, 4); - private UsernamePasswordAuthenticationToken dianne = new UsernamePasswordAuthenticationToken("dianne", - "not used"); + private UsernamePasswordAuthenticationToken scott = new UsernamePasswordAuthenticationToken("scott", "not used", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_TWO")}); + private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott.getPrincipal(), + new NamedEntityObjectIdentity("OBJECT", "100"), null, 4); + private UsernamePasswordAuthenticationToken dianne = new UsernamePasswordAuthenticationToken("dianne", "not used"); private UsernamePasswordAuthenticationToken marissa = new UsernamePasswordAuthenticationToken("marissa", "not used", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_ONE")}); - private SimpleAclEntry entry100Marissa = new SimpleAclEntry(marissa - .getPrincipal(), new NamedEntityObjectIdentity("OBJECT", "100"), - null, 2); + private SimpleAclEntry entry100Marissa = new SimpleAclEntry(marissa.getPrincipal(), + new NamedEntityObjectIdentity("OBJECT", "100"), null, 2); private UsernamePasswordAuthenticationToken scottWithUserDetails = new UsernamePasswordAuthenticationToken(new User( "scott", "NOT_USED", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl( - "ROLE_EVERYBODY")}), "not used", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY")}), "not used", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_TWO")}); // convenience group - private SimpleAclEntry[] acls = {entry100Marissa, entry100Scott, entry100RoleEverybody, entry100RoleOne, entry100RoleTwo}; + private SimpleAclEntry[] acls = { + entry100Marissa, entry100Scott, entry100RoleEverybody, entry100RoleOne, entry100RoleTwo + }; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public GrantedAuthorityEffectiveAclsResolverTests() { super(); @@ -73,16 +72,16 @@ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(GrantedAuthorityEffectiveAclsResolverTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testResolveAclsForDianneWhoHasANullForAuthorities() { GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver(); assertNull(resolver.resolveEffectiveAcls(acls, dianne)); @@ -91,35 +90,25 @@ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase { public void testResolveAclsForMarissa() { GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver(); assertEquals(3, resolver.resolveEffectiveAcls(acls, marissa).length); - assertEquals(entry100Marissa, - resolver.resolveEffectiveAcls(acls, marissa)[0]); - assertEquals(entry100RoleEverybody, - resolver.resolveEffectiveAcls(acls, marissa)[1]); - assertEquals(entry100RoleOne, - resolver.resolveEffectiveAcls(acls, marissa)[2]); + assertEquals(entry100Marissa, resolver.resolveEffectiveAcls(acls, marissa)[0]); + assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, marissa)[1]); + assertEquals(entry100RoleOne, resolver.resolveEffectiveAcls(acls, marissa)[2]); } public void testResolveAclsForScottWithStringObjectAsPrincipal() { GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver(); assertEquals(3, resolver.resolveEffectiveAcls(acls, scott).length); - assertEquals(entry100Scott, - resolver.resolveEffectiveAcls(acls, scott)[0]); - assertEquals(entry100RoleEverybody, - resolver.resolveEffectiveAcls(acls, scott)[1]); - assertEquals(entry100RoleTwo, - resolver.resolveEffectiveAcls(acls, scott)[2]); + assertEquals(entry100Scott, resolver.resolveEffectiveAcls(acls, scott)[0]); + assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, scott)[1]); + assertEquals(entry100RoleTwo, resolver.resolveEffectiveAcls(acls, scott)[2]); } public void testResolveAclsForScottWithUserDetailsObjectAsPrincipal() { GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver(); - assertEquals(3, - resolver.resolveEffectiveAcls(acls, scottWithUserDetails).length); - assertEquals(entry100Scott, - resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[0]); - assertEquals(entry100RoleEverybody, - resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[1]); - assertEquals(entry100RoleTwo, - resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[2]); + assertEquals(3, resolver.resolveEffectiveAcls(acls, scottWithUserDetails).length); + assertEquals(entry100Scott, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[0]); + assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[1]); + assertEquals(entry100RoleTwo, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[2]); } public void testResolveAclsReturnsNullIfNoAclsInFirstPlace() { @@ -129,11 +118,13 @@ public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase { public void testSkipsNonBasicAclEntryObjects() { GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver(); - AclEntry[] basicAcls = {entry100Marissa, entry100Scott, entry100RoleEverybody, entry100RoleOne, new MockAcl(), entry100RoleTwo}; + AclEntry[] basicAcls = { + entry100Marissa, entry100Scott, entry100RoleEverybody, entry100RoleOne, new MockAcl(), entry100RoleTwo + }; assertEquals(3, resolver.resolveEffectiveAcls(basicAcls, marissa).length); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAcl implements AclEntry { // does nothing diff --git a/core/src/test/java/org/acegisecurity/acl/basic/MockAclObjectIdentity.java b/core/src/test/java/org/acegisecurity/acl/basic/MockAclObjectIdentity.java index 5e6d98b5d0..f9320cdd83 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/MockAclObjectIdentity.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/MockAclObjectIdentity.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,8 @@ package org.acegisecurity.acl.basic; /** - * Implements AclObjectIdentity but is incompatible with - * BasicAclProvider because it cannot be constructed by passing - * in a domain object instance. + * Implements AclObjectIdentity but is incompatible with BasicAclProvider because it + * cannot be constructed by passing in a domain object instance. * * @author Ben Alex * @version $Id$ diff --git a/core/src/test/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentityTests.java b/core/src/test/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentityTests.java index 7facc8dcef..a893706427 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentityTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/NamedEntityObjectIdentityTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class NamedEntityObjectIdentityTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NamedEntityObjectIdentityTests() { super(); @@ -35,16 +35,16 @@ public class NamedEntityObjectIdentityTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(NamedEntityObjectIdentityTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConstructionViaReflection() throws Exception { SomeDomain domainObject = new SomeDomain(); domainObject.setId(34); @@ -75,28 +75,26 @@ public class NamedEntityObjectIdentityTests extends TestCase { } } + public void testEquality() { + NamedEntityObjectIdentity original = new NamedEntityObjectIdentity("foo", "12"); + assertFalse(original.equals(null)); + assertFalse(original.equals(new Integer(354))); + assertFalse(original.equals(new NamedEntityObjectIdentity("foo", "23232"))); + assertTrue(original.equals(new NamedEntityObjectIdentity("foo", "12"))); + assertTrue(original.equals(original)); + } + public void testNoArgConstructorDoesntExist() { Class clazz = NamedEntityObjectIdentity.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); } } - public void testEquality() { - NamedEntityObjectIdentity original = new NamedEntityObjectIdentity("foo", - "12"); - assertFalse(original.equals(null)); - assertFalse(original.equals(new Integer(354))); - assertFalse(original.equals( - new NamedEntityObjectIdentity("foo", "23232"))); - assertTrue(original.equals(new NamedEntityObjectIdentity("foo", "12"))); - assertTrue(original.equals(original)); - } - public void testNormalConstructionRejectedIfInvalidArguments() throws Exception { try { @@ -129,8 +127,7 @@ public class NamedEntityObjectIdentityTests extends TestCase { } public void testNormalOperation() { - NamedEntityObjectIdentity name = new NamedEntityObjectIdentity("domain", - "id"); + NamedEntityObjectIdentity name = new NamedEntityObjectIdentity("domain", "id"); assertEquals("domain", name.getClassname()); assertEquals("id", name.getId()); } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java index 926aa81579..b447e945c1 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class SimpleAclEntryTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SimpleAclEntryTests() { super(); @@ -35,22 +35,20 @@ public class SimpleAclEntryTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SimpleAclEntryTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperation() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); - SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, - null, 0); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); + SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0); assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION)); acl.addPermission(SimpleAclEntry.ADMINISTRATION); @@ -90,8 +88,7 @@ public class SimpleAclEntryTests extends TestCase { public void testDetectsNullOnMainConstructor() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); try { new SimpleAclEntry(recipient, null, null, 2); @@ -111,13 +108,11 @@ public class SimpleAclEntryTests extends TestCase { public void testGettersSetters() { SimpleAclEntry acl = new SimpleAclEntry(); - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "693"); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "693"); acl.setAclObjectIdentity(objectIdentity); assertEquals(objectIdentity, acl.getAclObjectIdentity()); - AclObjectIdentity parentObjectIdentity = new NamedEntityObjectIdentity("domain", - "13"); + AclObjectIdentity parentObjectIdentity = new NamedEntityObjectIdentity("domain", "13"); acl.setAclObjectParentIdentity(parentObjectIdentity); assertEquals(parentObjectIdentity, acl.getAclObjectParentIdentity()); @@ -130,10 +125,8 @@ public class SimpleAclEntryTests extends TestCase { public void testRejectsInvalidMasksInAddMethod() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); - SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, - null, 4); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); + SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 4); try { acl.addPermission(Integer.MAX_VALUE); @@ -145,10 +138,8 @@ public class SimpleAclEntryTests extends TestCase { public void testRejectsInvalidMasksInDeleteMethod() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); - SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, - null, 0); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); + SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0); acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE}); try { @@ -161,10 +152,8 @@ public class SimpleAclEntryTests extends TestCase { public void testRejectsInvalidMasksInTogglePermissionMethod() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); - SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, - null, 0); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); + SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0); acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE}); try { @@ -177,10 +166,8 @@ public class SimpleAclEntryTests extends TestCase { public void testToString() { String recipient = "marissa"; - AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", - "12"); - SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, - null, 0); + AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12"); + SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0); acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE}); assertTrue(acl.toString().endsWith("marissa=-RWC- ............................111. (14)]")); } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/SomeDomain.java b/core/src/test/java/org/acegisecurity/acl/basic/SomeDomain.java index 4494e847ef..1672a372c8 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/SomeDomain.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/SomeDomain.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,17 +22,17 @@ package org.acegisecurity.acl.basic; * @version $Id$ */ public class SomeDomain { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private int id; - //~ Methods ================================================================ - - public void setId(int id) { - this.id = id; - } + //~ Methods ======================================================================================================== public int getId() { return id; } + + public void setId(int id) { + this.id = id; + } } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolderTests.java b/core/src/test/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolderTests.java index 20f961b3e5..22ec190778 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolderTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/cache/BasicAclEntryHolderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.acegisecurity.acl.basic.SimpleAclEntry; * @version $Id$ */ public class BasicAclEntryHolderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicAclEntryHolderTests() { super(); @@ -38,16 +38,16 @@ public class BasicAclEntryHolderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(BasicAclEntryHolderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testRejectsNull() throws Exception { try { new BasicAclEntryHolder(null); diff --git a/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java b/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java index a2bb707621..699f4bbcba 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java @@ -36,20 +36,15 @@ import org.springframework.context.ApplicationContext; * @version $Id$ */ public class EhCacheBasedAclEntryCacheTests extends TestCase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== - private static final AclObjectIdentity OBJECT_100 = new NamedEntityObjectIdentity("OBJECT", - "100"); - private static final AclObjectIdentity OBJECT_200 = new NamedEntityObjectIdentity("OBJECT", - "200"); - private static final BasicAclEntry OBJECT_100_MARISSA = new SimpleAclEntry("marissa", - OBJECT_100, null, 2); - private static final BasicAclEntry OBJECT_100_SCOTT = new SimpleAclEntry("scott", - OBJECT_100, null, 4); - private static final BasicAclEntry OBJECT_200_PETER = new SimpleAclEntry("peter", - OBJECT_200, null, 4); + private static final AclObjectIdentity OBJECT_100 = new NamedEntityObjectIdentity("OBJECT", "100"); + private static final AclObjectIdentity OBJECT_200 = new NamedEntityObjectIdentity("OBJECT", "200"); + private static final BasicAclEntry OBJECT_100_MARISSA = new SimpleAclEntry("marissa", OBJECT_100, null, 2); + private static final BasicAclEntry OBJECT_100_SCOTT = new SimpleAclEntry("scott", OBJECT_100, null, 4); + private static final BasicAclEntry OBJECT_200_PETER = new SimpleAclEntry("peter", OBJECT_200, null, 4); - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public EhCacheBasedAclEntryCacheTests() { super(); @@ -59,7 +54,7 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private Cache getCache() { ApplicationContext ctx = MockApplicationContext.getContext(); @@ -84,23 +79,14 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase { cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_200_PETER}); // Check we can get them from cache again - assertEquals(OBJECT_100_SCOTT, - cache.getEntriesFromCache( - new NamedEntityObjectIdentity("OBJECT", "100"))[0]); - assertEquals(OBJECT_100_MARISSA, - cache.getEntriesFromCache( - new NamedEntityObjectIdentity("OBJECT", "100"))[1]); - assertEquals(OBJECT_200_PETER, - cache.getEntriesFromCache( - new NamedEntityObjectIdentity("OBJECT", "200"))[0]); - assertNull(cache.getEntriesFromCache( - new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE"))); + assertEquals(OBJECT_100_SCOTT, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"))[0]); + assertEquals(OBJECT_100_MARISSA, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"))[1]); + assertEquals(OBJECT_200_PETER, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "200"))[0]); + assertNull(cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE"))); // Check after eviction we cannot get them from cache - cache.removeEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", - "100")); - assertNull(cache.getEntriesFromCache( - new NamedEntityObjectIdentity("OBJECT", "100"))); + cache.removeEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100")); + assertNull(cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"))); } public void testStartupDetectsMissingCache() throws Exception { diff --git a/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java b/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java index 41fc145f00..bd528d6e08 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/cache/NullAclEntryCacheTests.java @@ -29,7 +29,7 @@ import org.acegisecurity.acl.basic.SimpleAclEntry; * @version $Id$ */ public class NullAclEntryCacheTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NullAclEntryCacheTests() { super(); @@ -39,7 +39,7 @@ public class NullAclEntryCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(NullAclEntryCacheTests.class); @@ -52,9 +52,7 @@ public class NullAclEntryCacheTests extends TestCase { public void testCacheOperation() throws Exception { NullAclEntryCache cache = new NullAclEntryCache(); cache.putEntriesInCache(new BasicAclEntry[] {new SimpleAclEntry()}); - cache.getEntriesFromCache(new NamedEntityObjectIdentity("not_used", - "not_used")); - cache.removeEntriesFromCache(new NamedEntityObjectIdentity("not_used", - "not_used")); + cache.getEntriesFromCache(new NamedEntityObjectIdentity("not_used", "not_used")); + cache.removeEntriesFromCache(new NamedEntityObjectIdentity("not_used", "not_used")); } } diff --git a/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImplTests.java b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImplTests.java index c0759aee2b..0e2ed96b6b 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImplTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.acl.basic.jdbc; import junit.framework.TestCase; import org.acegisecurity.PopulatedDatabase; + import org.acegisecurity.acl.basic.AclObjectIdentity; import org.acegisecurity.acl.basic.BasicAclEntry; import org.acegisecurity.acl.basic.NamedEntityObjectIdentity; @@ -35,11 +36,11 @@ import java.sql.SQLException; * @version $Id$ */ public class JdbcDaoImplTests extends TestCase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String OBJECT_IDENTITY = "org.acegisecurity.acl.DomainObject"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcDaoImplTests() { super(); @@ -49,21 +50,28 @@ public class JdbcDaoImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JdbcDaoImplTests.class); } + private JdbcDaoImpl makePopulatedJdbcDao() throws Exception { + JdbcDaoImpl dao = new JdbcDaoImpl(); + dao.setDataSource(PopulatedDatabase.getDataSource()); + dao.afterPropertiesSet(); + + return dao; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testExceptionThrownIfBasicAclEntryClassNotFound() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "7"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "7"); try { dao.getAcls(identity); @@ -76,8 +84,7 @@ public class JdbcDaoImplTests extends TestCase { public void testGetsEntriesWhichExistInDatabaseAndHaveAcls() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "2"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "2"); BasicAclEntry[] acls = dao.getAcls(identity); assertEquals(2, acls.length); } @@ -85,18 +92,15 @@ public class JdbcDaoImplTests extends TestCase { public void testGetsEntriesWhichExistInDatabaseButHaveNoAcls() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "5"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "5"); BasicAclEntry[] acls = dao.getAcls(identity); assertEquals(1, acls.length); - assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, - acls[0].getRecipient()); + assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, acls[0].getRecipient()); } public void testGetsEntriesWhichHaveNoParent() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); BasicAclEntry[] acls = dao.getAcls(identity); assertEquals(1, acls.length); assertNull(acls[0].getAclObjectParentIdentity()); @@ -116,8 +120,7 @@ public class JdbcDaoImplTests extends TestCase { public void testNullReturnedIfEntityNotFound() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "NOT_VALID_ID"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "NOT_VALID_ID"); BasicAclEntry[] result = dao.getAcls(identity); assertNull(result); } @@ -131,15 +134,7 @@ public class JdbcDaoImplTests extends TestCase { assertNull(dao.getAcls(identity)); } - private JdbcDaoImpl makePopulatedJdbcDao() throws Exception { - JdbcDaoImpl dao = new JdbcDaoImpl(); - dao.setDataSource(PopulatedDatabase.getDataSource()); - dao.afterPropertiesSet(); - - return dao; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockMappingSqlQuery extends MappingSqlQuery { protected Object mapRow(ResultSet arg0, int arg1) diff --git a/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java index 4b1c50b8cd..a4e4bed5e8 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.acl.basic.jdbc; import junit.framework.TestCase; import org.acegisecurity.PopulatedDatabase; + import org.acegisecurity.acl.basic.AclObjectIdentity; import org.acegisecurity.acl.basic.BasicAclEntry; import org.acegisecurity.acl.basic.NamedEntityObjectIdentity; @@ -39,11 +40,11 @@ import java.sql.SQLException; * @version $Id$ */ public class JdbcExtendedDaoImplTests extends TestCase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final String OBJECT_IDENTITY = "org.acegisecurity.acl.DomainObject"; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcExtendedDaoImplTests() { super(); @@ -53,31 +54,36 @@ public class JdbcExtendedDaoImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JdbcExtendedDaoImplTests.class); } + private JdbcExtendedDaoImpl makePopulatedJdbcDao() + throws Exception { + JdbcExtendedDaoImpl dao = new JdbcExtendedDaoImpl(); + dao.setDataSource(PopulatedDatabase.getDataSource()); + dao.afterPropertiesSet(); + + return dao; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testChangeMask() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "204"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "204"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); // Create a BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, - parentIdentity, SimpleAclEntry.CREATE); + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, parentIdentity, SimpleAclEntry.CREATE); dao.create(simpleAcl1); // Create another BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, - parentIdentity, SimpleAclEntry.READ); + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ); dao.create(simpleAcl2); // Check creation was successful @@ -87,8 +93,7 @@ public class JdbcExtendedDaoImplTests extends TestCase { assertEquals(SimpleAclEntry.READ, acls[1].getMask()); // Attempt to change mask - dao.changeMask(identity, "marissa", - new Integer(SimpleAclEntry.ADMINISTRATION)); + dao.changeMask(identity, "marissa", new Integer(SimpleAclEntry.ADMINISTRATION)); dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.NOTHING)); acls = dao.getAcls(identity); assertEquals(2, acls.length); @@ -101,20 +106,16 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testChangeMaskThrowsExceptionWhenExistingRecordNotFound() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "205"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "205"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); // Create at least one record for this AclObjectIdentity - SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, - parentIdentity, SimpleAclEntry.CREATE); + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, parentIdentity, SimpleAclEntry.CREATE); dao.create(simpleAcl1); // Attempt to change mask, but for a recipient we don't have try { - dao.changeMask(identity, "scott", - new Integer(SimpleAclEntry.ADMINISTRATION)); + dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.ADMINISTRATION)); fail("Should have thrown DataRetrievalFailureException"); } catch (DataRetrievalFailureException expected) { assertTrue(true); @@ -137,10 +138,8 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testCreationOfIdentityThenAclInSeparateInvocations() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "206"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "206"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); // Create just the object identity (NB: recipient and mask is null) SimpleAclEntry simpleAcl1 = new SimpleAclEntry(); @@ -154,17 +153,14 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testDeletionOfAllRecipients() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "203"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "203"); // Create a BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, - null, SimpleAclEntry.CREATE); + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, null, SimpleAclEntry.CREATE); dao.create(simpleAcl1); // Create another BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, null, - SimpleAclEntry.READ); + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, null, SimpleAclEntry.READ); dao.create(simpleAcl2); // Check creation was successful @@ -178,19 +174,15 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testDeletionOfSpecificRecipient() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "202"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "202"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); // Create a BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, - parentIdentity, SimpleAclEntry.CREATE); + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, parentIdentity, SimpleAclEntry.CREATE); dao.create(simpleAcl1); // Create another BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, - parentIdentity, SimpleAclEntry.READ); + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ); dao.create(simpleAcl2); // Check creation was successful @@ -267,19 +259,15 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testNormalCreationAndDuplicateDetection() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "200"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "1"); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "200"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1"); // Create a BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, - parentIdentity, SimpleAclEntry.CREATE); + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, parentIdentity, SimpleAclEntry.CREATE); dao.create(simpleAcl1); // Create another BasicAclEntry for this AclObjectIdentity - SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, - parentIdentity, SimpleAclEntry.READ); + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ); dao.create(simpleAcl2); // Check creation was successful @@ -301,12 +289,9 @@ public class JdbcExtendedDaoImplTests extends TestCase { public void testRejectsInvalidParent() throws Exception { JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); - AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "201"); - AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, - "987987987987986"); - SimpleAclEntry simpleAcl = new SimpleAclEntry("marissa", identity, - parentIdentity, SimpleAclEntry.CREATE); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "201"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "987987987987986"); + SimpleAclEntry simpleAcl = new SimpleAclEntry("marissa", identity, parentIdentity, SimpleAclEntry.CREATE); try { dao.create(simpleAcl); @@ -316,16 +301,7 @@ public class JdbcExtendedDaoImplTests extends TestCase { } } - private JdbcExtendedDaoImpl makePopulatedJdbcDao() - throws Exception { - JdbcExtendedDaoImpl dao = new JdbcExtendedDaoImpl(); - dao.setDataSource(PopulatedDatabase.getDataSource()); - dao.afterPropertiesSet(); - - return dao; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockMappingSqlQuery extends MappingSqlQuery { protected Object mapRow(ResultSet arg0, int arg1) diff --git a/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java index c42d4cd8a6..5a4632ae68 100644 --- a/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class AbstractAdapterAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractAdapterAuthenticationTokenTests() { super(); @@ -38,31 +38,27 @@ public class AbstractAdapterAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractAdapterAuthenticationTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() throws Exception { - MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("my_password".hashCode(), token.getKeyHash()); } public void testIsUserInRole() throws Exception { - MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(token.isUserInRole("ROLE_ONE")); assertTrue(token.isUserInRole("ROLE_TWO")); assertTrue(!token.isUserInRole("")); @@ -72,42 +68,31 @@ public class AbstractAdapterAuthenticationTokenTests extends TestCase { } public void testObjectsEquals() throws Exception { - MockDecisionManagerImpl token1 = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - MockDecisionManagerImpl token2 = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token1 = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + MockDecisionManagerImpl token2 = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals(token1, token2); - MockDecisionManagerImpl token3 = new MockDecisionManagerImpl("my_password", - "Test", "Password_Changed", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token3 = new MockDecisionManagerImpl("my_password", "Test", "Password_Changed", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(!token1.equals(token3)); - MockDecisionManagerImpl token4 = new MockDecisionManagerImpl("my_password", - "Test_Changed", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token4 = new MockDecisionManagerImpl("my_password", "Test_Changed", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(!token1.equals(token4)); - MockDecisionManagerImpl token5 = new MockDecisionManagerImpl("password_changed", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token5 = new MockDecisionManagerImpl("password_changed", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(!token1.equals(token5)); - MockDecisionManagerImpl token6 = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO_CHANGED")}); + MockDecisionManagerImpl token6 = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO_CHANGED") + }); assertTrue(!token1.equals(token6)); - MockDecisionManagerImpl token7 = new MockDecisionManagerImpl("my_password", - "Test", "Password", + MockDecisionManagerImpl token7 = new MockDecisionManagerImpl("my_password", "Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); assertTrue(!token1.equals(token7)); @@ -116,24 +101,20 @@ public class AbstractAdapterAuthenticationTokenTests extends TestCase { public void testSetAuthenticatedAlwaysReturnsTrue() throws Exception { - MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(token.isAuthenticated()); token.setAuthenticated(false); assertTrue(token.isAuthenticated()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockDecisionManagerImpl - extends AbstractAdapterAuthenticationToken { + private class MockDecisionManagerImpl extends AbstractAdapterAuthenticationToken { private String password; private String username; - public MockDecisionManagerImpl(String key, String username, - String password, GrantedAuthority[] authorities) { + public MockDecisionManagerImpl(String key, String username, String password, GrantedAuthority[] authorities) { super(key, authorities); this.username = username; this.password = password; diff --git a/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java b/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java index 90870467fd..30a5c6599a 100644 --- a/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java +++ b/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import java.util.Arrays; + /** * Tests {@link AuthByAdapterProvider} * @@ -33,7 +34,7 @@ import java.util.Arrays; * @version $Id$ */ public class AuthByAdapterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthByAdapterTests() { super(); @@ -43,25 +44,24 @@ public class AuthByAdapterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthByAdapterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthByAdapterProviderCorrectAuthenticationOperation() throws Exception { AuthByAdapterProvider provider = new AuthByAdapterProvider(); provider.setKey("my_password"); - PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, null); + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + null); assertTrue(provider.supports(token.getClass())); Authentication response = provider.authenticate(token); @@ -103,15 +103,13 @@ public class AuthByAdapterTests extends TestCase { provider.setKey("my_password"); // Should fail as UsernamePassword is not interface of AuthByAdapter - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password"); assertTrue(!provider.supports(token.getClass())); try { provider.authenticate(token); - fail( - "Should have thrown ClassCastException (supports() false response was ignored)"); + fail("Should have thrown ClassCastException (supports() false response was ignored)"); } catch (ClassCastException expected) { assertTrue(true); } @@ -123,8 +121,7 @@ public class AuthByAdapterTests extends TestCase { provider.setKey("my_password"); // Should fail as PrincipalAcegiUserToken has different key - PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("wrong_password", - "Test", "Password", null, null); + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("wrong_password", "Test", "Password", null, null); try { provider.authenticate(token); diff --git a/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java index 913c05ff60..8d7ce343f1 100644 --- a/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class HttpRequestIntegrationFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public HttpRequestIntegrationFilterTests() { super(); @@ -45,18 +45,26 @@ public class HttpRequestIntegrationFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(HttpRequestIntegrationFilterTests.class); } + protected void setUp() throws Exception { + super.setUp(); + SecurityContextHolder.getContext().setAuthentication(null); + } + + protected void tearDown() throws Exception { + super.tearDown(); + SecurityContextHolder.getContext().setAuthentication(null); + } + public void testCorrectOperation() throws Exception { HttpRequestIntegrationFilter filter = new HttpRequestIntegrationFilter(); - PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, - null); + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); MockHttpServletRequest request = new MockHttpServletRequest(); request.setUserPrincipal(principal); @@ -67,8 +75,7 @@ public class HttpRequestIntegrationFilterTests extends TestCase { filter.doFilter(request, response, chain); if (!(SecurityContextHolder.getContext().getAuthentication() instanceof PrincipalAcegiUserToken)) { - System.out.println(SecurityContextHolder.getContext() - .getAuthentication()); + System.out.println(SecurityContextHolder.getContext().getAuthentication()); fail("Should have returned PrincipalAcegiUserToken"); } @@ -99,14 +106,4 @@ public class HttpRequestIntegrationFilterTests extends TestCase { filter.doFilter(request, response, chain); assertNull(SecurityContextHolder.getContext().getAuthentication()); } - - protected void setUp() throws Exception { - super.setUp(); - SecurityContextHolder.getContext().setAuthentication(null); - } - - protected void tearDown() throws Exception { - super.tearDown(); - SecurityContextHolder.getContext().setAuthentication(null); - } } diff --git a/core/src/test/java/org/acegisecurity/adapters/MockPrincipal.java b/core/src/test/java/org/acegisecurity/adapters/MockPrincipal.java index 65485caff6..d7185196af 100644 --- a/core/src/test/java/org/acegisecurity/adapters/MockPrincipal.java +++ b/core/src/test/java/org/acegisecurity/adapters/MockPrincipal.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import java.security.Principal; * @version $Id$ */ public class MockPrincipal implements Principal { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public String getName() { return "MockPrincipal"; diff --git a/core/src/test/java/org/acegisecurity/adapters/PrincipalAcegiUserTokenTests.java b/core/src/test/java/org/acegisecurity/adapters/PrincipalAcegiUserTokenTests.java index 4d8e775ca6..c9a96c387d 100644 --- a/core/src/test/java/org/acegisecurity/adapters/PrincipalAcegiUserTokenTests.java +++ b/core/src/test/java/org/acegisecurity/adapters/PrincipalAcegiUserTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class PrincipalAcegiUserTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PrincipalAcegiUserTokenTests() { super(); @@ -38,21 +38,20 @@ public class PrincipalAcegiUserTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(PrincipalAcegiUserTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() throws Exception { - PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("my_password", - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, null); + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + null); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("my_password".hashCode(), token.getKeyHash()); @@ -63,10 +62,10 @@ public class PrincipalAcegiUserTokenTests extends TestCase { Class clazz = PrincipalAcegiUserToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); } - } + } } diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java index f78b10e85a..2dc69ea9be 100644 --- a/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java +++ b/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,9 @@ import org.acegisecurity.Authentication; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.intercept.web.FilterInvocation; + import org.acegisecurity.util.SimpleMethodInvocation; import org.aopalliance.intercept.MethodInvocation; @@ -38,7 +40,7 @@ import java.util.Vector; * @version $Id$ */ public class AfterInvocationProviderManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AfterInvocationProviderManagerTests() { super(); @@ -48,25 +50,22 @@ public class AfterInvocationProviderManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AfterInvocationProviderManagerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperation() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); - list.add(new MockAfterInvocationProvider("swap1", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); - list.add(new MockAfterInvocationProvider("swap2", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); - list.add(new MockAfterInvocationProvider("swap3", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); assertEquals(list, manager.getProviders()); manager.afterPropertiesSet(); @@ -87,25 +86,16 @@ public class AfterInvocationProviderManagerTests extends TestCase { ConfigAttributeDefinition attr4 = new ConfigAttributeDefinition(); attr4.addConfigAttribute(new SecurityConfig("NEVER_CAUSES_SWAP")); - assertEquals("swap1", - manager.decide(null, new SimpleMethodInvocation(), attr1, - "content-before-swapping")); + assertEquals("swap1", manager.decide(null, new SimpleMethodInvocation(), attr1, "content-before-swapping")); - assertEquals("swap2", - manager.decide(null, new SimpleMethodInvocation(), attr2, - "content-before-swapping")); + assertEquals("swap2", manager.decide(null, new SimpleMethodInvocation(), attr2, "content-before-swapping")); - assertEquals("swap3", - manager.decide(null, new SimpleMethodInvocation(), attr3, - "content-before-swapping")); + assertEquals("swap3", manager.decide(null, new SimpleMethodInvocation(), attr3, "content-before-swapping")); assertEquals("content-before-swapping", - manager.decide(null, new SimpleMethodInvocation(), attr4, - "content-before-swapping")); + manager.decide(null, new SimpleMethodInvocation(), attr4, "content-before-swapping")); - assertEquals("swap3", - manager.decide(null, new SimpleMethodInvocation(), attr2and3, - "content-before-swapping")); + assertEquals("swap3", manager.decide(null, new SimpleMethodInvocation(), attr2and3, "content-before-swapping")); } public void testRejectsEmptyProvidersList() { @@ -123,11 +113,9 @@ public class AfterInvocationProviderManagerTests extends TestCase { public void testRejectsNonAfterInvocationProviders() { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); - list.add(new MockAfterInvocationProvider("swap1", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); list.add(new Integer(45)); - list.add(new MockAfterInvocationProvider("swap3", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); try { manager.setProviders(list); @@ -152,12 +140,9 @@ public class AfterInvocationProviderManagerTests extends TestCase { throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); - list.add(new MockAfterInvocationProvider("swap1", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); - list.add(new MockAfterInvocationProvider("swap2", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); - list.add(new MockAfterInvocationProvider("swap3", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); manager.afterPropertiesSet(); @@ -168,12 +153,9 @@ public class AfterInvocationProviderManagerTests extends TestCase { public void testSupportsSecureObjectIteration() throws Exception { AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); List list = new Vector(); - list.add(new MockAfterInvocationProvider("swap1", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); - list.add(new MockAfterInvocationProvider("swap2", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); - list.add(new MockAfterInvocationProvider("swap3", - MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + list.add(new MockAfterInvocationProvider("swap1", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); manager.setProviders(list); manager.afterPropertiesSet(); @@ -181,20 +163,18 @@ public class AfterInvocationProviderManagerTests extends TestCase { assertTrue(manager.supports(MethodInvocation.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== /** - * Always returns the constructor-defined forceReturnObject, - * provided the same configuration attribute was provided. Also stores the - * secure object it supports. + * Always returns the constructor-defined forceReturnObject, provided the same configuration + * attribute was provided. Also stores the secure object it supports. */ private class MockAfterInvocationProvider implements AfterInvocationProvider { private Class secureObject; private ConfigAttribute configAttribute; private Object forceReturnObject; - public MockAfterInvocationProvider(Object forceReturnObject, - Class secureObject, ConfigAttribute configAttribute) { + public MockAfterInvocationProvider(Object forceReturnObject, Class secureObject, ConfigAttribute configAttribute) { this.forceReturnObject = forceReturnObject; this.secureObject = secureObject; this.configAttribute = configAttribute; @@ -202,9 +182,8 @@ public class AfterInvocationProviderManagerTests extends TestCase { private MockAfterInvocationProvider() {} - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) - throws AccessDeniedException { + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { if (config.contains(configAttribute)) { return forceReturnObject; } diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java index 869df56860..e640771765 100644 --- a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java +++ b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import org.acegisecurity.AuthorizationServiceException; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockAclManager; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.MockAclObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; import java.util.List; @@ -38,36 +41,34 @@ import java.util.Vector; * @author Ben Alex * @version $Id$ */ -public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests - extends TestCase { - //~ Constructors =========================================================== +public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests extends TestCase { + //~ Constructors =================================================================================================== public BasicAclEntryAfterInvocationCollectionFilteringProviderTests() { super(); } - public BasicAclEntryAfterInvocationCollectionFilteringProviderTests( - String arg0) { + public BasicAclEntryAfterInvocationCollectionFilteringProviderTests(String arg0) { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(BasicAclEntryAfterInvocationCollectionFilteringProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject() throws Exception { // Create an AclManager, granting scott only ADMINISTRATION rights AclManager aclManager = new MockAclManager("belmont", "scott", - new AclEntry[] {new SimpleAclEntry("scott", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION)}); + new AclEntry[] { + new SimpleAclEntry("scott", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION) + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); @@ -81,14 +82,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list.add("brisbane"); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(0, filteredList.size()); } @@ -97,12 +96,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); @@ -117,14 +116,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list.add("brisbane"); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(0, filteredList.size()); } @@ -133,12 +130,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); @@ -154,14 +151,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list.add("brisbane"); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(1, filteredList.size()); assertEquals("belmont", filteredList.get(0)); @@ -171,12 +166,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); @@ -192,14 +187,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list[3] = "brisbane"; // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - String[] filteredList = (String[]) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + String[] filteredList = (String[]) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(1, filteredList.length); assertEquals("belmont", filteredList[0]); @@ -209,27 +202,25 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), + new MockAclEntry() + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter try { - provider.decide(auth, new SimpleMethodInvocation(), attr, - new String("RETURN_OBJECT_NOT_COLLECTION")); + provider.decide(auth, new SimpleMethodInvocation(), attr, new String("RETURN_OBJECT_NOT_COLLECTION")); fail("Should have thrown AuthorizationServiceException"); } catch (AuthorizationServiceException expected) { assertTrue(true); @@ -240,26 +231,24 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), + new MockAclEntry() + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, null); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, null); assertNull(filteredList); } @@ -268,16 +257,16 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new MockAclEntry() + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); - assertEquals("AFTER_ACL_COLLECTION_READ", - provider.getProcessConfigAttribute()); + assertEquals("AFTER_ACL_COLLECTION_READ", provider.getProcessConfigAttribute()); provider.setProcessConfigAttribute("AFTER_ACL_COLLECTION_ADMIN"); - assertEquals("AFTER_ACL_COLLECTION_ADMIN", - provider.getProcessConfigAttribute()); + assertEquals("AFTER_ACL_COLLECTION_ADMIN", provider.getProcessConfigAttribute()); provider.afterPropertiesSet(); // Create a Collection containing many items, which only "sydney" @@ -289,21 +278,17 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list.add("brisbane"); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // As no matching config attrib, ensure provider doesn't change list - assertEquals(4, - ((List) provider.decide(auth, new SimpleMethodInvocation(), attr, list)) - .size()); + assertEquals(4, ((List) provider.decide(auth, new SimpleMethodInvocation(), attr, list)).size()); // Filter, this time with the conf attrib provider setup to answer attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_ADMIN")); - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(1, filteredList.size()); assertEquals("sydney", filteredList.get(0)); @@ -313,16 +298,16 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); provider.setAclManager(aclManager); assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]); provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION}); - assertEquals(SimpleAclEntry.ADMINISTRATION, - provider.getRequirePermission()[0]); + assertEquals(SimpleAclEntry.ADMINISTRATION, provider.getRequirePermission()[0]); provider.afterPropertiesSet(); // Create a Collection containing many items, which only "sydney" @@ -334,14 +319,12 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests list.add("brisbane"); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); // Filter - List filteredList = (List) provider.decide(auth, - new SimpleMethodInvocation(), attr, list); + List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list); assertEquals(1, filteredList.size()); assertEquals("sydney", filteredList.get(0)); @@ -362,9 +345,10 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); provider.setAclManager(aclManager); provider.setProcessConfigAttribute(null); @@ -373,8 +357,7 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests provider.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A processConfigAttribute is mandatory", - expected.getMessage()); + assertEquals("A processConfigAttribute is mandatory", expected.getMessage()); } } @@ -382,9 +365,10 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests throws Exception { BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); provider.setAclManager(aclManager); provider.setRequirePermission(null); @@ -393,17 +377,15 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests provider.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("One or more requirePermission entries is mandatory", - expected.getMessage()); + assertEquals("One or more requirePermission entries is mandatory", expected.getMessage()); } } public void testSupportsAnything() { - assertTrue(new BasicAclEntryAfterInvocationCollectionFilteringProvider() - .supports(String.class)); + assertTrue(new BasicAclEntryAfterInvocationCollectionFilteringProvider().supports(String.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry { // just so AclTag iterates some different types of AclEntrys diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java index 1bb23cf69c..08c4420a1f 100644 --- a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import org.acegisecurity.AccessDeniedException; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockAclManager; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.MockAclObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; @@ -36,7 +39,7 @@ import org.acegisecurity.util.SimpleMethodInvocation; * @version $Id$ */ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicAclEntryAfterInvocationProviderTests() { super(); @@ -46,31 +49,30 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(BasicAclEntryAfterInvocationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject() throws Exception { // Create an AclManager, granting scott only ADMINISTRATION rights AclManager aclManager = new MockAclManager("belmont", "scott", - new AclEntry[] {new SimpleAclEntry("scott", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION)}); + new AclEntry[] { + new SimpleAclEntry("scott", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION) + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); @@ -86,20 +88,19 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); @@ -115,12 +116,12 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); @@ -128,34 +129,31 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); // Filter - assertEquals("belmont", - provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont")); + assertEquals("belmont", provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont")); } public void testGrantsAccessIfReturnedObjectIsNull() throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("belmont", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), + new MockAclEntry() + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); @@ -167,8 +165,10 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new MockAclEntry() + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); @@ -178,46 +178,41 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); // As no matching config attrib, ensure provider returns original obj - assertEquals("sydney", - provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); + assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); // Filter, this time with the conf attrib provider setup to answer attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_ADMIN")); - assertEquals("sydney", - provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); + assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); } public void testRespectsModificationsToRequirePermissions() throws Exception { // Create an AclManager AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); provider.setAclManager(aclManager); assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]); provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION}); - assertEquals(SimpleAclEntry.ADMINISTRATION, - provider.getRequirePermission()[0]); + assertEquals(SimpleAclEntry.ADMINISTRATION, provider.getRequirePermission()[0]); provider.afterPropertiesSet(); // Create the Authentication and Config Attribs we'll be presenting - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", - "NOT_USED"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", "NOT_USED"); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); // Filter - assertEquals("sydney", - provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); + assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney")); } public void testStartupDetectsMissingAclManager() throws Exception { @@ -235,9 +230,10 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { throws Exception { BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); provider.setAclManager(aclManager); provider.setProcessConfigAttribute(null); @@ -246,8 +242,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { provider.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A processConfigAttribute is mandatory", - expected.getMessage()); + assertEquals("A processConfigAttribute is mandatory", expected.getMessage()); } } @@ -255,9 +250,10 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { throws Exception { BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); AclManager aclManager = new MockAclManager("sydney", "marissa", - new AclEntry[] {new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + new AclEntry[] { + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new MockAclEntry() + }); provider.setAclManager(aclManager); provider.setRequirePermission(null); @@ -266,17 +262,15 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase { provider.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("One or more requirePermission entries is mandatory", - expected.getMessage()); + assertEquals("One or more requirePermission entries is mandatory", expected.getMessage()); } } public void testSupportsAnything() { - assertTrue(new BasicAclEntryAfterInvocationProvider().supports( - String.class)); + assertTrue(new BasicAclEntryAfterInvocationProvider().supports(String.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry { // just so AclTag iterates some different types of AclEntrys diff --git a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests.java index ec5021530b..2b3afeff7d 100644 --- a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,51 +26,43 @@ import org.acegisecurity.captcha.AlwaysTestAfterMaxRequestsCaptchaChannelProcess * @author $author$ * @version $Revision$ */ -public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests - extends TestCase { - //~ Instance fields ======================================================== +public class AlwaysTestAfterMaxRequestsCaptchaChannelProcessorTests extends TestCase { + //~ Instance fields ================================================================================================ AlwaysTestAfterMaxRequestsCaptchaChannelProcessor alwaysTestAfterMaxRequestsCaptchaChannelProcessor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + super.setUp(); + alwaysTestAfterMaxRequestsCaptchaChannelProcessor = new AlwaysTestAfterMaxRequestsCaptchaChannelProcessor(); + } public void testIsContextValidConcerningHumanity() throws Exception { alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThresold(1); CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl(); - assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThresold(-1); - assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThresold(3); - assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } public void testNewContext() { CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl(); - assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); alwaysTestAfterMaxRequestsCaptchaChannelProcessor.setThresold(1); - assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); - } - - protected void setUp() throws Exception { - super.setUp(); - alwaysTestAfterMaxRequestsCaptchaChannelProcessor = new AlwaysTestAfterMaxRequestsCaptchaChannelProcessor(); + assertTrue(alwaysTestAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } } diff --git a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests.java index 15fbaaee1b..76ce95fb5e 100644 --- a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,42 +21,35 @@ import org.acegisecurity.captcha.AlwaysTestAfterTimeInMillisCaptchaChannelProces /** - * WARNING! This test class make some assumptions concerning the compute speed! - * For example the two following instructions should be computed in the same - * millis or the test is not valid. - *

- * context.setHuman();
+ * WARNING! This test class make some assumptions concerning the compute speed! For example the two following
+ * instructions should be computed in the same millis or the test is not valid.
context.setHuman();
  * assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context));
- * 
- * This should be the case for most environements unless - * - *
    - *
  • - * you run it on a good old TRS-80 - *
  • - *
  • - * you start M$office during this test ;) - *
  • - *
+ *
This should be the case for most environements unless + *
    + *
  • you run it on a good old TRS-80
  • + *
  • you start M$office during this test ;)
  • + *
*/ -public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests - extends TestCase { - //~ Instance fields ======================================================== +public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests extends TestCase { + //~ Instance fields ================================================================================================ AlwaysTestAfterTimeInMillisCaptchaChannelProcessor alwaysTestAfterTimeInMillisCaptchaChannelProcessor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + super.setUp(); + alwaysTestAfterTimeInMillisCaptchaChannelProcessor = new AlwaysTestAfterTimeInMillisCaptchaChannelProcessor(); + } public void testEqualsThresold() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); //the two following instructions should be computed or the test is not valid (never fails). This should be the case // for most environements unless if you run it on a good old TRS-80 (thanks mom). context.setHuman(); - assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } public void testIsContextValidConcerningHumanity() @@ -65,11 +58,9 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests alwaysTestAfterTimeInMillisCaptchaChannelProcessor.setThresold(100); context.setHuman(); - while ((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis()) < alwaysTestAfterTimeInMillisCaptchaChannelProcessor + while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < alwaysTestAfterTimeInMillisCaptchaChannelProcessor .getThresold()) { - assertTrue(alwaysTestAfterTimeInMillisCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); long now = System.currentTimeMillis(); @@ -79,20 +70,13 @@ public class AlwaysTestAfterTimeInMillisCaptchaChannelProcessorTests ; } - assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } public void testNewContext() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); //alwaysTestAfterTimeInMillisCaptchaChannelProcessor.setThresold(10); - assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); - } - - protected void setUp() throws Exception { - super.setUp(); - alwaysTestAfterTimeInMillisCaptchaChannelProcessor = new AlwaysTestAfterTimeInMillisCaptchaChannelProcessor(); + assertFalse(alwaysTestAfterTimeInMillisCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } } diff --git a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests.java index 7bf6c6d54c..935f8aa435 100644 --- a/core/src/test/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,18 +24,21 @@ import junit.framework.TestCase; * @author $author$ * @version $Revision$ */ -public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests - extends TestCase { - //~ Instance fields ======================================================== +public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTests extends TestCase { + //~ Instance fields ================================================================================================ AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + super.setUp(); + alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor = new AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor(); + } public void testEqualsThresold() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .setThresold(100); + alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThresold(100); context.setHuman(); @@ -47,33 +50,29 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTe } context.incrementHumanRestrictedRessoucesRequestsCount(); - assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity( + context)); context.setHuman(); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity( + context)); - alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .setThresold(0); + alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThresold(0); context.setHuman(); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .isContextValidConcerningHumanity(context)); - alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .setThresold(0); + assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity( + context)); + alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThresold(0); } public void testIsContextValidConcerningHumanity() throws Exception { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .setThresold(10); + alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.setThresold(10); context.setHuman(); - while ((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis()) < (10 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor + while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (10 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor .getThresold())) { assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor .isContextValidConcerningHumanity(context)); @@ -82,12 +81,12 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTe public void testNewContext() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); - assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity( + context)); context.setHuman(); - assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor.isContextValidConcerningHumanity( + context)); } public void testShouldPassAbove() { @@ -97,29 +96,20 @@ public class AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessorTe int i = 0; - while ((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis()) < (100 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor + while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (100 * alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor .getThresold())) { - System.out.println((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis())); + System.out.println((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis())); context.incrementHumanRestrictedRessoucesRequestsCount(); i++; - while ((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis()) < (alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor + while ((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis()) < (alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor .getThresold() * i)) {} - System.out.println((System.currentTimeMillis() - - context.getLastPassedCaptchaDateInMillis())); + System.out.println((System.currentTimeMillis() - context.getLastPassedCaptchaDateInMillis())); assertTrue(alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor .isContextValidConcerningHumanity(context)); } } - - protected void setUp() throws Exception { - super.setUp(); - alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor = new AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor(); - } } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplateTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplateTests.java index 6d6e7c5477..5bf61eb992 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplateTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaChannelProcessorTemplateTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.acegisecurity.captcha; import junit.framework.TestCase; @@ -19,7 +20,9 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.intercept.web.FilterInvocation; import org.springframework.mock.web.MockHttpServletRequest; @@ -37,7 +40,21 @@ import javax.servlet.ServletException; * @version $Id$ */ public class CaptchaChannelProcessorTemplateTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private MockHttpServletResponse decideWithNewResponse(ConfigAttributeDefinition cad, + CaptchaChannelProcessorTemplate processor, MockHttpServletRequest request) + throws IOException, ServletException { + MockHttpServletResponse response; + MockFilterChain chain; + FilterInvocation fi; + response = new MockHttpServletResponse(); + chain = new MockFilterChain(); + fi = new FilterInvocation(request, response, chain); + processor.decide(fi, cad); + + return response; + } public void setUp() { SecurityContextHolder.clearContext(); @@ -47,7 +64,6 @@ public class CaptchaChannelProcessorTemplateTests extends TestCase { SecurityContextHolder.clearContext(); } - public void testContextRedirect() throws Exception { CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor(); processor.setKeyword("X"); @@ -80,8 +96,7 @@ public class CaptchaChannelProcessorTemplateTests extends TestCase { assertEquals(null, response.getRedirectedUrl()); processor.setKeyword("Y"); response = decideWithNewResponse(cad, processor, request); - assertEquals("http://localhost:8000/demo/jcaptcha.do", - response.getRedirectedUrl()); + assertEquals("http://localhost:8000/demo/jcaptcha.do", response.getRedirectedUrl()); context.setHuman(); response = decideWithNewResponse(cad, processor, request); assertEquals(null, response.getRedirectedUrl()); @@ -189,8 +204,7 @@ public class CaptchaChannelProcessorTemplateTests extends TestCase { public void testSupports() { CaptchaChannelProcessorTemplate processor = new TestHumanityCaptchaChannelProcessor(); processor.setKeyword("X"); - assertTrue(processor.supports( - new SecurityConfig(processor.getKeyword()))); + assertTrue(processor.supports(new SecurityConfig(processor.getKeyword()))); assertTrue(processor.supports(new SecurityConfig("X"))); @@ -199,25 +213,9 @@ public class CaptchaChannelProcessorTemplateTests extends TestCase { assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); } - private MockHttpServletResponse decideWithNewResponse( - ConfigAttributeDefinition cad, - CaptchaChannelProcessorTemplate processor, - MockHttpServletRequest request) throws IOException, ServletException { - MockHttpServletResponse response; - MockFilterChain chain; - FilterInvocation fi; - response = new MockHttpServletResponse(); - chain = new MockFilterChain(); - fi = new FilterInvocation(request, response, chain); - processor.decide(fi, cad); + //~ Inner Classes ================================================================================================== - return response; - } - - //~ Inner Classes ========================================================== - - private class TestHumanityCaptchaChannelProcessor - extends CaptchaChannelProcessorTemplate { + private class TestHumanityCaptchaChannelProcessor extends CaptchaChannelProcessorTemplate { boolean isContextValidConcerningHumanity(CaptchaSecurityContext context) { return context.isHuman(); } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaEntryPointTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaEntryPointTests.java index 010d40dfaf..238c55bfd6 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.captcha; import junit.framework.TestCase; import org.acegisecurity.MockPortResolver; + import org.acegisecurity.util.PortMapperImpl; import org.springframework.mock.web.MockHttpServletRequest; @@ -36,7 +37,11 @@ import java.util.Map; * @version $Id$ */ public class CaptchaEntryPointTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public static void main(String[] args) { + junit.textui.TestRunner.run(CaptchaEntryPointTests.class); + } // ~ Methods // ================================================================ @@ -44,10 +49,6 @@ public class CaptchaEntryPointTests extends TestCase { super.setUp(); } - public static void main(String[] args) { - junit.textui.TestRunner.run(CaptchaEntryPointTests.class); - } - public void testDetectsMissingCaptchaFormUrl() throws Exception { CaptchaEntryPoint ep = new CaptchaEntryPoint(); ep.setPortMapper(new PortMapperImpl()); @@ -57,8 +58,7 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("captchaFormUrl must be specified", - expected.getMessage()); + assertEquals("captchaFormUrl must be specified", expected.getMessage()); } } @@ -97,8 +97,7 @@ public class CaptchaEntryPointTests extends TestCase { assertTrue(ep.getPortMapper() != null); assertTrue(ep.getPortResolver() != null); - assertEquals("original_requestUrl", - ep.getOriginalRequestUrlParameterName()); + assertEquals("original_requestUrl", ep.getOriginalRequestUrlParameterName()); ep.setOriginalRequestUrlParameterName("Z"); assertEquals("Z", ep.getOriginalRequestUrlParameterName()); @@ -138,22 +137,19 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); request.setServerPort(8080); response = new MockHttpServletResponse(); ep.setPortResolver(new MockPortResolver(8080, 8443)); ep.commence(request, response); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); // Now test an unusual custom HTTP:HTTPS is handled properly request.setServerPort(8888); response = new MockHttpServletResponse(); ep.commence(request, response); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); PortMapperImpl portMapper = new PortMapperImpl(); Map map = new HashMap(); @@ -172,8 +168,7 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com:9999/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:9999/bigWebApp/hello", response.getRedirectedUrl()); } public void testHttpsOperationFromOriginalHttpsUrl() @@ -198,15 +193,13 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); request.setServerPort(8443); response = new MockHttpServletResponse(); ep.setPortResolver(new MockPortResolver(8080, 8443)); ep.commence(request, response); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); } public void testNormalOperation() throws Exception { @@ -229,8 +222,7 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("http://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); } public void testOperationWhenHttpsRequestsButHttpsPortUnknown() @@ -259,8 +251,7 @@ public class CaptchaEntryPointTests extends TestCase { // Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to // HTTP port mapping - assertEquals("http://www.example.com:8888/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("http://www.example.com:8888/bigWebApp/hello", response.getRedirectedUrl()); } public void testOperationWithOriginalRequestIncludes() @@ -269,8 +260,7 @@ public class CaptchaEntryPointTests extends TestCase { ep.setCaptchaFormUrl("/hello"); PortMapperImpl mapper = new PortMapperImpl(); - mapper.getTranslatedPortMappings().put(new Integer(8888), - new Integer(1234)); + mapper.getTranslatedPortMappings().put(new Integer(8888), new Integer(1234)); ep.setPortMapper(mapper); ep.setPortResolver(new MockPortResolver(8888, 1234)); @@ -292,16 +282,16 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); assertEquals("http://www.example.com:8888/hello?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post", response.getRedirectedUrl()); + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post", + response.getRedirectedUrl()); // test the query params request.addParameter("name", "value"); response = new MockHttpServletResponse(); ep.commence(request, response); assertEquals("http://www.example.com:8888/hello?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post", response.getRedirectedUrl()); + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post", + response.getRedirectedUrl()); // test the multiple query params ep.setIncludeOriginalParameters(true); @@ -311,31 +301,26 @@ public class CaptchaEntryPointTests extends TestCase { response = new MockHttpServletResponse(); ep.commence(request, response); assertEquals("http://www.example.com:8888/hello?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); // test add parameter to captcha form url?? ep.setCaptchaFormUrl("/hello?toto=titi"); response = new MockHttpServletResponse(); ep.commence(request, response); - assertEquals( - "http://www.example.com:8888/hello?toto=titi&original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + assertEquals("http://www.example.com:8888/hello?toto=titi&original_requestUrl=" + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); // with forcing!!! ep.setForceHttps(true); response = new MockHttpServletResponse(); ep.commence(request, response); - assertEquals( - "https://www.example.com:1234/hello?toto=titi&original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + assertEquals("https://www.example.com:1234/hello?toto=titi&original_requestUrl=" + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); } @@ -344,8 +329,7 @@ public class CaptchaEntryPointTests extends TestCase { ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/"); PortMapperImpl mapper = new PortMapperImpl(); - mapper.getTranslatedPortMappings().put(new Integer(8888), - new Integer(1234)); + mapper.getTranslatedPortMappings().put(new Integer(8888), new Integer(1234)); ep.setPortMapper(mapper); ep.setPortResolver(new MockPortResolver(8888, 1234)); @@ -369,16 +353,16 @@ public class CaptchaEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post", response.getRedirectedUrl()); + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post", + response.getRedirectedUrl()); // test the query params request.addParameter("name", "value"); response = new MockHttpServletResponse(); ep.commence(request, response); assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post", response.getRedirectedUrl()); + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post", + response.getRedirectedUrl()); // test the multiple query params ep.setIncludeOriginalParameters(true); @@ -387,31 +371,26 @@ public class CaptchaEntryPointTests extends TestCase { response = new MockHttpServletResponse(); ep.commence(request, response); assertEquals("https://www.jcaptcha.net/dotest/?original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); // test add parameter to captcha form url?? ep.setCaptchaFormUrl("https://www.jcaptcha.net/dotest/?toto=titi"); response = new MockHttpServletResponse(); ep.commence(request, response); - assertEquals( - "https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + assertEquals("https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl=" + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); // with forcing!!! ep.setForceHttps(true); response = new MockHttpServletResponse(); ep.commence(request, response); - assertEquals( - "https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl=" - + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") - + "&original_request_method=post" + "&original_request_parameters=" - + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), + assertEquals("https://www.jcaptcha.net/dotest/?toto=titi&original_requestUrl=" + + URLEncoder.encode("http://www.example.com:8888/some_path", "UTF-8") + "&original_request_method=post" + + "&original_request_parameters=" + URLEncoder.encode("name__value;;name1__value2", "UTF-8"), response.getRedirectedUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaSecurityContextImplTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaSecurityContextImplTests.java index 45448e8e1d..de9491a0eb 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaSecurityContextImplTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaSecurityContextImplTests.java @@ -25,15 +25,13 @@ import org.acegisecurity.context.SecurityContextImplTests; * @version $Id$ */ public class CaptchaSecurityContextImplTests extends SecurityContextImplTests { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testDefaultValues() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); assertEquals("should not be human", false, context.isHuman()); - assertEquals("should be 0", 0, - context.getLastPassedCaptchaDateInMillis()); - assertEquals("should be 0", 0, - context.getHumanRestrictedResourcesRequestsCount()); + assertEquals("should be 0", 0, context.getLastPassedCaptchaDateInMillis()); + assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount()); } public void testEquals() { @@ -76,31 +74,24 @@ public class CaptchaSecurityContextImplTests extends SecurityContextImplTests { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); context.setHuman(); assertEquals("should be human", true, context.isHuman()); - assertEquals("should be 0", 0, - context.getHumanRestrictedResourcesRequestsCount()); + assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount()); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertEquals("should be 1", 1, - context.getHumanRestrictedResourcesRequestsCount()); + assertEquals("should be 1", 1, context.getHumanRestrictedResourcesRequestsCount()); } public void testResetHuman() { CaptchaSecurityContext context = new CaptchaSecurityContextImpl(); context.setHuman(); assertEquals("should be human", true, context.isHuman()); - assertEquals("should be 0", 0, - context.getHumanRestrictedResourcesRequestsCount()); + assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount()); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertEquals("should be 1", 1, - context.getHumanRestrictedResourcesRequestsCount()); + assertEquals("should be 1", 1, context.getHumanRestrictedResourcesRequestsCount()); long now = System.currentTimeMillis(); context.setHuman(); - assertEquals("should be 0", 0, - context.getHumanRestrictedResourcesRequestsCount()); - assertTrue("should be more than 0", - (context.getLastPassedCaptchaDateInMillis() - now) >= 0); - assertTrue("should be less than 0,1 seconde", - (context.getLastPassedCaptchaDateInMillis() - now) < 100); + assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount()); + assertTrue("should be more than 0", (context.getLastPassedCaptchaDateInMillis() - now) >= 0); + assertTrue("should be less than 0,1 seconde", (context.getLastPassedCaptchaDateInMillis() - now) < 100); } public void testSetHuman() { @@ -108,11 +99,8 @@ public class CaptchaSecurityContextImplTests extends SecurityContextImplTests { long now = System.currentTimeMillis(); context.setHuman(); assertEquals("should be human", true, context.isHuman()); - assertTrue("should be more than 0", - (context.getLastPassedCaptchaDateInMillis() - now) >= 0); - assertTrue("should be less than 0,1 seconde", - (context.getLastPassedCaptchaDateInMillis() - now) < 100); - assertEquals("should be 0", 0, - context.getHumanRestrictedResourcesRequestsCount()); + assertTrue("should be more than 0", (context.getLastPassedCaptchaDateInMillis() - now) >= 0); + assertTrue("should be less than 0,1 seconde", (context.getLastPassedCaptchaDateInMillis() - now) < 100); + assertEquals("should be 0", 0, context.getHumanRestrictedResourcesRequestsCount()); } } diff --git a/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java index 9f1ae58fda..819689a206 100644 --- a/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/CaptchaValidationProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.captcha; import junit.framework.TestCase; import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.util.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; @@ -30,7 +31,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class CaptchaValidationProcessingFilterTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /* */ diff --git a/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java b/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java index a0cb53c631..4e9676f0ad 100644 --- a/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java +++ b/core/src/test/java/org/acegisecurity/captcha/MockCaptchaServiceProxy.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,12 +22,12 @@ package org.acegisecurity.captcha; * @version $Id$ */ public class MockCaptchaServiceProxy implements CaptchaServiceProxy { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ public boolean hasBeenCalled = false; public boolean valid = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean validateReponseForId(String id, Object response) { hasBeenCalled = true; diff --git a/core/src/test/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessorTests.java index f55bb02954..d51e81046a 100644 --- a/core/src/test/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/captcha/TestOnceAfterMaxRequestsCaptchaChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,59 +26,48 @@ import org.acegisecurity.captcha.TestOnceAfterMaxRequestsCaptchaChannelProcessor * @author $author$ * @version $Revision$ */ -public class TestOnceAfterMaxRequestsCaptchaChannelProcessorTests - extends TestCase { - //~ Instance fields ======================================================== +public class TestOnceAfterMaxRequestsCaptchaChannelProcessorTests extends TestCase { + //~ Instance fields ================================================================================================ TestOnceAfterMaxRequestsCaptchaChannelProcessor testOnceAfterMaxRequestsCaptchaChannelProcessor; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + super.setUp(); + testOnceAfterMaxRequestsCaptchaChannelProcessor = new TestOnceAfterMaxRequestsCaptchaChannelProcessor(); + } public void testIsContextValidConcerningHumanity() throws Exception { testOnceAfterMaxRequestsCaptchaChannelProcessor.setThresold(1); CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl(); - assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); testOnceAfterMaxRequestsCaptchaChannelProcessor.setThresold(-1); - assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); testOnceAfterMaxRequestsCaptchaChannelProcessor.setThresold(3); - assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.incrementHumanRestrictedRessoucesRequestsCount(); - assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); context.setHuman(); - for (int i = 0; - i < (2 * testOnceAfterMaxRequestsCaptchaChannelProcessor - .getThresold()); i++) { - assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + for (int i = 0; i < (2 * testOnceAfterMaxRequestsCaptchaChannelProcessor.getThresold()); i++) { + assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } } public void testNewContext() { CaptchaSecurityContextImpl context = new CaptchaSecurityContextImpl(); - assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); + assertFalse(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); testOnceAfterMaxRequestsCaptchaChannelProcessor.setThresold(1); - assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor - .isContextValidConcerningHumanity(context)); - } - - protected void setUp() throws Exception { - super.setUp(); - testOnceAfterMaxRequestsCaptchaChannelProcessor = new TestOnceAfterMaxRequestsCaptchaChannelProcessor(); + assertTrue(testOnceAfterMaxRequestsCaptchaChannelProcessor.isContextValidConcerningHumanity(context)); } } diff --git a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java index a2af10b2b6..127592181b 100644 --- a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java +++ b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java @@ -34,11 +34,10 @@ import org.springframework.mock.web.MockHttpSession; * @version $Id$ */ public class ConcurrentSessionControllerImplTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private Authentication createAuthentication(String user, String password) { - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, - password); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, password); auth.setDetails(createWebDetails(auth)); return auth; @@ -64,8 +63,7 @@ public class ConcurrentSessionControllerImplTests extends TestCase { sc.checkAuthenticationAllowed(auth); sc.registerSuccessfulAuthentication(auth); - String sessionId1 = ((WebAuthenticationDetails) auth.getDetails()) - .getSessionId(); + String sessionId1 = ((WebAuthenticationDetails) auth.getDetails()).getSessionId(); assertFalse(registry.getSessionInformation(sessionId1).isExpired()); // Attempt to authenticate again - it should still be successful @@ -92,8 +90,7 @@ public class ConcurrentSessionControllerImplTests extends TestCase { sc.checkAuthenticationAllowed(auth3); sc.registerSuccessfulAuthentication(auth3); - String sessionId3 = ((WebAuthenticationDetails) auth3.getDetails()) - .getSessionId(); + String sessionId3 = ((WebAuthenticationDetails) auth3.getDetails()).getSessionId(); assertTrue(registry.getSessionInformation(sessionId1).isExpired()); assertFalse(registry.getSessionInformation(sessionId3).isExpired()); } diff --git a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionFilterTests.java b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionFilterTests.java index b2eff83b55..d82e30ab2b 100644 --- a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionFilterTests.java +++ b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class ConcurrentSessionFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ConcurrentSessionFilterTests() { super(); @@ -51,7 +51,15 @@ public class ConcurrentSessionFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + filter.init(filterConfig); + filter.doFilter(request, response, filterChain); + filter.destroy(); + } public static void main(String[] args) { junit.textui.TestRunner.run(ConcurrentSessionFilterTests.class); @@ -78,8 +86,7 @@ public class ConcurrentSessionFilterTests extends TestCase { filter.setExpiredUrl("/expired.jsp"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/expired.jsp", response.getRedirectedUrl()); } @@ -125,30 +132,19 @@ public class ConcurrentSessionFilterTests extends TestCase { SessionRegistry registry = new SessionRegistryImpl(); registry.registerNewSession(session.getId(), "principal"); - Date lastRequest = registry.getSessionInformation(session.getId()) - .getLastRequest(); + Date lastRequest = registry.getSessionInformation(session.getId()).getLastRequest(); filter.setSessionRegistry(registry); filter.setExpiredUrl("/expired.jsp"); Thread.sleep(1000); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); - assertTrue(registry.getSessionInformation(session.getId()) - .getLastRequest().after(lastRequest)); + assertTrue(registry.getSessionInformation(session.getId()).getLastRequest().after(lastRequest)); } - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - filter.init(filterConfig); - filter.doFilter(request, response, filterChain); - filter.destroy(); - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private boolean expectToProceed; diff --git a/core/src/test/java/org/acegisecurity/concurrent/SessionInformationTests.java b/core/src/test/java/org/acegisecurity/concurrent/SessionInformationTests.java index 2af9de9c38..5bde73b6b9 100644 --- a/core/src/test/java/org/acegisecurity/concurrent/SessionInformationTests.java +++ b/core/src/test/java/org/acegisecurity/concurrent/SessionInformationTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,15 +27,14 @@ import java.util.Date; * @version $Id$ */ public class SessionInformationTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testObject() throws Exception { Object principal = "Some principal object"; String sessionId = "1234567890"; Date currentDate = new Date(); - SessionInformation info = new SessionInformation(principal, sessionId, - currentDate); + SessionInformation info = new SessionInformation(principal, sessionId, currentDate); assertEquals(principal, info.getPrincipal()); assertEquals(sessionId, info.getSessionId()); assertEquals(currentDate, info.getLastRequest()); diff --git a/core/src/test/java/org/acegisecurity/concurrent/SessionRegistryImplTests.java b/core/src/test/java/org/acegisecurity/concurrent/SessionRegistryImplTests.java index edef658510..9cf3a49489 100644 --- a/core/src/test/java/org/acegisecurity/concurrent/SessionRegistryImplTests.java +++ b/core/src/test/java/org/acegisecurity/concurrent/SessionRegistryImplTests.java @@ -31,7 +31,7 @@ import java.util.Date; * @version $Id$ */ public class SessionRegistryImplTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testEventPublishing() { MockHttpSession httpSession = new MockHttpSession(); @@ -45,8 +45,7 @@ public class SessionRegistryImplTests extends TestCase { sessionRegistry.registerNewSession(sessionId, principal); // Deregister session via an ApplicationEvent - sessionRegistry.onApplicationEvent(new HttpSessionDestroyedEvent( - httpSession)); + sessionRegistry.onApplicationEvent(new HttpSessionDestroyedEvent(httpSession)); // Check attempts to retrieve cleared session return null assertNull(sessionRegistry.getSessionInformation(sessionId)); @@ -78,14 +77,10 @@ public class SessionRegistryImplTests extends TestCase { sessionRegistry.registerNewSession(sessionId, principal); // Retrieve existing session by session ID - Date currentDateTime = sessionRegistry.getSessionInformation(sessionId) - .getLastRequest(); - assertEquals(principal, - sessionRegistry.getSessionInformation(sessionId).getPrincipal()); - assertEquals(sessionId, - sessionRegistry.getSessionInformation(sessionId).getSessionId()); - assertNotNull(sessionRegistry.getSessionInformation(sessionId) - .getLastRequest()); + Date currentDateTime = sessionRegistry.getSessionInformation(sessionId).getLastRequest(); + assertEquals(principal, sessionRegistry.getSessionInformation(sessionId).getPrincipal()); + assertEquals(sessionId, sessionRegistry.getSessionInformation(sessionId).getSessionId()); + assertNotNull(sessionRegistry.getSessionInformation(sessionId).getLastRequest()); // Retrieve existing session by principal assertEquals(1, sessionRegistry.getAllSessions(principal, false).length); @@ -96,13 +91,11 @@ public class SessionRegistryImplTests extends TestCase { // Update request date/time sessionRegistry.refreshLastRequest(sessionId); - Date retrieved = sessionRegistry.getSessionInformation(sessionId) - .getLastRequest(); + Date retrieved = sessionRegistry.getSessionInformation(sessionId).getLastRequest(); assertTrue(retrieved.after(currentDateTime)); // Check it retrieves correctly when looked up via principal - assertEquals(retrieved, - sessionRegistry.getAllSessions(principal, false)[0].getLastRequest()); + assertEquals(retrieved, sessionRegistry.getAllSessions(principal, false)[0].getLastRequest()); // Clear session information sessionRegistry.removeSessionInformation(sessionId); @@ -121,14 +114,12 @@ public class SessionRegistryImplTests extends TestCase { // Register new Session sessionRegistry.registerNewSession(sessionId1, principal); assertEquals(1, sessionRegistry.getAllSessions(principal, false).length); - assertEquals(sessionId1, - sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); + assertEquals(sessionId1, sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); // Register new Session sessionRegistry.registerNewSession(sessionId2, principal); assertEquals(2, sessionRegistry.getAllSessions(principal, false).length); - assertEquals(sessionId2, - sessionRegistry.getAllSessions(principal, false)[1].getSessionId()); + assertEquals(sessionId2, sessionRegistry.getAllSessions(principal, false)[1].getSessionId()); // Expire one session SessionInformation session = sessionRegistry.getSessionInformation(sessionId2); @@ -148,20 +139,17 @@ public class SessionRegistryImplTests extends TestCase { // Register new Session sessionRegistry.registerNewSession(sessionId1, principal); assertEquals(1, sessionRegistry.getAllSessions(principal, false).length); - assertEquals(sessionId1, - sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); + assertEquals(sessionId1, sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); // Register new Session sessionRegistry.registerNewSession(sessionId2, principal); assertEquals(2, sessionRegistry.getAllSessions(principal, false).length); - assertEquals(sessionId2, - sessionRegistry.getAllSessions(principal, false)[1].getSessionId()); + assertEquals(sessionId2, sessionRegistry.getAllSessions(principal, false)[1].getSessionId()); // Clear session information sessionRegistry.removeSessionInformation(sessionId1); assertEquals(1, sessionRegistry.getAllSessions(principal, false).length); - assertEquals(sessionId2, - sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); + assertEquals(sessionId2, sessionRegistry.getAllSessions(principal, false)[0].getSessionId()); // Clear final session sessionRegistry.removeSessionInformation(sessionId2); diff --git a/core/src/test/java/org/acegisecurity/context/HttpSessionContextIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/context/HttpSessionContextIntegrationFilterTests.java index 5718798684..a6a11b8631 100644 --- a/core/src/test/java/org/acegisecurity/context/HttpSessionContextIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/context/HttpSessionContextIntegrationFilterTests.java @@ -44,7 +44,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class HttpSessionContextIntegrationFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public HttpSessionContextIntegrationFilterTests() { super(); @@ -54,11 +54,11 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { filter.init(filterConfig); filter.doFilter(request, response, filterChain); filter.destroy(); @@ -110,10 +110,8 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { public void testExceptionWithinFilterChainStillClearsSecurityContextHolder() throws Exception { // Build an Authentication object we simulate came from HttpSession - PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, - null); + PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); // Build a Context to store in HttpSession (simulating prior request) SecurityContext sc = new SecurityContextImpl(); @@ -121,13 +119,10 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { // Build a mock request MockHttpServletRequest request = new MockHttpServletRequest(); - request.getSession() - .setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, - sc); + request.getSession().setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, sc); MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain chain = new MockFilterChain(sessionPrincipal, null, - new IOException()); + FilterChain chain = new MockFilterChain(sessionPrincipal, null, new IOException()); // Prepare filter HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); @@ -136,32 +131,25 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { // Execute filter try { - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); - fail( - "We should have received the IOException thrown inside the filter chain here"); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); + fail("We should have received the IOException thrown inside the filter chain here"); } catch (IOException ioe) { assertTrue(true); } // Check the SecurityContextHolder is null, even though an exception was thrown during chain - assertEquals(new SecurityContextImpl(), - SecurityContextHolder.getContext()); + assertEquals(new SecurityContextImpl(), SecurityContextHolder.getContext()); } public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession() throws Exception { // Build an Authentication object we simulate came from HttpSession - PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, - null); + PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); // Build an Authentication object we simulate our Authentication changed it to - PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, - null); + PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); // Build a Context to store in HttpSession (simulating prior request) SecurityContext sc = new SecurityContextImpl(); @@ -169,13 +157,10 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { // Build a mock request MockHttpServletRequest request = new MockHttpServletRequest(); - request.getSession() - .setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, - sc); + request.getSession().setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, sc); MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain chain = new MockFilterChain(sessionPrincipal, - updatedPrincipal, null); + FilterChain chain = new MockFilterChain(sessionPrincipal, updatedPrincipal, null); // Prepare filter HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); @@ -183,23 +168,19 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { filter.afterPropertiesSet(); // Execute filter - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); // Obtain new/update Authentication from HttpSession SecurityContext context = (SecurityContext) request.getSession() .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); - assertEquals(updatedPrincipal, - ((SecurityContext) context).getAuthentication()); + assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); } public void testHttpSessionCreatedWhenContextHolderChanges() throws Exception { // Build an Authentication object we simulate our Authentication changed it to - PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, - null); + PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); // Build a mock request MockHttpServletRequest request = new MockHttpServletRequest(); @@ -212,14 +193,12 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { filter.afterPropertiesSet(); // Execute filter - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); // Obtain new/updated Authentication from HttpSession SecurityContext context = (SecurityContext) request.getSession(false) .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); - assertEquals(updatedPrincipal, - ((SecurityContext) context).getAuthentication()); + assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); } public void testHttpSessionEagerlyCreatedWhenDirected() @@ -236,8 +215,7 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { filter.afterPropertiesSet(); // Execute filter - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); // Check the session is not null assertNotNull(request.getSession(false)); @@ -256,8 +234,7 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { filter.afterPropertiesSet(); // Execute filter - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); // Check the session is null assertNull(request.getSession(false)); @@ -266,16 +243,13 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten() throws Exception { // Build an Authentication object we simulate our Authentication changed it to - PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", - "someone", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, - null); + PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); // Build a mock request MockHttpServletRequest request = new MockHttpServletRequest(); request.getSession() - .setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, - "NOT_A_CONTEXT_OBJECT"); + .setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, "NOT_A_CONTEXT_OBJECT"); MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain chain = new MockFilterChain(null, updatedPrincipal, null); @@ -286,25 +260,23 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { filter.afterPropertiesSet(); // Execute filter - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, response, chain); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); // Obtain new/update Authentication from HttpSession SecurityContext context = (SecurityContext) request.getSession() .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); - assertEquals(updatedPrincipal, - ((SecurityContext) context).getAuthentication()); + assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain extends TestCase implements FilterChain { private Authentication changeContextHolder; private Authentication expectedOnContextHolder; private IOException toThrowDuringChain; - public MockFilterChain(Authentication expectedOnContextHolder, - Authentication changeContextHolder, IOException toThrowDuringChain) { + public MockFilterChain(Authentication expectedOnContextHolder, Authentication changeContextHolder, + IOException toThrowDuringChain) { this.expectedOnContextHolder = expectedOnContextHolder; this.changeContextHolder = changeContextHolder; this.toThrowDuringChain = toThrowDuringChain; @@ -315,8 +287,7 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase { public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { if (expectedOnContextHolder != null) { - assertEquals(expectedOnContextHolder, - SecurityContextHolder.getContext().getAuthentication()); + assertEquals(expectedOnContextHolder, SecurityContextHolder.getContext().getAuthentication()); } if (changeContextHolder != null) { diff --git a/core/src/test/java/org/acegisecurity/context/SecurityContextHolderTests.java b/core/src/test/java/org/acegisecurity/context/SecurityContextHolderTests.java index d3694b6c33..a086ef0eb4 100644 --- a/core/src/test/java/org/acegisecurity/context/SecurityContextHolderTests.java +++ b/core/src/test/java/org/acegisecurity/context/SecurityContextHolderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,12 @@ package org.acegisecurity.context; -import java.util.Random; +import junit.framework.ComparisonFailure; +import junit.framework.TestCase; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; -import junit.framework.ComparisonFailure; -import junit.framework.TestCase; +import java.util.Random; /** @@ -30,8 +30,11 @@ import junit.framework.TestCase; * @version $Id$ */ public class SecurityContextHolderTests extends TestCase { - //~ Constructors =========================================================== - private static int errors = 0; + //~ Static fields/initializers ===================================================================================== + + private static int errors = 0; + + //~ Constructors =================================================================================================== public SecurityContextHolderTests() { super(); @@ -41,19 +44,179 @@ public class SecurityContextHolderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); + private void loadStartAndWaitForThreads(boolean topLevelThread, String prefix, int createThreads, + boolean expectAllThreadsToUseIdenticalAuthentication, boolean expectChildrenToShareAuthenticationWithParent) { + Thread[] threads = new Thread[createThreads]; + errors = 0; + + if (topLevelThread) { + // PARENT (TOP-LEVEL) THREAD CREATION + if (expectChildrenToShareAuthenticationWithParent) { + // An InheritableThreadLocal + for (int i = 0; i < threads.length; i++) { + if ((i % 2) == 0) { + // Don't inject auth into current thread; neither current thread or child will have authentication + threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, false, true, null); + } else { + // Inject auth into current thread, but not child; current thread will have auth, child will also have auth + threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, false, true, + prefix + "Auth_Parent_" + i); + } + } + } else if (expectAllThreadsToUseIdenticalAuthentication) { + // A global + SecurityContextHolder.getContext() + .setAuthentication(new UsernamePasswordAuthenticationToken("GLOBAL_USERNAME", + "pass")); + + for (int i = 0; i < threads.length; i++) { + if ((i % 2) == 0) { + // Don't inject auth into current thread;both current thread and child will have same authentication + threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, true, true, + "GLOBAL_USERNAME"); + } else { + // Inject auth into current thread; current thread will have auth, child will also have auth + threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, true, true, "GLOBAL_USERNAME"); + } + } + } else { + // A standard ThreadLocal + for (int i = 0; i < threads.length; i++) { + if ((i % 2) == 0) { + // Don't inject auth into current thread; neither current thread or child will have authentication + threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, false, false, null); + } else { + // Inject auth into current thread, but not child; current thread will have auth, child will not have auth + threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, false, false, + prefix + "Auth_Parent_" + i); + } + } + } + } else { + // CHILD THREAD CREATION + if (expectChildrenToShareAuthenticationWithParent || expectAllThreadsToUseIdenticalAuthentication) { + // The children being created are all expected to have security (ie an InheritableThreadLocal/global AND auth was injected into parent) + for (int i = 0; i < threads.length; i++) { + String expectedUsername = prefix; + + if (expectAllThreadsToUseIdenticalAuthentication) { + expectedUsername = "GLOBAL_USERNAME"; + } + + // Don't inject auth into current thread; the current thread will obtain auth from its parent + // NB: As topLevelThread = true, no further child threads will be created + threads[i] = makeThread(prefix + "->child->Inherited_Auth_Child_" + i, false, false, + expectAllThreadsToUseIdenticalAuthentication, false, expectedUsername); + } + } else { + // The children being created are NOT expected to have security (ie not an InheritableThreadLocal OR auth was not injected into parent) + for (int i = 0; i < threads.length; i++) { + // Don't inject auth into current thread; neither current thread or child will have authentication + // NB: As topLevelThread = true, no further child threads will be created + threads[i] = makeThread(prefix + "->child->Unauth_Child_" + i, false, false, false, false, null); + } + } + } + + // Start and execute the threads + startAndRun(threads); } public static void main(String[] args) { junit.textui.TestRunner.run(SecurityContextHolderTests.class); } + private Thread makeThread(final String threadIdentifier, final boolean topLevelThread, + final boolean injectAuthIntoCurrentThread, final boolean expectAllThreadsToUseIdenticalAuthentication, + final boolean expectChildrenToShareAuthenticationWithParent, final String expectedUsername) { + final Random rnd = new Random(); + + Thread t = new Thread(new Runnable() { + public void run() { + if (injectAuthIntoCurrentThread) { + // Set authentication in this thread + SecurityContextHolder.getContext() + .setAuthentication(new UsernamePasswordAuthenticationToken( + expectedUsername, "pass")); + + //System.out.println(threadIdentifier + " - set to " + SecurityContextHolder.getContext().getAuthentication()); + } else { + //System.out.println(threadIdentifier + " - not set (currently " + SecurityContextHolder.getContext().getAuthentication() + ")"); + } + + // Do some operations in current thread, checking authentication is as expected in the current thread (ie another thread doesn't change it) + for (int i = 0; i < 25; i++) { + String currentUsername = (SecurityContextHolder.getContext().getAuthentication() == null) + ? null : SecurityContextHolder.getContext().getAuthentication().getName(); + + if ((i % 7) == 0) { + System.out.println(threadIdentifier + " at " + i + " username " + currentUsername); + } + + try { + TestCase.assertEquals("Failed on iteration " + i + "; Authentication was '" + + currentUsername + "' but principal was expected to contain username '" + + expectedUsername + "'", expectedUsername, currentUsername); + } catch (ComparisonFailure err) { + errors++; + throw err; + } + + try { + Thread.sleep(rnd.nextInt(250)); + } catch (InterruptedException ignore) {} + } + + // Load some children threads, checking the authentication is as expected in the children (ie another thread doesn't change it) + if (topLevelThread) { + // Make four children, but we don't want the children to have any more children (so anti-nature, huh?) + if (injectAuthIntoCurrentThread && expectChildrenToShareAuthenticationWithParent) { + loadStartAndWaitForThreads(false, threadIdentifier, 4, + expectAllThreadsToUseIdenticalAuthentication, true); + } else { + loadStartAndWaitForThreads(false, threadIdentifier, 4, + expectAllThreadsToUseIdenticalAuthentication, false); + } + } + } + }, threadIdentifier); + + return t; + } + + public final void setUp() throws Exception { + SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); + } + + private void startAndRun(Thread[] threads) { + // Start them up + for (int i = 0; i < threads.length; i++) { + threads[i].start(); + } + + // Wait for them to finish + while (stillRunning(threads)) { + try { + Thread.sleep(250); + } catch (InterruptedException ignore) {} + } + } + + private boolean stillRunning(Thread[] threads) { + for (int i = 0; i < threads.length; i++) { + if (threads[i].isAlive()) { + return true; + } + } + + return false; + } + public void testContextHolderGetterSetterClearer() { SecurityContext sc = new SecurityContextImpl(); - sc.setAuthentication(new UsernamePasswordAuthenticationToken("Foobar","pass")); + sc.setAuthentication(new UsernamePasswordAuthenticationToken("Foobar", "pass")); SecurityContextHolder.setContext(sc); assertEquals(sc, SecurityContextHolder.getContext()); SecurityContextHolder.clearContext(); @@ -65,7 +228,7 @@ public class SecurityContextHolderTests extends TestCase { assertNotNull(SecurityContextHolder.getContext()); SecurityContextHolder.clearContext(); } - + public void testRejectsNulls() { try { SecurityContextHolder.setContext(null); @@ -74,170 +237,34 @@ public class SecurityContextHolderTests extends TestCase { assertTrue(true); } } - + public void testSynchronizationCustomStrategyLoading() { SecurityContextHolder.setStrategyName(InheritableThreadLocalSecurityContextHolderStrategy.class.getName()); - assertEquals("SecurityContextHolder[strategy='org.acegisecurity.context.InheritableThreadLocalSecurityContextHolderStrategy']", new SecurityContextHolder().toString()); - loadStartAndWaitForThreads(true, "Main_", 10, false, true); - assertEquals("Thread errors detected; review log output for details", 0, errors); + assertEquals("SecurityContextHolder[strategy='org.acegisecurity.context.InheritableThreadLocalSecurityContextHolderStrategy']", + new SecurityContextHolder().toString()); + loadStartAndWaitForThreads(true, "Main_", 10, false, true); + assertEquals("Thread errors detected; review log output for details", 0, errors); } - - public void testSynchronizationInheritableThreadLocal() throws Exception { - SecurityContextHolder.clearContext(); - SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); - loadStartAndWaitForThreads(true, "Main_", 10, false, true); - assertEquals("Thread errors detected; review log output for details", 0, errors); - } - - public void testSynchronizationThreadLocal() throws Exception { - SecurityContextHolder.clearContext(); - SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_THREADLOCAL); - loadStartAndWaitForThreads(true, "Main_", 10, false, false); - assertEquals("Thread errors detected; review log output for details", 0, errors); - } - + public void testSynchronizationGlobal() throws Exception { - SecurityContextHolder.clearContext(); + SecurityContextHolder.clearContext(); SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL); - loadStartAndWaitForThreads(true, "Main_", 10, true, false); - assertEquals("Thread errors detected; review log output for details", 0, errors); + loadStartAndWaitForThreads(true, "Main_", 10, true, false); + assertEquals("Thread errors detected; review log output for details", 0, errors); } - - private void loadStartAndWaitForThreads(boolean topLevelThread, String prefix, int createThreads, boolean expectAllThreadsToUseIdenticalAuthentication, boolean expectChildrenToShareAuthenticationWithParent) { - Thread[] threads = new Thread[createThreads]; - errors = 0; - - if (topLevelThread) { - // PARENT (TOP-LEVEL) THREAD CREATION - if (expectChildrenToShareAuthenticationWithParent) { - // An InheritableThreadLocal - for (int i = 0; i < threads.length; i++) { - if (i % 2 == 0) { - // Don't inject auth into current thread; neither current thread or child will have authentication - threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, false, true, null); - } else { - // Inject auth into current thread, but not child; current thread will have auth, child will also have auth - threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, false, true, prefix + "Auth_Parent_" + i); - } - } - } else if (expectAllThreadsToUseIdenticalAuthentication) { - // A global - SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("GLOBAL_USERNAME","pass")); - for (int i = 0; i < threads.length; i++) { - if (i % 2 == 0) { - // Don't inject auth into current thread;both current thread and child will have same authentication - threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, true, true, "GLOBAL_USERNAME"); - } else { - // Inject auth into current thread; current thread will have auth, child will also have auth - threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, true, true, "GLOBAL_USERNAME"); - } - } - } else { - // A standard ThreadLocal - for (int i = 0; i < threads.length; i++) { - if (i % 2 == 0) { - // Don't inject auth into current thread; neither current thread or child will have authentication - threads[i] = makeThread(prefix + "Unauth_Parent_" + i, true, false, false, false, null); - } else { - // Inject auth into current thread, but not child; current thread will have auth, child will not have auth - threads[i] = makeThread(prefix + "Auth_Parent_" + i, true, true, false, false, prefix + "Auth_Parent_" + i); - } - } - } - } else { - // CHILD THREAD CREATION - if (expectChildrenToShareAuthenticationWithParent || expectAllThreadsToUseIdenticalAuthentication) { - // The children being created are all expected to have security (ie an InheritableThreadLocal/global AND auth was injected into parent) - for (int i = 0; i < threads.length; i++) { - String expectedUsername = prefix; - if (expectAllThreadsToUseIdenticalAuthentication) { - expectedUsername = "GLOBAL_USERNAME"; - } - // Don't inject auth into current thread; the current thread will obtain auth from its parent - // NB: As topLevelThread = true, no further child threads will be created - threads[i] = makeThread(prefix + "->child->Inherited_Auth_Child_" + i, false, false, expectAllThreadsToUseIdenticalAuthentication, false, expectedUsername); - } - } else { - // The children being created are NOT expected to have security (ie not an InheritableThreadLocal OR auth was not injected into parent) - for (int i = 0; i < threads.length; i++) { - // Don't inject auth into current thread; neither current thread or child will have authentication - // NB: As topLevelThread = true, no further child threads will be created - threads[i] = makeThread(prefix + "->child->Unauth_Child_" + i, false, false, false, false, null); - } - } - } - - // Start and execute the threads - startAndRun(threads); - } - - private void startAndRun(Thread[] threads) { - // Start them up - for (int i = 0; i < threads.length; i++) { - threads[i].start(); - } - - // Wait for them to finish - while (stillRunning(threads)) { - try { - Thread.sleep(250); - } catch (InterruptedException ignore) {} - } - } - - private boolean stillRunning(Thread[] threads) { - for (int i = 0; i < threads.length; i++) { - if (threads[i].isAlive()) { - return true; - } - } - return false; - } - - private Thread makeThread(final String threadIdentifier, final boolean topLevelThread, final boolean injectAuthIntoCurrentThread, final boolean expectAllThreadsToUseIdenticalAuthentication, final boolean expectChildrenToShareAuthenticationWithParent, final String expectedUsername) { - final Random rnd = new Random(); - - Thread t = new Thread(new Runnable() { - public void run() { - if (injectAuthIntoCurrentThread) { - // Set authentication in this thread - SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(expectedUsername,"pass")); - //System.out.println(threadIdentifier + " - set to " + SecurityContextHolder.getContext().getAuthentication()); - } else { - //System.out.println(threadIdentifier + " - not set (currently " + SecurityContextHolder.getContext().getAuthentication() + ")"); - } - - // Do some operations in current thread, checking authentication is as expected in the current thread (ie another thread doesn't change it) - for (int i = 0; i < 25; i++) { - String currentUsername = SecurityContextHolder.getContext().getAuthentication() == null ? null : SecurityContextHolder.getContext().getAuthentication().getName(); - - if (i % 7 == 0) { - System.out.println(threadIdentifier + " at " + i + " username " + currentUsername); - } - try { - TestCase.assertEquals("Failed on iteration " + i + "; Authentication was '" + currentUsername + "' but principal was expected to contain username '" + expectedUsername + "'", expectedUsername, currentUsername); - } catch (ComparisonFailure err) { - errors++; - throw err; - } - - try { - Thread.sleep(rnd.nextInt(250)); - } catch (InterruptedException ignore) {} - } + public void testSynchronizationInheritableThreadLocal() + throws Exception { + SecurityContextHolder.clearContext(); + SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); + loadStartAndWaitForThreads(true, "Main_", 10, false, true); + assertEquals("Thread errors detected; review log output for details", 0, errors); + } - // Load some children threads, checking the authentication is as expected in the children (ie another thread doesn't change it) - if (topLevelThread) { - // Make four children, but we don't want the children to have any more children (so anti-nature, huh?) - if (injectAuthIntoCurrentThread && expectChildrenToShareAuthenticationWithParent) { - loadStartAndWaitForThreads(false, threadIdentifier, 4, expectAllThreadsToUseIdenticalAuthentication, true); - } else { - loadStartAndWaitForThreads(false, threadIdentifier, 4, expectAllThreadsToUseIdenticalAuthentication, false); - } - } - } - }, threadIdentifier); - return t; + public void testSynchronizationThreadLocal() throws Exception { + SecurityContextHolder.clearContext(); + SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_THREADLOCAL); + loadStartAndWaitForThreads(true, "Main_", 10, false, false); + assertEquals("Thread errors detected; review log output for details", 0, errors); } } diff --git a/core/src/test/java/org/acegisecurity/context/SecurityContextImplTests.java b/core/src/test/java/org/acegisecurity/context/SecurityContextImplTests.java index 5ce414da2a..6c004e6a94 100644 --- a/core/src/test/java/org/acegisecurity/context/SecurityContextImplTests.java +++ b/core/src/test/java/org/acegisecurity/context/SecurityContextImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.context; import junit.framework.TestCase; import org.acegisecurity.Authentication; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -28,7 +29,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class SecurityContextImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityContextImplTests() { super(); @@ -38,16 +39,16 @@ public class SecurityContextImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SecurityContextImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testEmptyObjectsAreEquals() { SecurityContextImpl obj1 = new SecurityContextImpl(); SecurityContextImpl obj2 = new SecurityContextImpl(); @@ -56,8 +57,7 @@ public class SecurityContextImplTests extends TestCase { public void testSecurityContextCorrectOperation() { SecurityContext context = new SecurityContextImpl(); - Authentication auth = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + Authentication auth = new UsernamePasswordAuthenticationToken("marissa", "koala"); context.setAuthentication(auth); assertEquals(auth, context.getAuthentication()); assertTrue(context.toString().lastIndexOf("marissa") != -1); diff --git a/core/src/test/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java b/core/src/test/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java index c3ed17a4d5..1c1451aee3 100644 --- a/core/src/test/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java +++ b/core/src/test/java/org/acegisecurity/context/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,10 @@ package org.acegisecurity.context.httpinvoker; import junit.framework.TestCase; import org.acegisecurity.Authentication; + import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import java.io.IOException; @@ -37,9 +39,8 @@ import java.util.Map; * @author Ben Alex * @version $Id$ */ -public class AuthenticationSimpleHttpInvokerRequestExecutorTests - extends TestCase { - //~ Constructors =========================================================== +public class AuthenticationSimpleHttpInvokerRequestExecutorTests extends TestCase { + //~ Constructors =================================================================================================== public AuthenticationSimpleHttpInvokerRequestExecutorTests() { super(); @@ -49,7 +50,7 @@ public class AuthenticationSimpleHttpInvokerRequestExecutorTests super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationSimpleHttpInvokerRequestExecutorTests.class); @@ -57,22 +58,19 @@ public class AuthenticationSimpleHttpInvokerRequestExecutorTests public void testNormalOperation() throws Exception { // Setup client-side context - Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("Aladdin", - "open sesame"); + Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("Aladdin", "open sesame"); SecurityContextHolder.getContext().setAuthentication(clientSideAuthentication); // Create a connection and ensure our executor sets its // properties correctly AuthenticationSimpleHttpInvokerRequestExecutor executor = new AuthenticationSimpleHttpInvokerRequestExecutor(); - HttpURLConnection conn = new MockHttpURLConnection(new URL( - "http://localhost/")); + HttpURLConnection conn = new MockHttpURLConnection(new URL("http://localhost/")); executor.prepareConnection(conn, 10); // Check connection properties // See http://www.faqs.org/rfcs/rfc1945.html section 11.1 for example // we are comparing against - assertEquals("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - conn.getRequestProperty("Authorization")); + assertEquals("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", conn.getRequestProperty("Authorization")); SecurityContextHolder.getContext().setAuthentication(null); } @@ -83,15 +81,14 @@ public class AuthenticationSimpleHttpInvokerRequestExecutorTests // Create a connection and ensure our executor sets its // properties correctly AuthenticationSimpleHttpInvokerRequestExecutor executor = new AuthenticationSimpleHttpInvokerRequestExecutor(); - HttpURLConnection conn = new MockHttpURLConnection(new URL( - "http://localhost/")); + HttpURLConnection conn = new MockHttpURLConnection(new URL("http://localhost/")); executor.prepareConnection(conn, 10); // Check connection properties (shouldn't be an Authorization header) assertNull(conn.getRequestProperty("Authorization")); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockHttpURLConnection extends HttpURLConnection { private Map requestProperties = new HashMap(); @@ -100,14 +97,6 @@ public class AuthenticationSimpleHttpInvokerRequestExecutorTests super(u); } - public void setRequestProperty(String key, String value) { - requestProperties.put(key, value); - } - - public String getRequestProperty(String key) { - return (String) requestProperties.get(key); - } - public void connect() throws IOException { throw new UnsupportedOperationException("mock not implemented"); } @@ -116,6 +105,14 @@ public class AuthenticationSimpleHttpInvokerRequestExecutorTests throw new UnsupportedOperationException("mock not implemented"); } + public String getRequestProperty(String key) { + return (String) requestProperties.get(key); + } + + public void setRequestProperty(String key, String value) { + requestProperties.put(key, value); + } + public boolean usingProxy() { throw new UnsupportedOperationException("mock not implemented"); } diff --git a/core/src/test/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationTests.java b/core/src/test/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationTests.java index d8a717afeb..356e21c39c 100644 --- a/core/src/test/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationTests.java +++ b/core/src/test/java/org/acegisecurity/context/rmi/ContextPropagatingRemoteInvocationTests.java @@ -32,14 +32,13 @@ import java.lang.reflect.Method; /** - * Tests {@link ContextPropagatingRemoteInvocation} and {@link - * ContextPropagatingRemoteInvocationFactory}. + * Tests {@link ContextPropagatingRemoteInvocation} and {@link ContextPropagatingRemoteInvocationFactory}. * * @author Ben Alex * @version $Id$ */ public class ContextPropagatingRemoteInvocationTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ContextPropagatingRemoteInvocationTests() { super(); @@ -49,20 +48,17 @@ public class ContextPropagatingRemoteInvocationTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private ContextPropagatingRemoteInvocation getRemoteInvocation() throws Exception { Class clazz = TargetObject.class; - Method method = clazz.getMethod("makeLowerCase", - new Class[] {String.class}); - MethodInvocation mi = new SimpleMethodInvocation(method, - new Object[] {"SOME_STRING"}); + Method method = clazz.getMethod("makeLowerCase", new Class[] {String.class}); + MethodInvocation mi = new SimpleMethodInvocation(method, new Object[] {"SOME_STRING"}); ContextPropagatingRemoteInvocationFactory factory = new ContextPropagatingRemoteInvocationFactory(); - return (ContextPropagatingRemoteInvocation) factory - .createRemoteInvocation(mi); + return (ContextPropagatingRemoteInvocation) factory.createRemoteInvocation(mi); } public static void main(String[] args) { @@ -72,10 +68,8 @@ public class ContextPropagatingRemoteInvocationTests extends TestCase { public void testContextIsResetEvenIfExceptionOccurs() throws Exception { // Setup client-side context - Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa", - "koala"); - SecurityContextHolder.getContext() - .setAuthentication(clientSideAuthentication); + Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala"); + SecurityContextHolder.getContext().setAuthentication(clientSideAuthentication); ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation(); @@ -88,16 +82,13 @@ public class ContextPropagatingRemoteInvocationTests extends TestCase { // expected } - assertNull("Authentication must be null ", - SecurityContextHolder.getContext().getAuthentication()); + assertNull("Authentication must be null ", SecurityContextHolder.getContext().getAuthentication()); } public void testNormalOperation() throws Exception { // Setup client-side context - Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa", - "koala"); - SecurityContextHolder.getContext() - .setAuthentication(clientSideAuthentication); + Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala"); + SecurityContextHolder.getContext().setAuthentication(clientSideAuthentication); ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation(); @@ -119,7 +110,6 @@ public class ContextPropagatingRemoteInvocationTests extends TestCase { ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation(); SecurityContextHolder.getContext().setAuthentication(null); // unnecessary, but for explicitness - assertEquals("some_string Authentication empty", - remoteInvocation.invoke(new TargetObject())); + assertEquals("some_string Authentication empty", remoteInvocation.invoke(new TargetObject())); } } diff --git a/core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java b/core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java index 06915814eb..cd11c15b66 100644 --- a/core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java +++ b/core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.DisabledException; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -30,16 +31,24 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class AuthenticationEventTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private Authentication getAuthentication() { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal", + "Credentials"); + authentication.setDetails("127.0.0.1"); + + return authentication; } public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationEventTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAbstractAuthenticationEvent() { Authentication auth = getAuthentication(); AbstractAuthenticationEvent event = new AuthenticationSuccessEvent(auth); @@ -49,8 +58,7 @@ public class AuthenticationEventTests extends TestCase { public void testAbstractAuthenticationFailureEvent() { Authentication auth = getAuthentication(); AuthenticationException exception = new DisabledException("TEST"); - AbstractAuthenticationFailureEvent event = new AuthenticationFailureDisabledEvent(auth, - exception); + AbstractAuthenticationFailureEvent event = new AuthenticationFailureDisabledEvent(auth, exception); assertEquals(auth, event.getAuthentication()); assertEquals(exception, event.getException()); } @@ -59,8 +67,7 @@ public class AuthenticationEventTests extends TestCase { AuthenticationException exception = new DisabledException("TEST"); try { - AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(null, - exception); + AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(null, exception); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -75,12 +82,4 @@ public class AuthenticationEventTests extends TestCase { assertTrue(true); } } - - private Authentication getAuthentication() { - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal", - "Credentials"); - authentication.setDetails("127.0.0.1"); - - return authentication; - } } diff --git a/core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java b/core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java index f5b33aad0a..f2b0744a39 100644 --- a/core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java +++ b/core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.LockedException; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -29,16 +30,24 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class LoggerListenerTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private Authentication getAuthentication() { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal", + "Credentials"); + authentication.setDetails("127.0.0.1"); + + return authentication; } public static void main(String[] args) { junit.textui.TestRunner.run(LoggerListenerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testLogsEvents() { AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(getAuthentication(), new LockedException("TEST")); @@ -46,12 +55,4 @@ public class LoggerListenerTests extends TestCase { listener.onApplicationEvent(event); assertTrue(true); } - - private Authentication getAuthentication() { - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal", - "Credentials"); - authentication.setDetails("127.0.0.1"); - - return authentication; - } } diff --git a/core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java b/core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java index f8f57b54e9..be388ac8e3 100644 --- a/core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java +++ b/core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.AuthenticationCredentialsNotFoundException; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.util.SimpleMethodInvocation; @@ -29,7 +30,7 @@ import org.acegisecurity.util.SimpleMethodInvocation; * @version $Id$ */ public class AuthenticationCredentialsNotFoundEventTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthenticationCredentialsNotFoundEventTests() { super(); @@ -39,7 +40,7 @@ public class AuthenticationCredentialsNotFoundEventTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationCredentialsNotFoundEventTests.class); @@ -47,8 +48,7 @@ public class AuthenticationCredentialsNotFoundEventTests extends TestCase { public void testRejectsNulls() { try { - new AuthenticationCredentialsNotFoundEvent(null, - new ConfigAttributeDefinition(), + new AuthenticationCredentialsNotFoundEvent(null, new ConfigAttributeDefinition(), new AuthenticationCredentialsNotFoundException("test")); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { @@ -56,16 +56,16 @@ public class AuthenticationCredentialsNotFoundEventTests extends TestCase { } try { - new AuthenticationCredentialsNotFoundEvent(new SimpleMethodInvocation(), - null, new AuthenticationCredentialsNotFoundException("test")); + new AuthenticationCredentialsNotFoundEvent(new SimpleMethodInvocation(), null, + new AuthenticationCredentialsNotFoundException("test")); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - new AuthenticationCredentialsNotFoundEvent(new SimpleMethodInvocation(), - new ConfigAttributeDefinition(), null); + new AuthenticationCredentialsNotFoundEvent(new SimpleMethodInvocation(), new ConfigAttributeDefinition(), + null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); diff --git a/core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java b/core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java index 43c8ae8bdb..1194dca494 100644 --- a/core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java +++ b/core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,11 @@ import junit.framework.TestCase; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.event.authorization.AuthorizationFailureEvent; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; @@ -31,7 +34,7 @@ import org.acegisecurity.util.SimpleMethodInvocation; * @version $Id$ */ public class AuthorizationFailureEventTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthorizationFailureEventTests() { super(); @@ -41,7 +44,7 @@ public class AuthorizationFailureEventTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthorizationFailureEventTests.class); @@ -49,10 +52,8 @@ public class AuthorizationFailureEventTests extends TestCase { public void testRejectsNulls() { try { - new AuthorizationFailureEvent(null, - new ConfigAttributeDefinition(), - new UsernamePasswordAuthenticationToken("foo", "bar"), - new AccessDeniedException("error")); + new AuthorizationFailureEvent(null, new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar"), new AccessDeniedException("error")); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -60,7 +61,14 @@ public class AuthorizationFailureEventTests extends TestCase { try { new AuthorizationFailureEvent(new SimpleMethodInvocation(), null, - new UsernamePasswordAuthenticationToken("foo", "bar"), + new UsernamePasswordAuthenticationToken("foo", "bar"), new AccessDeniedException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + new AuthorizationFailureEvent(new SimpleMethodInvocation(), new ConfigAttributeDefinition(), null, new AccessDeniedException("error")); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { @@ -68,17 +76,7 @@ public class AuthorizationFailureEventTests extends TestCase { } try { - new AuthorizationFailureEvent(new SimpleMethodInvocation(), - new ConfigAttributeDefinition(), null, - new AccessDeniedException("error")); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new AuthorizationFailureEvent(new SimpleMethodInvocation(), - new ConfigAttributeDefinition(), + new AuthorizationFailureEvent(new SimpleMethodInvocation(), new ConfigAttributeDefinition(), new UsernamePasswordAuthenticationToken("foo", "bar"), null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { diff --git a/core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java b/core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java index 5c6cb43988..23598cb85f 100644 --- a/core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java +++ b/core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ package org.acegisecurity.event.authorization; import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; @@ -29,7 +31,7 @@ import org.acegisecurity.util.SimpleMethodInvocation; * @version $Id$ */ public class AuthorizedEventTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthorizedEventTests() { super(); @@ -39,7 +41,7 @@ public class AuthorizedEventTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthorizedEventTests.class); @@ -63,8 +65,7 @@ public class AuthorizedEventTests extends TestCase { } try { - new AuthorizedEvent(new SimpleMethodInvocation(), - new ConfigAttributeDefinition(), null); + new AuthorizedEvent(new SimpleMethodInvocation(), new ConfigAttributeDefinition(), null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); diff --git a/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java index 0aefdcf8b7..94c49a940d 100644 --- a/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,20 +21,21 @@ import org.acegisecurity.MockAccessDecisionManager; import org.acegisecurity.MockAfterInvocationManager; import org.acegisecurity.MockAuthenticationManager; import org.acegisecurity.MockRunAsManager; + import org.acegisecurity.intercept.method.MockMethodDefinitionSource; + import org.acegisecurity.util.SimpleMethodInvocation; /** - * Tests some {@link AbstractSecurityInterceptor} methods. Most of the testing - * for this class is found in the MethodSecurityInterceptorTests - * class. + * Tests some {@link AbstractSecurityInterceptor} methods. Most of the testing for this class is found in the + * MethodSecurityInterceptorTests class. * * @author Ben Alex * @version $Id$ */ public class AbstractSecurityInterceptorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractSecurityInterceptorTests() { super(); @@ -44,7 +45,7 @@ public class AbstractSecurityInterceptorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractSecurityInterceptorTests.class); @@ -80,22 +81,15 @@ public class AbstractSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Subclass must provide a non-null response to getSecureObjectClass()", - expected.getMessage()); + assertEquals("Subclass must provide a non-null response to getSecureObjectClass()", expected.getMessage()); } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockSecurityInterceptorReturnsNull - extends AbstractSecurityInterceptor { + private class MockSecurityInterceptorReturnsNull extends AbstractSecurityInterceptor { private ObjectDefinitionSource objectDefinitionSource; - public void setObjectDefinitionSource( - ObjectDefinitionSource objectDefinitionSource) { - this.objectDefinitionSource = objectDefinitionSource; - } - public Class getSecureObjectClass() { return null; } @@ -103,16 +97,14 @@ public class AbstractSecurityInterceptorTests extends TestCase { public ObjectDefinitionSource obtainObjectDefinitionSource() { return objectDefinitionSource; } - } - private class MockSecurityInterceptorWhichOnlySupportsStrings - extends AbstractSecurityInterceptor { - private ObjectDefinitionSource objectDefinitionSource; - - public void setObjectDefinitionSource( - ObjectDefinitionSource objectDefinitionSource) { + public void setObjectDefinitionSource(ObjectDefinitionSource objectDefinitionSource) { this.objectDefinitionSource = objectDefinitionSource; } + } + + private class MockSecurityInterceptorWhichOnlySupportsStrings extends AbstractSecurityInterceptor { + private ObjectDefinitionSource objectDefinitionSource; public Class getSecureObjectClass() { return String.class; @@ -121,5 +113,9 @@ public class AbstractSecurityInterceptorTests extends TestCase { public ObjectDefinitionSource obtainObjectDefinitionSource() { return objectDefinitionSource; } + + public void setObjectDefinitionSource(ObjectDefinitionSource objectDefinitionSource) { + this.objectDefinitionSource = objectDefinitionSource; + } } } diff --git a/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java b/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java index 757def63df..df1f63c9f8 100644 --- a/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,9 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; import org.aopalliance.intercept.MethodInvocation; @@ -32,7 +34,7 @@ import org.aopalliance.intercept.MethodInvocation; * @version $Id$ */ public class InterceptorStatusTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public InterceptorStatusTokenTests() { super(); @@ -42,7 +44,7 @@ public class InterceptorStatusTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(InterceptorStatusTokenTests.class); @@ -52,7 +54,7 @@ public class InterceptorStatusTokenTests extends TestCase { Class clazz = InterceptorStatusToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -65,8 +67,8 @@ public class InterceptorStatusTokenTests extends TestCase { MethodInvocation mi = new SimpleMethodInvocation(); - InterceptorStatusToken token = new InterceptorStatusToken(new UsernamePasswordAuthenticationToken( - "marissa", "koala"), true, attr, mi); + InterceptorStatusToken token = new InterceptorStatusToken(new UsernamePasswordAuthenticationToken("marissa", + "koala"), true, attr, mi); assertTrue(token.isContextHolderRefreshRequired()); assertEquals(attr, token.getAttr()); diff --git a/core/src/test/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSourceTests.java b/core/src/test/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSourceTests.java index 03b7352037..9565ef03c0 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSourceTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/AbstractMethodDefinitionSourceTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,14 +23,13 @@ import org.aopalliance.intercept.MethodInvocation; /** - * Tests {@link AbstractMethodDefinitionSource} and associated {@link - * ConfigAttributeDefinition}. + * Tests {@link AbstractMethodDefinitionSource} and associated {@link ConfigAttributeDefinition}. * * @author Ben Alex * @version $Id$ */ public class AbstractMethodDefinitionSourceTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractMethodDefinitionSourceTests() { super(); @@ -40,25 +39,23 @@ public class AbstractMethodDefinitionSourceTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractMethodDefinitionSourceTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDoesNotSupportAnotherObject() { - MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, true); assertFalse(mds.supports(String.class)); } public void testGetAttributesForANonMethodInvocation() { - MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, true); try { mds.getAttributes(new String()); @@ -69,8 +66,7 @@ public class AbstractMethodDefinitionSourceTests extends TestCase { } public void testGetAttributesForANullObject() { - MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, true); try { mds.getAttributes(null); @@ -81,8 +77,7 @@ public class AbstractMethodDefinitionSourceTests extends TestCase { } public void testGetAttributesForMethodInvocation() { - MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, true); try { mds.getAttributes(new SimpleMethodInvocation()); @@ -93,8 +88,7 @@ public class AbstractMethodDefinitionSourceTests extends TestCase { } public void testSupportsMethodInvocation() { - MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource mds = new MockMethodDefinitionSource(false, true); assertTrue(mds.supports(MethodInvocation.class)); } } diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java index 7af874d1b5..b5ba12c874 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,13 @@ import org.acegisecurity.ITargetObject; import org.acegisecurity.OtherTargetObject; import org.acegisecurity.SecurityConfig; import org.acegisecurity.TargetObject; + import org.acegisecurity.acl.basic.SomeDomain; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; import org.springframework.context.ApplicationContext; @@ -48,163 +52,20 @@ import java.util.Set; * @version $Id$ */ public class MethodDefinitionAttributesTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ ClassPathXmlApplicationContext applicationContext; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodDefinitionAttributesTests(String a) { super(a); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); - } - - public static void main(String[] args) { - junit.textui.TestRunner.run(MethodDefinitionAttributesTests.class); - } - - public void testAttributesForInterfaceTargetObject() + private ConfigAttributeDefinition getConfigAttributeDefinition(Class clazz, String methodName, Class[] args) throws Exception { - ConfigAttributeDefinition def1 = getConfigAttributeDefinition(ITargetObject.class, - "countLength", new Class[] {String.class}); - Set set1 = toSet(def1); - assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set1.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); - - ConfigAttributeDefinition def2 = getConfigAttributeDefinition(ITargetObject.class, - "makeLowerCase", new Class[] {String.class}); - Set set2 = toSet(def2); - assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set2.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); - - ConfigAttributeDefinition def3 = getConfigAttributeDefinition(ITargetObject.class, - "makeUpperCase", new Class[] {String.class}); - Set set3 = toSet(def3); - assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set3.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); - } - - public void testAttributesForOtherTargetObject() throws Exception { - ConfigAttributeDefinition def1 = getConfigAttributeDefinition(OtherTargetObject.class, - "countLength", new Class[] {String.class}); - Set set1 = toSet(def1); - assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set1.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); - - // Confirm MOCK_CLASS_METHOD_COUNT_LENGTH not added, as it's a String (not a ConfigAttribute) - // Confirm also MOCK_CLASS not added, as we return null for class - assertEquals(2, set1.size()); - - ConfigAttributeDefinition def2 = getConfigAttributeDefinition(OtherTargetObject.class, - "makeLowerCase", new Class[] {String.class}); - Set set2 = toSet(def2); - assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set2.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); - assertTrue(set2.contains( - new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); - - // Confirm MOCK_CLASS not added, as we return null for class - assertEquals(3, set2.size()); - - ConfigAttributeDefinition def3 = getConfigAttributeDefinition(OtherTargetObject.class, - "makeUpperCase", new Class[] {String.class}); - Set set3 = toSet(def3); - assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set3.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); - assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); // defined against interface - - assertEquals(3, set3.size()); - } - - public void testAttributesForTargetObject() throws Exception { - ConfigAttributeDefinition def1 = getConfigAttributeDefinition(TargetObject.class, - "countLength", new Class[] {String.class}); - Set set1 = toSet(def1); - assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set1.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); - - assertTrue(set1.contains(new SecurityConfig("MOCK_CLASS"))); - - // Confirm the MOCK_CLASS_METHOD_COUNT_LENGTH was not added, as it's not a ConfigAttribute - assertEquals(3, set1.size()); - - ConfigAttributeDefinition def2 = getConfigAttributeDefinition(TargetObject.class, - "makeLowerCase", new Class[] {String.class}); - Set set2 = toSet(def2); - assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set2.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); - assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS"))); - assertTrue(set2.contains( - new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); - assertEquals(4, set2.size()); - - ConfigAttributeDefinition def3 = getConfigAttributeDefinition(TargetObject.class, - "makeUpperCase", new Class[] {String.class}); - Set set3 = toSet(def3); - assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); - assertTrue(set3.contains( - new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); - assertTrue(set3.contains(new SecurityConfig("MOCK_CLASS"))); - assertTrue(set3.contains( - new SecurityConfig("MOCK_CLASS_METHOD_MAKE_UPPER_CASE"))); - assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); - assertEquals(5, set3.size()); - } - - public void testMethodCallWithRunAsReplacement() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")}); - SecurityContextHolder.getContext().setAuthentication(token); - - ITargetObject target = makeInterceptedTarget(); - String result = target.makeUpperCase("hello"); - assertEquals("HELLO org.acegisecurity.MockRunAsAuthenticationToken true", - result); - - SecurityContextHolder.getContext().setAuthentication(null); - } - - public void testMethodCallWithoutRunAsReplacement() - throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")}); - SecurityContextHolder.getContext().setAuthentication(token); - - ITargetObject target = makeInterceptedTarget(); - String result = target.makeLowerCase("HELLO"); - - assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken true", - result); - - SecurityContextHolder.getContext().setAuthentication(null); - } - - public void testNullReturnedIfZeroAttributesDefinedForMethodInvocation() - throws Exception { - // SomeDomain is not defined in the MockAttributes() - // (which getConfigAttributeDefinition refers to) - ConfigAttributeDefinition def = getConfigAttributeDefinition(SomeDomain.class, - "getId", null); - assertNull(def); - } - - private ConfigAttributeDefinition getConfigAttributeDefinition( - Class clazz, String methodName, Class[] args) throws Exception { final Method method = clazz.getMethod(methodName, args); MethodDefinitionAttributes source = new MethodDefinitionAttributes(); source.setAttributes(new MockAttributes()); @@ -218,6 +79,10 @@ public class MethodDefinitionAttributesTests extends TestCase { return config; } + public static void main(String[] args) { + junit.textui.TestRunner.run(MethodDefinitionAttributesTests.class); + } + private ITargetObject makeInterceptedTarget() { ApplicationContext context = new ClassPathXmlApplicationContext( "org/acegisecurity/intercept/method/applicationContext.xml"); @@ -225,9 +90,130 @@ public class MethodDefinitionAttributesTests extends TestCase { return (ITargetObject) context.getBean("target"); } + public final void setUp() throws Exception { + super.setUp(); + } + + public void testAttributesForInterfaceTargetObject() + throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(ITargetObject.class, "countLength", + new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(ITargetObject.class, "makeLowerCase", + new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(ITargetObject.class, "makeUpperCase", + new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + } + + public void testAttributesForOtherTargetObject() throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(OtherTargetObject.class, "countLength", + new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + // Confirm MOCK_CLASS_METHOD_COUNT_LENGTH not added, as it's a String (not a ConfigAttribute) + // Confirm also MOCK_CLASS not added, as we return null for class + assertEquals(2, set1.size()); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(OtherTargetObject.class, "makeLowerCase", + new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); + + // Confirm MOCK_CLASS not added, as we return null for class + assertEquals(3, set2.size()); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(OtherTargetObject.class, "makeUpperCase", + new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); // defined against interface + + assertEquals(3, set3.size()); + } + + public void testAttributesForTargetObject() throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(TargetObject.class, "countLength", + new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + assertTrue(set1.contains(new SecurityConfig("MOCK_CLASS"))); + + // Confirm the MOCK_CLASS_METHOD_COUNT_LENGTH was not added, as it's not a ConfigAttribute + assertEquals(3, set1.size()); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(TargetObject.class, "makeLowerCase", + new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); + assertEquals(4, set2.size()); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(TargetObject.class, "makeUpperCase", + new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_CLASS"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_CLASS_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); + assertEquals(5, set3.size()); + } + + public void testMethodCallWithRunAsReplacement() throws Exception { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")}); + SecurityContextHolder.getContext().setAuthentication(token); + + ITargetObject target = makeInterceptedTarget(); + String result = target.makeUpperCase("hello"); + assertEquals("HELLO org.acegisecurity.MockRunAsAuthenticationToken true", result); + + SecurityContextHolder.getContext().setAuthentication(null); + } + + public void testMethodCallWithoutRunAsReplacement() + throws Exception { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")}); + SecurityContextHolder.getContext().setAuthentication(token); + + ITargetObject target = makeInterceptedTarget(); + String result = target.makeLowerCase("HELLO"); + + assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken true", result); + + SecurityContextHolder.getContext().setAuthentication(null); + } + + public void testNullReturnedIfZeroAttributesDefinedForMethodInvocation() + throws Exception { + // SomeDomain is not defined in the MockAttributes() + // (which getConfigAttributeDefinition refers to) + ConfigAttributeDefinition def = getConfigAttributeDefinition(SomeDomain.class, "getId", null); + assertNull(def); + } + /** - * convert a ConfigAttributeDefinition into a set of - * ConfigAttribute(s) + * convert a ConfigAttributeDefinition into a set of ConfigAttribute(s) * * @param def the ConfigAttributeDefinition to cover * diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java index 6bc0609b3c..af1e02c7b2 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,14 +31,13 @@ import java.util.Iterator; /** - * Tests {@link MethodDefinitionSourceEditor} and its asociated {@link - * MethodDefinitionMap}. + * Tests {@link MethodDefinitionSourceEditor} and its asociated {@link MethodDefinitionMap}. * * @author Ben Alex * @version $Id$ */ public class MethodDefinitionSourceEditorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodDefinitionSourceEditorTests() { super(); @@ -48,26 +47,24 @@ public class MethodDefinitionSourceEditorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(MethodDefinitionSourceEditorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAspectJJointPointLookup() throws Exception { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); + editor.setAsText("org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); Class clazz = TargetObject.class; - Method method = clazz.getMethod("countLength", - new Class[] {String.class}); + Method method = clazz.getMethod("countLength", new Class[] {String.class}); MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); ConfigAttributeDefinition returnedCountLength = map.getAttributes(joinPoint); @@ -75,8 +72,7 @@ public class MethodDefinitionSourceEditorTests extends TestCase { ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition(); expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_ONE")); expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_TWO")); - expectedCountLength.addConfigAttribute(new SecurityConfig( - "RUN_AS_ENTRY")); + expectedCountLength.addConfigAttribute(new SecurityConfig("RUN_AS_ENTRY")); assertEquals(expectedCountLength, returnedCountLength); } @@ -106,8 +102,7 @@ public class MethodDefinitionSourceEditorTests extends TestCase { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); try { - editor.setAsText( - "org.acegisecurity.TargetObject.INVALID_METHOD=FOO,BAR"); + editor.setAsText("org.acegisecurity.TargetObject.INVALID_METHOD=FOO,BAR"); fail("Should have given IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -123,22 +118,17 @@ public class MethodDefinitionSourceEditorTests extends TestCase { MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); assertEquals(3, map.getMethodMapSize()); - ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "makeLowerCase", - new Class[] {String.class})); + ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "makeLowerCase", new Class[] {String.class})); ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition(); - expectedMakeLower.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeLower, returnedMakeLower); - ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "makeUpperCase", - new Class[] {String.class})); + ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "makeUpperCase", new Class[] {String.class})); ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_IMPLEMENTATION")); - expectedMakeUpper.addConfigAttribute(new SecurityConfig( - "ROLE_FROM_INTERFACE")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_IMPLEMENTATION")); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE")); assertEquals(expectedMakeUpper, returnedMakeUpper); } @@ -185,40 +175,34 @@ public class MethodDefinitionSourceEditorTests extends TestCase { MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); assertEquals(5, map.getMethodMapSize()); - ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "makeLowerCase", - new Class[] {String.class})); + ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "makeLowerCase", new Class[] {String.class})); ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition(); expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_LOWER")); assertEquals(expectedMakeLower, returnedMakeLower); - ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "makeUpperCase", - new Class[] {String.class})); + ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "makeUpperCase", new Class[] {String.class})); ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(); expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_UPPER")); assertEquals(expectedMakeUpper, returnedMakeUpper); - ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "countLength", - new Class[] {String.class})); + ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "countLength", new Class[] {String.class})); ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition(); - expectedCountLength.addConfigAttribute(new SecurityConfig( - "ROLE_GENERAL")); + expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_GENERAL")); assertEquals(expectedCountLength, returnedCountLength); } public void testNullIsReturnedByMethodDefinitionSourceWhenMethodInvocationNotDefined() throws Exception { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); + editor.setAsText("org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); ConfigAttributeDefinition configAttributeDefinition = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "makeLowerCase", - new Class[] {String.class})); + TargetObject.class, "makeLowerCase", new Class[] {String.class})); assertNull(configAttributeDefinition); } @@ -232,36 +216,33 @@ public class MethodDefinitionSourceEditorTests extends TestCase { public void testSingleMethodParsing() throws Exception { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); + editor.setAsText("org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); - ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation( - TargetObject.class, "countLength", - new Class[] {String.class})); + ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation(TargetObject.class, + "countLength", new Class[] {String.class})); ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition(); expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_ONE")); expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_TWO")); - expectedCountLength.addConfigAttribute(new SecurityConfig( - "RUN_AS_ENTRY")); + expectedCountLength.addConfigAttribute(new SecurityConfig("RUN_AS_ENTRY")); assertEquals(expectedCountLength, returnedCountLength); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockMethodInvocation implements MethodInvocation { Method method; - public MockMethodInvocation(Class clazz, String methodName, - Class[] parameterTypes) throws NoSuchMethodException { - method = clazz.getMethod(methodName, parameterTypes); - } - private MockMethodInvocation() { super(); } + public MockMethodInvocation(Class clazz, String methodName, Class[] parameterTypes) + throws NoSuchMethodException { + method = clazz.getMethod(methodName, parameterTypes); + } + public Object[] getArguments() { return null; } diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java index 3eb8f22c09..30e78cd595 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java @@ -34,14 +34,13 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * Tests {@link - * org.acegisecurity.intercept.method.MethodInvocationPrivilegeEvaluator}. + * Tests {@link org.acegisecurity.intercept.method.MethodInvocationPrivilegeEvaluator}. * * @author Ben Alex * @version $Id$ */ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodInvocationPrivilegeEvaluatorTests() { super(); @@ -51,7 +50,7 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private Object lookupTargetObject() { ApplicationContext context = new ClassPathXmlApplicationContext( @@ -68,17 +67,14 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { ApplicationContext context = new ClassPathXmlApplicationContext( "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); - return (MethodSecurityInterceptor) context.getBean( - "securityInterceptor"); + return (MethodSecurityInterceptor) context.getBean("securityInterceptor"); } public void testAllowsAccessUsingCreate() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")}); Object object = lookupTargetObject(); - MethodInvocation mi = MethodInvocationUtils.create(object, - "makeLowerCase", new Object[] {"foobar"}); + MethodInvocation mi = MethodInvocationUtils.create(object, "makeLowerCase", new Object[] {"foobar"}); MethodSecurityInterceptor interceptor = makeSecurityInterceptor(); MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator(); @@ -90,11 +86,10 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { public void testAllowsAccessUsingCreateFromClass() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")}); - MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, - "makeLowerCase", new Class[] {String.class}); + MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, "makeLowerCase", + new Class[] {String.class}); MethodSecurityInterceptor interceptor = makeSecurityInterceptor(); MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator(); @@ -105,12 +100,10 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { } public void testDeclinesAccessUsingCreate() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_NOT_HELD")}); Object object = lookupTargetObject(); - MethodInvocation mi = MethodInvocationUtils.create(object, - "makeLowerCase", new Object[] {"foobar"}); + MethodInvocation mi = MethodInvocationUtils.create(object, "makeLowerCase", new Object[] {"foobar"}); MethodSecurityInterceptor interceptor = makeSecurityInterceptor(); MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator(); @@ -122,11 +115,10 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase { public void testDeclinesAccessUsingCreateFromClass() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_NOT_HELD")}); - MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, - "makeLowerCase", new Class[] {String.class}); + MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, "makeLowerCase", + new Class[] {String.class}); MethodSecurityInterceptor interceptor = makeSecurityInterceptor(); MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator(); diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MockAttributes.java b/core/src/test/java/org/acegisecurity/intercept/method/MockAttributes.java index 8fb99e82bd..6b95df9bc9 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MockAttributes.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MockAttributes.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,27 +37,28 @@ import java.util.List; * @author Ben Alex */ public class MockAttributes implements Attributes { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - List classAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_CLASS")}); - List classMethodAttributesCountLength = Arrays.asList(new String[] {new String( - "MOCK_CLASS_METHOD_COUNT_LENGTH")}); - List classMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_CLASS_METHOD_MAKE_LOWER_CASE")}); - List classMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_CLASS_METHOD_MAKE_UPPER_CASE")}); - List interfaceAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_INTERFACE")}); - List interfaceMethodAttributesCountLength = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_INTERFACE_METHOD_COUNT_LENGTH")}); - List interfaceMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")}); - List interfaceMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( - "MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"), new SecurityConfig( - "RUN_AS")}); + List classAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig("MOCK_CLASS")}); + List classMethodAttributesCountLength = Arrays.asList(new String[] {new String("MOCK_CLASS_METHOD_COUNT_LENGTH")}); + List classMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] { + new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE") + }); + List classMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] { + new SecurityConfig("MOCK_CLASS_METHOD_MAKE_UPPER_CASE") + }); + List interfaceAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig("MOCK_INTERFACE")}); + List interfaceMethodAttributesCountLength = Arrays.asList(new SecurityConfig[] { + new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH") + }); + List interfaceMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] { + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE") + }); + List interfaceMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] { + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"), new SecurityConfig("RUN_AS") + }); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Collection getAttributes(Class clazz) { // Emphasise we return null for OtherTargetObject @@ -94,8 +95,7 @@ public class MockAttributes implements Attributes { } if (method.getName().equals("publicMakeLowerCase")) { - throw new UnsupportedOperationException( - "mock support not implemented"); + throw new UnsupportedOperationException("mock support not implemented"); } } @@ -114,8 +114,7 @@ public class MockAttributes implements Attributes { } if (method.getName().equals("publicMakeLowerCase")) { - throw new UnsupportedOperationException( - "mock support not implemented"); + throw new UnsupportedOperationException("mock support not implemented"); } } @@ -134,8 +133,7 @@ public class MockAttributes implements Attributes { } if (method.getName().equals("publicMakeLowerCase")) { - throw new UnsupportedOperationException( - "mock support not implemented"); + throw new UnsupportedOperationException("mock support not implemented"); } } diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MockMethodDefinitionSource.java b/core/src/test/java/org/acegisecurity/intercept/method/MockMethodDefinitionSource.java index 4d4bda92d1..4553e03c2f 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MockMethodDefinitionSource.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MockMethodDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,15 +32,14 @@ import java.util.Vector; * @version $Id$ */ public class MockMethodDefinitionSource extends AbstractMethodDefinitionSource { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private List list; private boolean returnAnIterator; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public MockMethodDefinitionSource(boolean includeInvalidAttributes, - boolean returnAnIteratorWhenRequested) { + public MockMethodDefinitionSource(boolean includeInvalidAttributes, boolean returnAnIteratorWhenRequested) { returnAnIterator = returnAnIteratorWhenRequested; list = new Vector(); @@ -72,7 +71,7 @@ public class MockMethodDefinitionSource extends AbstractMethodDefinitionSource { super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Iterator getConfigAttributeDefinitions() { if (returnAnIterator) { diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java index 64119c89ae..5d61882747 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.acegisecurity.intercept.method.aopalliance; import junit.framework.TestCase; import org.acegisecurity.TargetObject; + import org.acegisecurity.intercept.method.MethodDefinitionMap; import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor; @@ -33,7 +34,7 @@ import java.lang.reflect.Method; * @version $Id$ */ public class MethodDefinitionSourceAdvisorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodDefinitionSourceAdvisorTests() { super(); @@ -43,21 +44,32 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private MethodSecurityInterceptor getInterceptor() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText("org.acegisecurity.TargetObject.countLength=ROLE_NOT_USED"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + + MethodSecurityInterceptor msi = new MethodSecurityInterceptor(); + msi.setObjectDefinitionSource(map); + + return msi; } public static void main(String[] args) { junit.textui.TestRunner.run(MethodDefinitionSourceAdvisorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAdvisorReturnsFalseWhenMethodInvocationNotDefined() throws Exception { Class clazz = TargetObject.class; - Method method = clazz.getMethod("makeLowerCase", - new Class[] {String.class}); + Method method = clazz.getMethod("makeLowerCase", new Class[] {String.class}); MethodDefinitionSourceAdvisor advisor = new MethodDefinitionSourceAdvisor(getInterceptor()); assertFalse(advisor.matches(method, clazz)); @@ -66,8 +78,7 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { public void testAdvisorReturnsTrueWhenMethodInvocationIsDefined() throws Exception { Class clazz = TargetObject.class; - Method method = clazz.getMethod("countLength", - new Class[] {String.class}); + Method method = clazz.getMethod("countLength", new Class[] {String.class}); MethodDefinitionSourceAdvisor advisor = new MethodDefinitionSourceAdvisor(getInterceptor()); assertTrue(advisor.matches(method, clazz)); @@ -78,8 +89,7 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { try { new MethodDefinitionSourceAdvisor(msi); - fail( - "Should have detected null ObjectDefinitionSource and thrown AopConfigException"); + fail("Should have detected null ObjectDefinitionSource and thrown AopConfigException"); } catch (AopConfigException expected) { assertTrue(true); } @@ -87,8 +97,7 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { public void testUnsupportedOperations() throws Throwable { Class clazz = TargetObject.class; - Method method = clazz.getMethod("countLength", - new Class[] {String.class}); + Method method = clazz.getMethod("countLength", new Class[] {String.class}); MethodDefinitionSourceAdvisor.InternalMethodInvocation imi = new MethodDefinitionSourceAdvisor(getInterceptor()).new InternalMethodInvocation(method); @@ -127,17 +136,4 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { assertTrue(true); } } - - private MethodSecurityInterceptor getInterceptor() { - MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=ROLE_NOT_USED"); - - MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); - - MethodSecurityInterceptor msi = new MethodSecurityInterceptor(); - msi.setObjectDefinitionSource(map); - - return msi; - } } diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java index a2aba27d36..3f5e6812ca 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.intercept.method.aopalliance; -import java.lang.reflect.Method; -import java.util.Iterator; - import junit.framework.TestCase; import org.acegisecurity.AccessDecisionManager; @@ -36,14 +33,23 @@ import org.acegisecurity.MockAfterInvocationManager; import org.acegisecurity.MockAuthenticationManager; import org.acegisecurity.MockRunAsManager; import org.acegisecurity.RunAsManager; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.intercept.method.AbstractMethodDefinitionSource; import org.acegisecurity.intercept.method.MockMethodDefinitionSource; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.runas.RunAsManagerImpl; + import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import java.lang.reflect.Method; + +import java.util.Iterator; + /** * Tests {@link MethodSecurityInterceptor}. @@ -52,7 +58,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * @version $Id$ */ public class MethodSecurityInterceptorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MethodSecurityInterceptorTests() { super(); @@ -62,17 +68,45 @@ public class MethodSecurityInterceptorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public static void main(String[] args) { + junit.textui.TestRunner.run(MethodSecurityInterceptorTests.class); + } + + private ITargetObject makeInterceptedTarget() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + + return (ITargetObject) context.getBean("target"); + } + + private ITargetObject makeInterceptedTargetRejectsAuthentication() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + + MockAuthenticationManager authenticationManager = new MockAuthenticationManager(false); + MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor"); + si.setAuthenticationManager(authenticationManager); + + return (ITargetObject) context.getBean("target"); + } + + private ITargetObject makeInterceptedTargetWithoutAnAfterInvocationManager() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + + MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor"); + si.setAfterInvocationManager(null); + + return (ITargetObject) context.getBean("target"); + } public final void setUp() throws Exception { super.setUp(); SecurityContextHolder.getContext().setAuthentication(null); } - public static void main(String[] args) { - junit.textui.TestRunner.run(MethodSecurityInterceptorTests.class); - } - public void testCallingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts() throws Exception { ITargetObject target = makeInterceptedTarget(); @@ -82,21 +116,18 @@ public class MethodSecurityInterceptorTests extends TestCase { public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillNotChangeItsIsAuthenticatedProperty() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password"); assertTrue(!token.isAuthenticated()); SecurityContextHolder.getContext().setAuthentication(token); // The associated MockAuthenticationManager WILL accept the above UsernamePasswordAuthenticationToken ITargetObject target = makeInterceptedTarget(); String result = target.publicMakeLowerCase("HELLO"); - assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken false", - result); + assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken false", result); } public void testDeniesWhenAppropriate() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NO_BENEFIT_TO_THIS_GRANTED_AUTHORITY")}); SecurityContextHolder.getContext().setAuthentication(token); @@ -114,8 +145,7 @@ public class MethodSecurityInterceptorTests extends TestCase { MockAccessDecisionManager accessDecision = new MockAccessDecisionManager(); MockRunAsManager runAs = new MockRunAsManager(); MockAuthenticationManager authManager = new MockAuthenticationManager(); - MockMethodDefinitionSource methodSource = new MockMethodDefinitionSource(false, - true); + MockMethodDefinitionSource methodSource = new MockMethodDefinitionSource(false, true); MockAfterInvocationManager afterInvocation = new MockAfterInvocationManager(); MethodSecurityInterceptor si = new MethodSecurityInterceptor(); @@ -133,21 +163,18 @@ public class MethodSecurityInterceptorTests extends TestCase { } public void testMethodCallWithRunAsReplacement() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_UPPER")}); SecurityContextHolder.getContext().setAuthentication(token); ITargetObject target = makeInterceptedTarget(); String result = target.makeUpperCase("hello"); - assertEquals("HELLO org.acegisecurity.MockRunAsAuthenticationToken true", - result); + assertEquals("HELLO org.acegisecurity.MockRunAsAuthenticationToken true", result); } public void testMethodCallWithoutRunAsReplacement() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")}); assertTrue(token.isAuthenticated()); SecurityContextHolder.getContext().setAuthentication(token); @@ -156,8 +183,7 @@ public class MethodSecurityInterceptorTests extends TestCase { String result = target.makeLowerCase("HELLO"); // Note we check the isAuthenticated remained true in following line - assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken true", - result); + assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken true", result); } public void testRejectionOfEmptySecurityContext() throws Exception { @@ -165,8 +191,7 @@ public class MethodSecurityInterceptorTests extends TestCase { try { target.makeUpperCase("hello"); - fail( - "Should have thrown AuthenticationCredentialsNotFoundException"); + fail("Should have thrown AuthenticationCredentialsNotFoundException"); } catch (AuthenticationCredentialsNotFoundException expected) { assertTrue(true); } @@ -191,8 +216,7 @@ public class MethodSecurityInterceptorTests extends TestCase { public void testRejectsCallsWhenAuthenticationIsIncorrect() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password"); assertTrue(!token.isAuthenticated()); SecurityContextHolder.getContext().setAuthentication(token); @@ -266,8 +290,7 @@ public class MethodSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An AccessDecisionManager is required", - expected.getMessage()); + assertEquals("An AccessDecisionManager is required", expected.getMessage()); } } @@ -284,8 +307,7 @@ public class MethodSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An AuthenticationManager is required", - expected.getMessage()); + assertEquals("An AuthenticationManager is required", expected.getMessage()); } } @@ -299,8 +321,7 @@ public class MethodSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An ObjectDefinitionSource is required", - expected.getMessage()); + assertEquals("An ObjectDefinitionSource is required", expected.getMessage()); } } @@ -384,66 +405,12 @@ public class MethodSecurityInterceptorTests extends TestCase { assertTrue(true); } - private ITargetObject makeInterceptedTarget() { - ApplicationContext context = new ClassPathXmlApplicationContext( - "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + //~ Inner Classes ================================================================================================== - return (ITargetObject) context.getBean("target"); - } - - private ITargetObject makeInterceptedTargetRejectsAuthentication() { - ApplicationContext context = new ClassPathXmlApplicationContext( - "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); - - MockAuthenticationManager authenticationManager = new MockAuthenticationManager(false); - MethodSecurityInterceptor si = (MethodSecurityInterceptor) context - .getBean("securityInterceptor"); - si.setAuthenticationManager(authenticationManager); - - return (ITargetObject) context.getBean("target"); - } - - private ITargetObject makeInterceptedTargetWithoutAnAfterInvocationManager() { - ApplicationContext context = new ClassPathXmlApplicationContext( - "org/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); - - MethodSecurityInterceptor si = (MethodSecurityInterceptor) context - .getBean("securityInterceptor"); - si.setAfterInvocationManager(null); - - return (ITargetObject) context.getBean("target"); - } - - //~ Inner Classes ========================================================== - - private class MockAccessDecisionManagerWhichOnlySupportsStrings - implements AccessDecisionManager { - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { - throw new UnsupportedOperationException( - "mock method not implemented"); - } - - public boolean supports(Class clazz) { - if (String.class.isAssignableFrom(clazz)) { - return true; - } else { - return false; - } - } - - public boolean supports(ConfigAttribute attribute) { - return true; - } - } - - private class MockAfterInvocationManagerWhichOnlySupportsStrings - implements AfterInvocationManager { - public Object decide(Authentication authentication, Object object, - ConfigAttributeDefinition config, Object returnedObject) + private class MockAccessDecisionManagerWhichOnlySupportsStrings implements AccessDecisionManager { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } public boolean supports(Class clazz) { @@ -459,12 +426,34 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - private class MockObjectDefinitionSourceWhichOnlySupportsStrings - extends AbstractMethodDefinitionSource { + private class MockAfterInvocationManagerWhichOnlySupportsStrings implements AfterInvocationManager { + public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, + Object returnedObject) throws AccessDeniedException { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public boolean supports(Class clazz) { + if (String.class.isAssignableFrom(clazz)) { + return true; + } else { + return false; + } + } + + public boolean supports(ConfigAttribute attribute) { + return true; + } + } + + private class MockObjectDefinitionSourceWhichOnlySupportsStrings extends AbstractMethodDefinitionSource { public Iterator getConfigAttributeDefinitions() { return null; } + protected ConfigAttributeDefinition lookupAttributes(Method method) { + throw new UnsupportedOperationException("mock method not implemented"); + } + public boolean supports(Class clazz) { if (String.class.isAssignableFrom(clazz)) { return true; @@ -472,19 +461,11 @@ public class MethodSecurityInterceptorTests extends TestCase { return false; } } - - protected ConfigAttributeDefinition lookupAttributes(Method method) { - throw new UnsupportedOperationException( - "mock method not implemented"); - } } - private class MockRunAsManagerWhichOnlySupportsStrings - implements RunAsManager { - public Authentication buildRunAs(Authentication authentication, - Object object, ConfigAttributeDefinition config) { - throw new UnsupportedOperationException( - "mock method not implemented"); + private class MockRunAsManagerWhichOnlySupportsStrings implements RunAsManager { + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) { + throw new UnsupportedOperationException("mock method not implemented"); } public boolean supports(Class clazz) { diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java index 2085dad878..0b6b7d0890 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ package org.acegisecurity.intercept.method.aspectj; -import java.lang.reflect.Method; - import junit.framework.TestCase; import org.acegisecurity.AccessDeniedException; @@ -28,11 +26,16 @@ import org.acegisecurity.MockAuthenticationManager; import org.acegisecurity.MockJoinPoint; import org.acegisecurity.MockRunAsManager; import org.acegisecurity.TargetObject; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.intercept.method.MethodDefinitionMap; import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor; + import org.acegisecurity.providers.TestingAuthenticationToken; +import java.lang.reflect.Method; + /** * Tests {@link AspectJSecurityInterceptor}. @@ -41,7 +44,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class AspectJSecurityInterceptorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AspectJSecurityInterceptorTests() { super(); @@ -51,16 +54,16 @@ public class AspectJSecurityInterceptorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AspectJSecurityInterceptorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCallbackIsInvokedWhenPermissionGranted() throws Exception { AspectJSecurityInterceptor si = new AspectJSecurityInterceptor(); @@ -70,8 +73,7 @@ public class AspectJSecurityInterceptorTests extends TestCase { si.setRunAsManager(new MockRunAsManager()); MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); + editor.setAsText("org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); si.setObjectDefinitionSource(map); @@ -80,14 +82,13 @@ public class AspectJSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); Class clazz = TargetObject.class; - Method method = clazz.getMethod("countLength", - new Class[] {String.class}); + Method method = clazz.getMethod("countLength", new Class[] {String.class}); MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); MockAspectJCallback aspectJCallback = new MockAspectJCallback(); - SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken( - "marissa", "koala", + SecurityContextHolder.getContext() + .setAuthentication(new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_ONE")})); Object result = si.invoke(joinPoint, aspectJCallback); @@ -106,8 +107,7 @@ public class AspectJSecurityInterceptorTests extends TestCase { si.setRunAsManager(new MockRunAsManager()); MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); - editor.setAsText( - "org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); + editor.setAsText("org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); si.setObjectDefinitionSource(map); @@ -115,15 +115,15 @@ public class AspectJSecurityInterceptorTests extends TestCase { si.afterPropertiesSet(); Class clazz = TargetObject.class; - Method method = clazz.getMethod("countLength", - new Class[] {String.class}); + Method method = clazz.getMethod("countLength", new Class[] {String.class}); MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); MockAspectJCallback aspectJCallback = new MockAspectJCallback(); aspectJCallback.setThrowExceptionIfInvoked(true); - SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken( - "marissa", "koala", new GrantedAuthority[] {})); + SecurityContextHolder.getContext() + .setAuthentication(new TestingAuthenticationToken("marissa", "koala", + new GrantedAuthority[] {})); try { si.invoke(joinPoint, aspectJCallback); @@ -135,17 +135,13 @@ public class AspectJSecurityInterceptorTests extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAspectJCallback implements AspectJCallback { private boolean throwExceptionIfInvoked = false; private MockAspectJCallback() {} - public void setThrowExceptionIfInvoked(boolean throwExceptionIfInvoked) { - this.throwExceptionIfInvoked = throwExceptionIfInvoked; - } - public Object proceedWithObject() { if (throwExceptionIfInvoked) { throw new IllegalStateException("AspectJCallback proceeded"); @@ -153,5 +149,9 @@ public class AspectJSecurityInterceptorTests extends TestCase { return "object proceeded"; } + + public void setThrowExceptionIfInvoked(boolean throwExceptionIfInvoked) { + this.throwExceptionIfInvoked = throwExceptionIfInvoked; + } } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSourceTests.java b/core/src/test/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSourceTests.java index 3d83117264..8e6a9d48e4 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSourceTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/AbstractFilterInvocationDefinitionSourceTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,8 @@ package org.acegisecurity.intercept.web; import junit.framework.TestCase; - - +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import java.io.IOException; @@ -27,10 +27,6 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - - /** * Tests {@link AbstractFilterInvocationDefinitionSource}. @@ -39,7 +35,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class AbstractFilterInvocationDefinitionSourceTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractFilterInvocationDefinitionSourceTests() { super(); @@ -49,25 +45,23 @@ public class AbstractFilterInvocationDefinitionSourceTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractFilterInvocationDefinitionSourceTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDoesNotSupportAnotherObject() { - MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, - true); + MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, true); assertFalse(mfis.supports(String.class)); } public void testGetAttributesForANonFilterInvocation() { - MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, - true); + MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, true); try { mfis.getAttributes(new String()); @@ -78,8 +72,7 @@ public class AbstractFilterInvocationDefinitionSourceTests extends TestCase { } public void testGetAttributesForANullObject() { - MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, - true); + MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, true); try { mfis.getAttributes(null); @@ -90,12 +83,10 @@ public class AbstractFilterInvocationDefinitionSourceTests extends TestCase { } public void testGetAttributesForFilterInvocationSuccess() { - MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, - true); + MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, true); try { - mfis.getAttributes(new FilterInvocation( - new MockHttpServletRequest(null, null), + mfis.getAttributes(new FilterInvocation(new MockHttpServletRequest(null, null), new MockHttpServletResponse(), new MockFilterChain())); fail("Should have thrown UnsupportedOperationException"); } catch (UnsupportedOperationException expected) { @@ -104,18 +95,16 @@ public class AbstractFilterInvocationDefinitionSourceTests extends TestCase { } public void testSupportsFilterInvocation() { - MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, - true); + MockFilterInvocationDefinitionSource mfis = new MockFilterInvocationDefinitionSource(false, true); assertTrue(mfis.supports(FilterInvocation.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorTests.java index a42d4e48be..b636184a03 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorTests.java @@ -28,14 +28,14 @@ import java.util.Iterator; /** - * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated - * default {@link RegExpBasedFilterInvocationDefinitionMap}. + * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated default {@link + * RegExpBasedFilterInvocationDefinitionMap}. * * @author Ben Alex * @version $Id$ */ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public FilterInvocationDefinitionSourceEditorTests() { super(); @@ -45,7 +45,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(FilterInvocationDefinitionSourceEditorTests.class); @@ -57,8 +57,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { public void testConvertUrlToLowercaseDefaultSettingUnchangedByEditor() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); + editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor .getValue(); @@ -73,8 +72,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT\r\n\\/secUre/super/**=ROLE_WE_DONT_HAVE"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage() - .lastIndexOf("you have specified an uppercase character in line") != -1); + assertTrue(expected.getMessage().lastIndexOf("you have specified an uppercase character in line") != -1); } } @@ -83,18 +81,15 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { editor.setAsText( "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\n\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); assertTrue(map.isConvertUrlToLowercaseBeforeComparison()); } public void testDefaultIsRegularExpression() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); + editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - FilterInvocationDefinitionMap map = (FilterInvocationDefinitionMap) editor - .getValue(); + FilterInvocationDefinitionMap map = (FilterInvocationDefinitionMap) editor.getValue(); assertTrue(map instanceof RegExpBasedFilterInvocationDefinitionMap); } @@ -106,8 +101,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT\r\n\\/secure/super/**=ROLE_WE_DONT_HAVE"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage() - .lastIndexOf("Line appears to be malformed") != -1); + assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); } } @@ -119,8 +113,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT /secure/super/**=ROLE_WE_DONT_HAVE"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage() - .lastIndexOf("Line appears to be malformed") != -1); + assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); } } @@ -132,8 +125,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { "PATTERN_TYPE_APACHE_ANT\r\nCONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON /secure/super/**=ROLE_WE_DONT_HAVE"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertTrue(expected.getMessage() - .lastIndexOf("Line appears to be malformed") != -1); + assertTrue(expected.getMessage().lastIndexOf("Line appears to be malformed") != -1); } } @@ -141,8 +133,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText(""); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(0, map.getMapSize()); } @@ -153,18 +144,15 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { try { editor.setAsText("*=SOME_ROLE"); } catch (IllegalArgumentException expected) { - assertEquals("Malformed regular expression: *", - expected.getMessage()); + assertEquals("Malformed regular expression: *", expected.getMessage()); } } public void testIterator() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); + editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); Iterator iter = map.getConfigAttributeDefinitions(); int counter = 0; @@ -180,27 +168,22 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/totally/different/path/index.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); assertEquals(null, returned); } public void testMultiUrlParsing() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); + editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(2, map.getMapSize()); } @@ -219,8 +202,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText(null); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(0, map.getMapSize()); } @@ -229,17 +211,14 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { editor.setAsText( "\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE\r\n\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); // Test ensures we match the first entry, not the second - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE")); @@ -253,16 +232,13 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { editor.setAsText( "\\A/secure/.*\\Z=ROLE_SUPERVISOR,ROLE_TELLER\r\n\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_SUPERVISOR")); @@ -275,16 +251,13 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText("\\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE")); @@ -298,8 +271,7 @@ public class FilterInvocationDefinitionSourceEditorTests extends TestCase { editor.setAsText( " \\A/secure/super.*\\Z=ROLE_WE_DONT_HAVE,ANOTHER_ROLE \r\n \r\n \r\n // comment line \r\n \\A/testing.*\\Z=ROLE_TEST \r\n"); - RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor - .getValue(); + RegExpBasedFilterInvocationDefinitionMap map = (RegExpBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(2, map.getMapSize()); } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorWithPathsTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorWithPathsTests.java index 1354fbf39a..dcf9e27514 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorWithPathsTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationDefinitionSourceEditorWithPathsTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,26 +19,23 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; - - import org.acegisecurity.SecurityConfig; -import java.util.Iterator; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import java.util.Iterator; + /** - * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated - * {@link PathBasedFilterInvocationDefinitionMap}. + * Tests {@link FilterInvocationDefinitionSourceEditor} and its associated {@link + * PathBasedFilterInvocationDefinitionMap}. * * @author Ben Alex * @version $Id$ */ -public class FilterInvocationDefinitionSourceEditorWithPathsTests - extends TestCase { - //~ Constructors =========================================================== +public class FilterInvocationDefinitionSourceEditorWithPathsTests extends TestCase { + //~ Constructors =================================================================================================== public FilterInvocationDefinitionSourceEditorWithPathsTests() { super(); @@ -48,23 +45,22 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(FilterInvocationDefinitionSourceEditorWithPathsTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAntPathDirectiveIsDetected() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - FilterInvocationDefinitionMap map = (FilterInvocationDefinitionMap) editor - .getValue(); + FilterInvocationDefinitionMap map = (FilterInvocationDefinitionMap) editor.getValue(); assertTrue(map instanceof PathBasedFilterInvocationDefinitionMap); } @@ -73,8 +69,7 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); assertFalse(map.isConvertUrlToLowercaseBeforeComparison()); } @@ -83,18 +78,26 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON\r\nPATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); assertTrue(map.isConvertUrlToLowercaseBeforeComparison()); } + public void testInvalidNameValueFailsToParse() { + FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); + + try { + // Use a "==" instead of an "=" + editor.setAsText(" PATTERN_TYPE_APACHE_ANT\r\n /secure/*==ROLE_SUPERVISOR,ROLE_TELLER \r\n"); + fail("Shouldn't be able to use '==' for config attribute."); + } catch (IllegalArgumentException expected) {} + } + public void testIterator() { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); Iterator iter = map.getConfigAttributeDefinitions(); int counter = 0; @@ -108,19 +111,15 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests public void testMapReturnsNullWhenNoMatchFound() throws Exception { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE"); + editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/totally/different/path/index.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); assertEquals(null, returned); } @@ -130,8 +129,7 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE\r\n/secure/*=ROLE_SUPERVISOR,ROLE_TELLER"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(2, map.getMapSize()); } @@ -139,7 +137,7 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests Class clazz = PathBasedFilterInvocationDefinitionMap.EntryHolder.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -151,17 +149,14 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/**=ROLE_WE_DONT_HAVE,ANOTHER_ROLE\r\n/secure/**=ROLE_SUPERVISOR,ROLE_TELLER"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); // Test ensures we match the first entry, not the second - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE")); @@ -175,16 +170,13 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( "PATTERN_TYPE_APACHE_ANT\r\n/secure/**=ROLE_SUPERVISOR,ROLE_TELLER\r\n/secure/super/**=ROLE_WE_DONT_HAVE"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_SUPERVISOR")); @@ -195,19 +187,15 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests public void testSingleUrlParsing() throws Exception { FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - editor.setAsText( - "PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); + editor.setAsText("PATTERN_TYPE_APACHE_ANT\r\n/secure/super/*=ROLE_WE_DONT_HAVE,ANOTHER_ROLE"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); - MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, - null); + MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null); httpRequest.setServletPath("/secure/super/very_secret.html"); - ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation( - httpRequest, new MockHttpServletResponse(), - new MockFilterChain())); + ConfigAttributeDefinition returned = map.getAttributes(new FilterInvocation(httpRequest, + new MockHttpServletResponse(), new MockFilterChain())); ConfigAttributeDefinition expected = new ConfigAttributeDefinition(); expected.addConfigAttribute(new SecurityConfig("ROLE_WE_DONT_HAVE")); @@ -221,18 +209,7 @@ public class FilterInvocationDefinitionSourceEditorWithPathsTests editor.setAsText( " PATTERN_TYPE_APACHE_ANT\r\n /secure/super/*=ROLE_WE_DONT_HAVE\r\n /secure/*=ROLE_SUPERVISOR,ROLE_TELLER \r\n \r\n \r\n // comment line \r\n \r\n"); - PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor - .getValue(); + PathBasedFilterInvocationDefinitionMap map = (PathBasedFilterInvocationDefinitionMap) editor.getValue(); assertEquals(2, map.getMapSize()); } - - public void testInvalidNameValueFailsToParse() { - FilterInvocationDefinitionSourceEditor editor = new FilterInvocationDefinitionSourceEditor(); - try { - // Use a "==" instead of an "=" - editor.setAsText(" PATTERN_TYPE_APACHE_ANT\r\n /secure/*==ROLE_SUPERVISOR,ROLE_TELLER \r\n"); - fail("Shouldn't be able to use '==' for config attribute."); - } catch(IllegalArgumentException expected) { - } - } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java index 9ef695a263..aff4287d45 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java @@ -34,7 +34,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class FilterInvocationTests extends MockObjectTestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public FilterInvocationTests() { super(); @@ -44,7 +44,7 @@ public class FilterInvocationTests extends MockObjectTestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(FilterInvocationTests.class); @@ -73,10 +73,8 @@ public class FilterInvocationTests extends MockObjectTestCase { assertEquals(response, fi.getHttpResponse()); assertEquals(chain, fi.getChain()); assertEquals("/HelloWorld/some/more/segments.html", fi.getRequestUrl()); - assertEquals("FilterInvocation: URL: /HelloWorld/some/more/segments.html", - fi.toString()); - assertEquals("http://www.example.com/mycontext/HelloWorld/some/more/segments.html", - fi.getFullRequestUrl()); + assertEquals("FilterInvocation: URL: /HelloWorld/some/more/segments.html", fi.toString()); + assertEquals("http://www.example.com/mycontext/HelloWorld/some/more/segments.html", fi.getFullRequestUrl()); } public void testNoArgConstructorDoesntExist() { @@ -135,8 +133,7 @@ public class FilterInvocationTests extends MockObjectTestCase { new FilterInvocation(request, response, chain); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -149,8 +146,7 @@ public class FilterInvocationTests extends MockObjectTestCase { new FilterInvocation(request, response, chain); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } @@ -169,8 +165,7 @@ public class FilterInvocationTests extends MockObjectTestCase { FilterInvocation fi = new FilterInvocation(request, response, chain); assertEquals("/HelloWorld?foo=bar", fi.getRequestUrl()); assertEquals("FilterInvocation: URL: /HelloWorld?foo=bar", fi.toString()); - assertEquals("http://www.example.com/mycontext/HelloWorld?foo=bar", - fi.getFullRequestUrl()); + assertEquals("http://www.example.com/mycontext/HelloWorld?foo=bar", fi.getFullRequestUrl()); } public void testStringMethodsWithoutAnyQueryString() { @@ -187,7 +182,6 @@ public class FilterInvocationTests extends MockObjectTestCase { FilterInvocation fi = new FilterInvocation(request, response, chain); assertEquals("/HelloWorld", fi.getRequestUrl()); assertEquals("FilterInvocation: URL: /HelloWorld", fi.toString()); - assertEquals("http://www.example.com/mycontext/HelloWorld", - fi.getFullRequestUrl()); + assertEquals("http://www.example.com/mycontext/HelloWorld", fi.getFullRequestUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java index a7920e605f..622e807c4e 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java @@ -55,7 +55,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class FilterSecurityInterceptorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public FilterSecurityInterceptorTests() { super(); @@ -65,7 +65,7 @@ public class FilterSecurityInterceptorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(FilterSecurityInterceptorTests.class); @@ -91,11 +91,9 @@ public class FilterSecurityInterceptorTests extends TestCase { return true; } - public void decide(Authentication authentication, - Object object, ConfigAttributeDefinition config) + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } }); @@ -124,11 +122,9 @@ public class FilterSecurityInterceptorTests extends TestCase { return true; } - public Authentication buildRunAs( - Authentication authentication, Object object, + public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } }); @@ -148,15 +144,13 @@ public class FilterSecurityInterceptorTests extends TestCase { interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setRunAsManager(new MockRunAsManager()); - interceptor.setApplicationEventPublisher(MockApplicationContext - .getContext()); + interceptor.setApplicationEventPublisher(MockApplicationContext.getContext()); // Setup a mock config attribute definition ConfigAttributeDefinition def = new ConfigAttributeDefinition(); def.addConfigAttribute(new SecurityConfig("MOCK_OK")); - MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html", - def); + MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html", def); interceptor.setObjectDefinitionSource(mockSource); // Setup our expectation that the filter chain will be invoked, as access is granted @@ -170,8 +164,7 @@ public class FilterSecurityInterceptorTests extends TestCase { request.setServerPort(443); // Setup a Context - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_OK")}); SecurityContextHolder.getContext().setAuthentication(token); @@ -197,9 +190,8 @@ public class FilterSecurityInterceptorTests extends TestCase { } /** - * We just test invocation works in a success event. There is no need to - * test access denied events as the abstract parent enforces that logic, - * which is extensively tested separately. + * We just test invocation works in a success event. There is no need to test access denied events as the + * abstract parent enforces that logic, which is extensively tested separately. * * @throws Throwable DOCUMENT ME! */ @@ -209,15 +201,13 @@ public class FilterSecurityInterceptorTests extends TestCase { interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setRunAsManager(new MockRunAsManager()); - interceptor.setApplicationEventPublisher(MockApplicationContext - .getContext()); + interceptor.setApplicationEventPublisher(MockApplicationContext.getContext()); // Setup a mock config attribute definition ConfigAttributeDefinition def = new ConfigAttributeDefinition(); def.addConfigAttribute(new SecurityConfig("MOCK_OK")); - MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html", - def); + MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html", def); interceptor.setObjectDefinitionSource(mockSource); // Setup our expectation that the filter chain will be invoked, as access is granted @@ -229,8 +219,7 @@ public class FilterSecurityInterceptorTests extends TestCase { request.setServletPath("/secure/page.html"); // Setup a Context - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_OK")}); SecurityContextHolder.getContext().setAuthentication(token); @@ -242,7 +231,7 @@ public class FilterSecurityInterceptorTests extends TestCase { SecurityContextHolder.clearContext(); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private boolean expectToProceed; @@ -265,13 +254,11 @@ public class FilterSecurityInterceptorTests extends TestCase { } } - private class MockFilterInvocationDefinitionMap - implements FilterInvocationDefinitionSource { + private class MockFilterInvocationDefinitionMap implements FilterInvocationDefinitionSource { private ConfigAttributeDefinition toReturn; private String servletPath; - public MockFilterInvocationDefinitionMap(String servletPath, - ConfigAttributeDefinition toReturn) { + public MockFilterInvocationDefinitionMap(String servletPath, ConfigAttributeDefinition toReturn) { this.servletPath = servletPath; this.toReturn = toReturn; } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/MockFilterInvocationDefinitionSource.java b/core/src/test/java/org/acegisecurity/intercept/web/MockFilterInvocationDefinitionSource.java index efc08d1e8f..7d0a60f0af 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/MockFilterInvocationDefinitionSource.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/MockFilterInvocationDefinitionSource.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,17 +29,15 @@ import java.util.Vector; * @author Ben Alex * @version $Id$ */ -public class MockFilterInvocationDefinitionSource - extends AbstractFilterInvocationDefinitionSource { - //~ Instance fields ======================================================== +public class MockFilterInvocationDefinitionSource extends AbstractFilterInvocationDefinitionSource { + //~ Instance fields ================================================================================================ private List list; private boolean returnAnIterator; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public MockFilterInvocationDefinitionSource( - boolean includeInvalidAttributes, boolean returnAnIteratorWhenRequested) { + public MockFilterInvocationDefinitionSource(boolean includeInvalidAttributes, boolean returnAnIteratorWhenRequested) { returnAnIterator = returnAnIteratorWhenRequested; list = new Vector(); @@ -71,7 +69,7 @@ public class MockFilterInvocationDefinitionSource super(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Iterator getConfigAttributeDefinitions() { if (returnAnIterator) { diff --git a/core/src/test/java/org/acegisecurity/intercept/web/PathBasedFilterDefinitionMapTests.java b/core/src/test/java/org/acegisecurity/intercept/web/PathBasedFilterDefinitionMapTests.java index 7de936fafa..789bf582e5 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/PathBasedFilterDefinitionMapTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/PathBasedFilterDefinitionMapTests.java @@ -26,14 +26,14 @@ import org.springframework.mock.web.MockHttpServletResponse; /** - * Tests parts of {@link PathBasedFilterInvocationDefinitionMap} not tested by - * {@link FilterInvocationDefinitionSourceEditorWithPathsTests}. + * Tests parts of {@link PathBasedFilterInvocationDefinitionMap} not tested by {@link + * FilterInvocationDefinitionSourceEditorWithPathsTests}. * * @author Ben Alex * @version $Id$ */ public class PathBasedFilterDefinitionMapTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PathBasedFilterDefinitionMapTests() { super(); @@ -43,7 +43,7 @@ public class PathBasedFilterDefinitionMapTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(PathBasedFilterDefinitionMapTests.class); @@ -80,11 +80,9 @@ public class PathBasedFilterDefinitionMapTests extends TestCase { MockHttpServletRequest req = request; req.setServletPath("/SeCuRE/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(def, response); } @@ -103,11 +101,9 @@ public class PathBasedFilterDefinitionMapTests extends TestCase { MockHttpServletRequest req = request; req.setServletPath("/SeCuRE/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(null, response); } @@ -126,11 +122,9 @@ public class PathBasedFilterDefinitionMapTests extends TestCase { MockHttpServletRequest req = request; req.setServletPath("/secure/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(def, response); } @@ -149,11 +143,9 @@ public class PathBasedFilterDefinitionMapTests extends TestCase { MockHttpServletRequest req = request; req.setServletPath("/someAdminPage.html?a=/test"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(def, response); // see SEC-161 (it should truncate after ? sign) } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/RegExpBasedFilterDefinitionMapTests.java b/core/src/test/java/org/acegisecurity/intercept/web/RegExpBasedFilterDefinitionMapTests.java index 9790587c69..6143bd3791 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/RegExpBasedFilterDefinitionMapTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/RegExpBasedFilterDefinitionMapTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; - - import org.acegisecurity.SecurityConfig; import org.springframework.mock.web.MockHttpServletRequest; @@ -28,14 +26,14 @@ import org.springframework.mock.web.MockHttpServletResponse; /** - * Tests parts of {@link RegExpBasedFilterInvocationDefinitionMap} not tested - * by {@link FilterInvocationDefinitionSourceEditorTests}. + * Tests parts of {@link RegExpBasedFilterInvocationDefinitionMap} not tested by {@link + * FilterInvocationDefinitionSourceEditorTests}. * * @author Ben Alex * @version $Id$ */ public class RegExpBasedFilterDefinitionMapTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RegExpBasedFilterDefinitionMapTests() { super(); @@ -45,16 +43,16 @@ public class RegExpBasedFilterDefinitionMapTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RegExpBasedFilterDefinitionMapTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConvertUrlToLowercaseIsFalseByDefault() { RegExpBasedFilterInvocationDefinitionMap map = new RegExpBasedFilterInvocationDefinitionMap(); assertFalse(map.isConvertUrlToLowercaseBeforeComparison()); @@ -78,14 +76,13 @@ public class RegExpBasedFilterDefinitionMapTests extends TestCase { // Build a HTTP request MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI(null); + MockHttpServletRequest req = request; req.setServletPath("/SeCuRE/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(def, response); } @@ -100,14 +97,13 @@ public class RegExpBasedFilterDefinitionMapTests extends TestCase { // Build a HTTP request MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI(null); + MockHttpServletRequest req = request; req.setServletPath("/SeCuRE/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(null, response); } @@ -122,14 +118,13 @@ public class RegExpBasedFilterDefinitionMapTests extends TestCase { // Build a HTTP request MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI(null); + MockHttpServletRequest req = request; req.setServletPath("/secure/super/somefile.html"); - FilterInvocation fi = new FilterInvocation(req, - new MockHttpServletResponse(), new MockFilterChain()); + FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain()); - ConfigAttributeDefinition response = map.lookupAttributes(fi - .getRequestUrl()); + ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl()); assertEquals(def, response); } } diff --git a/core/src/test/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluatorTests.java b/core/src/test/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluatorTests.java index 07b99a7465..7365b8d9d9 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluatorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/WebInvocationPrivilegeEvaluatorTests.java @@ -29,14 +29,13 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * Tests {@link - * org.acegisecurity.intercept.web.WebInvocationPrivilegeEvaluator}. + * Tests {@link org.acegisecurity.intercept.web.WebInvocationPrivilegeEvaluator}. * * @author Ben Alex * @version $Id$ */ public class WebInvocationPrivilegeEvaluatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public WebInvocationPrivilegeEvaluatorTests() { super(); @@ -46,7 +45,7 @@ public class WebInvocationPrivilegeEvaluatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(WebInvocationPrivilegeEvaluatorTests.class); @@ -56,13 +55,11 @@ public class WebInvocationPrivilegeEvaluatorTests extends TestCase { ApplicationContext context = new ClassPathXmlApplicationContext( "org/acegisecurity/intercept/web/applicationContext.xml"); - return (FilterSecurityInterceptor) context.getBean( - "securityInterceptor"); + return (FilterSecurityInterceptor) context.getBean("securityInterceptor"); } public void testAllowsAccess1() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INDEX")}); FilterInvocation fi = FilterInvocationUtils.create("/foo/index.jsp"); FilterSecurityInterceptor interceptor = makeFilterSecurityInterceptor(); @@ -75,8 +72,7 @@ public class WebInvocationPrivilegeEvaluatorTests extends TestCase { } public void testAllowsAccess2() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_USER")}); FilterInvocation fi = FilterInvocationUtils.create("/anything.jsp"); FilterSecurityInterceptor interceptor = makeFilterSecurityInterceptor(); @@ -89,8 +85,7 @@ public class WebInvocationPrivilegeEvaluatorTests extends TestCase { } public void testDeniesAccess1() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NOTHING_USEFUL")}); FilterInvocation fi = FilterInvocationUtils.create("/anything.jsp"); FilterSecurityInterceptor interceptor = makeFilterSecurityInterceptor(); diff --git a/core/src/test/java/org/acegisecurity/ldap/AbstractLdapServerTestCase.java b/core/src/test/java/org/acegisecurity/ldap/AbstractLdapServerTestCase.java index e937fe1271..79b0df4906 100644 --- a/core/src/test/java/org/acegisecurity/ldap/AbstractLdapServerTestCase.java +++ b/core/src/test/java/org/acegisecurity/ldap/AbstractLdapServerTestCase.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,21 @@ package org.acegisecurity.ldap; import junit.framework.TestCase; -import java.util.Hashtable; - import org.apache.directory.server.core.jndi.CoreContextFactory; +import java.util.Hashtable; + + /** + * +DOCUMENT ME! + * * @author Luke Taylor * @version $Id$ */ public abstract class AbstractLdapServerTestCase extends TestCase { + //~ Static fields/initializers ===================================================================================== + private static final String ROOT_DN = "dc=acegisecurity,dc=org"; protected static final String MANAGER_USER = "cn=manager," + ROOT_DN; protected static final String MANAGER_PASSWORD = "acegisecurity"; @@ -35,21 +41,31 @@ public abstract class AbstractLdapServerTestCase extends TestCase { // private static final String CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; // private static final Hashtable EXTRA_ENV = new Hashtable(); - // Embedded (non-networked) server config private static final LdapTestServer SERVER = new LdapTestServer(); private static final String PROVIDER_URL = ROOT_DN; private static final String CONTEXT_FACTORY = CoreContextFactory.class.getName(); private static final Hashtable EXTRA_ENV = SERVER.getConfiguration().toJndiEnvironment(); - protected AbstractLdapServerTestCase() { - } + //~ Instance fields ================================================================================================ + + private DefaultInitialDirContextFactory idf; + + //~ Constructors =================================================================================================== + + protected AbstractLdapServerTestCase() {} protected AbstractLdapServerTestCase(String string) { super(string); } - private DefaultInitialDirContextFactory idf; + //~ Methods ======================================================================================================== + + protected DefaultInitialDirContextFactory getInitialCtxFactory() { + return idf; + } + + protected void onSetUp() {} public final void setUp() { idf = new DefaultInitialDirContextFactory(PROVIDER_URL); @@ -58,10 +74,4 @@ public abstract class AbstractLdapServerTestCase extends TestCase { onSetUp(); } - - protected void onSetUp() {} - - protected DefaultInitialDirContextFactory getInitialCtxFactory() { - return idf; - } } diff --git a/core/src/test/java/org/acegisecurity/ldap/DefaultInitialDirContextFactoryTests.java b/core/src/test/java/org/acegisecurity/ldap/DefaultInitialDirContextFactoryTests.java index dd705f165d..b7b023e896 100644 --- a/core/src/test/java/org/acegisecurity/ldap/DefaultInitialDirContextFactoryTests.java +++ b/core/src/test/java/org/acegisecurity/ldap/DefaultInitialDirContextFactoryTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ package org.acegisecurity.ldap; -import javax.naming.Context; -import javax.naming.directory.DirContext; +import org.acegisecurity.AcegiMessageSource; +import org.acegisecurity.BadCredentialsException; + import java.util.Hashtable; -import org.acegisecurity.BadCredentialsException; -import org.acegisecurity.AcegiMessageSource; +import javax.naming.Context; +import javax.naming.directory.DirContext; + /** * Tests {@link org.acegisecurity.ldap.DefaultInitialDirContextFactory}. @@ -29,52 +31,17 @@ import org.acegisecurity.AcegiMessageSource; * @version $Id$ */ public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTestCase { + //~ Instance fields ================================================================================================ + DefaultInitialDirContextFactory idf; + //~ Methods ======================================================================================================== + public void onSetUp() { idf = getInitialCtxFactory(); idf.setMessageSource(new AcegiMessageSource()); } -// public void testNonLdapUrlIsRejected() throws Exception { -// DefaultInitialDirContextFactory idf = new DefaultInitialDirContextFactory(); -// -// idf.setUrl("http://acegisecurity.org/dc=acegisecurity,dc=org"); -// idf.setInitialContextFactory(CoreContextFactory.class.getName()); -// -// try { -// idf.afterPropertiesSet(); -// fail("Expected exception for non 'ldap://' URL"); -// } catch(IllegalArgumentException expected) { -// } -// } - - public void testServiceLocationUrlIsSupported() { - idf = new DefaultInitialDirContextFactory("ldap:///dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); - } - - public void testSecureLdapUrlIsSupported() { - idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); - } - - public void testConnectionFailure() throws Exception { - // Use the wrong port - idf = new DefaultInitialDirContextFactory("ldap://localhost:60389"); - idf.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory"); - Hashtable env = new Hashtable(); - env.put("com.sun.jndi.ldap.connect.timeout", "200"); - idf.setExtraEnvVars(env); - idf.setUseConnectionPool(false); // coverage purposes only - - try { - idf.newInitialDirContext(); - fail("Connection succeeded unexpectedly"); - } catch(LdapDataAccessException expected) { - } - } - public void testAnonymousBindSucceeds() throws Exception { DirContext ctx = idf.newInitialDirContext(); // Connection pooling should be set by default for anon users. @@ -83,6 +50,36 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTest ctx.close(); } + public void testBaseDnIsParsedFromCorrectlyFromUrl() { + idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org"); + assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + + // Check with an empty root + idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/"); + assertEquals("", idf.getRootDn()); + + // Empty root without trailing slash + idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org"); + assertEquals("", idf.getRootDn()); + } + + public void testBindAsManagerFailsIfNoPasswordSet() + throws Exception { + idf.setManagerDn(MANAGER_USER); + + DirContext ctx = null; + + try { + ctx = idf.newInitialDirContext(); + fail("Binding with no manager password should fail."); + +// Can't rely on this property being there with embedded server +// assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool")); + } catch (BadCredentialsException expected) {} + + LdapUtils.closeContext(ctx); + } + public void testBindAsManagerSucceeds() throws Exception { idf.setManagerPassword(MANAGER_PASSWORD); idf.setManagerDn(MANAGER_USER); @@ -93,45 +90,31 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTest ctx.close(); } - public void testBindAsManagerFailsIfNoPasswordSet() throws Exception { - idf.setManagerDn(MANAGER_USER); - - DirContext ctx = null; - - try { - ctx = idf.newInitialDirContext(); - fail("Binding with no manager password should fail."); -// Can't rely on this property being there with embedded server -// assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool")); - } catch(BadCredentialsException expected) { - } - - LdapUtils.closeContext(ctx); - } - - public void testInvalidPasswordCausesBadCredentialsException() throws Exception { - idf.setManagerDn(MANAGER_USER); - idf.setManagerPassword("wrongpassword"); - - DirContext ctx = null; - try { - ctx = idf.newInitialDirContext(); - fail("Binding with wrong credentials should fail."); - } catch(BadCredentialsException expected) { - } - - LdapUtils.closeContext(ctx); - } - - public void testConnectionAsSpecificUserSucceeds() throws Exception { - DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=acegisecurity,dc=org", - "bobspassword"); + public void testConnectionAsSpecificUserSucceeds() + throws Exception { + DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=acegisecurity,dc=org", "bobspassword"); // We don't want pooling for specific users. // assertNull(ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool")); // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); ctx.close(); } + public void testConnectionFailure() throws Exception { + // Use the wrong port + idf = new DefaultInitialDirContextFactory("ldap://localhost:60389"); + idf.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory"); + + Hashtable env = new Hashtable(); + env.put("com.sun.jndi.ldap.connect.timeout", "200"); + idf.setExtraEnvVars(env); + idf.setUseConnectionPool(false); // coverage purposes only + + try { + idf.newInitialDirContext(); + fail("Connection succeeded unexpectedly"); + } catch (LdapDataAccessException expected) {} + } + public void testEnvironment() { idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/"); @@ -139,7 +122,7 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTest Hashtable env = idf.getEnvironment(); //assertEquals("com.sun.jndi.ldap.LdapCtxFactory", env.get(Context.INITIAL_CONTEXT_FACTORY)); assertEquals("ldap://acegisecurity.org/", env.get(Context.PROVIDER_URL)); - assertEquals("simple",env.get(Context.SECURITY_AUTHENTICATION)); + assertEquals("simple", env.get(Context.SECURITY_AUTHENTICATION)); assertNull(env.get(Context.SECURITY_PRINCIPAL)); assertNull(env.get(Context.SECURITY_CREDENTIALS)); @@ -161,30 +144,53 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTest assertEquals("extravarvalue", env.get("extravar")); } - public void testBaseDnIsParsedFromCorrectlyFromUrl() { - idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + public void testInvalidPasswordCausesBadCredentialsException() + throws Exception { + idf.setManagerDn(MANAGER_USER); + idf.setManagerPassword("wrongpassword"); - // Check with an empty root - idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/"); - assertEquals("", idf.getRootDn()); + DirContext ctx = null; - // Empty root without trailing slash - idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org"); - assertEquals("", idf.getRootDn()); + try { + ctx = idf.newInitialDirContext(); + fail("Binding with wrong credentials should fail."); + } catch (BadCredentialsException expected) {} + + LdapUtils.closeContext(ctx); } public void testMultipleProviderUrlsAreAccepted() { - idf = new DefaultInitialDirContextFactory("ldaps://acegisecurity.org/dc=acegisecurity,dc=org " + - "ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org"); + idf = new DefaultInitialDirContextFactory("ldaps://acegisecurity.org/dc=acegisecurity,dc=org " + + "ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org"); } public void testMultipleProviderUrlsWithDifferentRootsAreRejected() { try { - idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org " + - "ldap://monkeymachine.co.uk/dc=someotherplace,dc=org"); + idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org " + + "ldap://monkeymachine.co.uk/dc=someotherplace,dc=org"); fail("Different root DNs should cause an exception"); - } catch (IllegalArgumentException expected) { - } + } catch (IllegalArgumentException expected) {} + } + + public void testSecureLdapUrlIsSupported() { + idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=acegisecurity,dc=org"); + assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + } + +// public void testNonLdapUrlIsRejected() throws Exception { +// DefaultInitialDirContextFactory idf = new DefaultInitialDirContextFactory(); +// +// idf.setUrl("http://acegisecurity.org/dc=acegisecurity,dc=org"); +// idf.setInitialContextFactory(CoreContextFactory.class.getName()); +// +// try { +// idf.afterPropertiesSet(); +// fail("Expected exception for non 'ldap://' URL"); +// } catch(IllegalArgumentException expected) { +// } +// } + public void testServiceLocationUrlIsSupported() { + idf = new DefaultInitialDirContextFactory("ldap:///dc=acegisecurity,dc=org"); + assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); } } diff --git a/core/src/test/java/org/acegisecurity/ldap/LdapTemplateTests.java b/core/src/test/java/org/acegisecurity/ldap/LdapTemplateTests.java index 4d1226bd78..2fe795c78d 100644 --- a/core/src/test/java/org/acegisecurity/ldap/LdapTemplateTests.java +++ b/core/src/test/java/org/acegisecurity/ldap/LdapTemplateTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,43 +15,68 @@ package org.acegisecurity.ldap; -import javax.naming.directory.DirContext; -import javax.naming.NamingException; import java.util.Set; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; + + /** + * +DOCUMENT ME! * * @author Luke Taylor * @version $Id$ */ public class LdapTemplateTests extends AbstractLdapServerTestCase { + //~ Instance fields ================================================================================================ + private LdapTemplate template; + //~ Methods ======================================================================================================== + protected void onSetUp() { getInitialCtxFactory().setManagerDn(MANAGER_USER); getInitialCtxFactory().setManagerPassword(MANAGER_PASSWORD); template = new LdapTemplate(getInitialCtxFactory()); } + public void testCompareOfCorrectByteValueSucceeds() { +// Doesn't work with embedded server due to bugs in apacheds +// assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("bobspassword"))); + } public void testCompareOfCorrectValueSucceeds() { assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "bob")); } + public void testCompareOfWrongByteValueFails() { +// Doesn't work with embedded server due to bugs in apacheds +// assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue"))); + } + public void testCompareOfWrongValueFails() { assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "wrongvalue")); } - public void testCompareOfCorrectByteValueSucceeds() { - -// Doesn't work with embedded server due to bugs in apacheds -// assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("bobspassword"))); + public void testNameExistsForInValidNameFails() { + assertFalse(template.nameExists("ou=doesntexist,dc=acegisecurity,dc=org")); } - public void testCompareOfWrongByteValueFails() { + public void testNameExistsForValidNameSucceeds() { + assertTrue(template.nameExists("ou=groups,dc=acegisecurity,dc=org")); + } -// Doesn't work with embedded server due to bugs in apacheds -// assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue"))); + public void testNamingExceptionIsTranslatedCorrectly() { + try { + template.execute(new LdapCallback() { + public Object doInDirContext(DirContext dirContext) + throws NamingException { + throw new NamingException(); + } + }); + fail("Expected LdapDataAccessException on NamingException"); + } catch (LdapDataAccessException expected) {} } public void testSearchForSingleAttributeValues() { @@ -63,26 +88,4 @@ public class LdapTemplateTests extends AbstractLdapServerTestCase { assertTrue(values.contains("developer")); assertTrue(values.contains("manager")); } - - public void testNameExistsForValidNameSucceeds() { - assertTrue(template.nameExists("ou=groups,dc=acegisecurity,dc=org")); - } - - public void testNameExistsForInValidNameFails() { - assertFalse(template.nameExists("ou=doesntexist,dc=acegisecurity,dc=org")); - } - - public void testNamingExceptionIsTranslatedCorrectly() { - try { - template.execute(new LdapCallback() { - - public Object doInDirContext(DirContext dirContext) throws NamingException { - throw new NamingException(); - } - }); - fail("Expected LdapDataAccessException on NamingException"); - } - catch(LdapDataAccessException expected) { - } - } } diff --git a/core/src/test/java/org/acegisecurity/ldap/LdapTestServer.java b/core/src/test/java/org/acegisecurity/ldap/LdapTestServer.java index ce5f29f2cb..dc616bb759 100644 --- a/core/src/test/java/org/acegisecurity/ldap/LdapTestServer.java +++ b/core/src/test/java/org/acegisecurity/ldap/LdapTestServer.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,49 +15,47 @@ package org.acegisecurity.ldap; -import org.apache.directory.server.core.configuration.MutableStartupConfiguration; -import org.apache.directory.server.core.configuration.MutableDirectoryPartitionConfiguration; import org.apache.directory.server.core.configuration.Configuration; +import org.apache.directory.server.core.configuration.MutableDirectoryPartitionConfiguration; +import org.apache.directory.server.core.configuration.MutableStartupConfiguration; import org.apache.directory.server.core.jndi.CoreContextFactory; import org.apache.directory.server.core.partition.DirectoryPartitionNexus; -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.NameAlreadyBoundException; -import javax.naming.directory.InitialDirContext; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttributes; -import javax.naming.directory.Attribute; -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.DirContext; -import java.util.Properties; -import java.util.Set; -import java.util.HashSet; import java.io.File; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import javax.naming.Context; +import javax.naming.NameAlreadyBoundException; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + + /** - * An embedded LDAP test server, complete with test data for running the - * unit tests against. + * An embedded LDAP test server, complete with test data for running the unit tests against. * * @author Luke Taylor * @version $Id$ */ public class LdapTestServer { - - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private DirContext serverContext; + // Move the working dir to the temp directory + private File workingDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "apacheds-work"); private MutableStartupConfiguration cfg; - // Move the working dir to the temp directory - private File workingDir = new File( System.getProperty("java.io.tmpdir") - + File.separator + "apacheds-work" ); + //~ Constructors =================================================================================================== - - //~ Constructors ================================================================ - - /** +/** * Starts up and configures ApacheDS. */ public LdapTestServer() { @@ -66,125 +64,28 @@ public class LdapTestServer { initTestData(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private void startLdapServer() { - - cfg = new MutableStartupConfiguration(); - ((MutableStartupConfiguration)cfg).setWorkingDirectory(workingDir); - - System.out.println("Working directory is " + workingDir.getAbsolutePath()); - - Properties env = new Properties(); - - env.setProperty( Context.PROVIDER_URL, "dc=acegisecurity,dc=org" ); - env.setProperty( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName()); - env.setProperty( Context.SECURITY_AUTHENTICATION, "simple"); - env.setProperty( Context.SECURITY_PRINCIPAL, DirectoryPartitionNexus.ADMIN_PRINCIPAL); - env.setProperty( Context.SECURITY_CREDENTIALS, DirectoryPartitionNexus.ADMIN_PASSWORD); - - try { - initConfiguration(); - env.putAll( cfg.toJndiEnvironment() ); - serverContext = new InitialDirContext( env ); - } catch (NamingException e) { - System.err.println("Failed to start Apache DS"); - e.printStackTrace(); - } - } - - private void initTestData() { - createOu("people"); - createOu("groups"); - createUser("bob","Bob Hamilton", "bobspassword"); - createUser("ben","Ben Alex", "{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ="); - String[] developers = new String[] - {"uid=ben,ou=people,dc=acegisecurity,dc=org", "uid=bob,ou=people,dc=acegisecurity,dc=org"}; - createGroup("developers","developer",developers); - createGroup("managers","manager", new String[] { developers[0]}); - } - - private void createManagerUser() { - Attributes user = new BasicAttributes( "cn", "manager" , true ); - user.put( "userPassword", "acegisecurity" ); - Attribute objectClass = new BasicAttribute("objectClass"); - user.put( objectClass ); - objectClass.add( "top" ); - objectClass.add( "person" ); - objectClass.add( "organizationalPerson" ); - objectClass.add( "inetOrgPerson" ); - user.put( "sn", "Manager" ); - user.put( "cn", "manager" ); - try { - serverContext.createSubcontext("cn=manager", user ); - } catch(NameAlreadyBoundException ignore) { - // System.out.println("Manager user already exists."); - } catch (NamingException ne) { - System.err.println("Failed to create manager user."); - ne.printStackTrace(); - } - } - - public void createUser( String uid, String cn, String password ) { - Attributes user = new BasicAttributes("uid", uid); - user.put( "cn", cn); - user.put( "userPassword", LdapUtils.getUtf8Bytes(password) ); - Attribute objectClass = new BasicAttribute( "objectClass" ); - user.put( objectClass ); - objectClass.add( "top" ); - objectClass.add( "person" ); - objectClass.add( "organizationalPerson" ); - objectClass.add( "inetOrgPerson" ); - user.put( "sn", uid ); - - try { - serverContext.createSubcontext( "uid="+uid+",ou=people", user ); - } catch(NameAlreadyBoundException ignore) { -// System.out.println(" user " + uid + " already exists."); - } catch (NamingException ne) { - System.err.println("Failed to create user."); - ne.printStackTrace(); - } - } - - public void createOu(String name) { - Attributes ou = new BasicAttributes( "ou", name ); - Attribute objectClass = new BasicAttribute( "objectClass" ); - objectClass.add("top"); - objectClass.add("organizationalUnit"); - ou.put(objectClass); - - try { - serverContext.createSubcontext( "ou="+name, ou); - } catch(NameAlreadyBoundException ignore) { - // System.out.println(" ou " + name + " already exists."); - } catch (NamingException ne) { - System.err.println("Failed to create ou."); - ne.printStackTrace(); - } - - } - - public void createGroup( String cn, String ou, String[] memberDns ) { + public void createGroup(String cn, String ou, String[] memberDns) { Attributes group = new BasicAttributes("cn", cn); Attribute members = new BasicAttribute("member"); Attribute orgUnit = new BasicAttribute("ou", ou); - for(int i=0; i < memberDns.length; i++) { + for (int i = 0; i < memberDns.length; i++) { members.add(memberDns[i]); } - Attribute objectClass = new BasicAttribute( "objectClass" ); - objectClass.add( "top" ); - objectClass.add( "groupOfNames" ); + Attribute objectClass = new BasicAttribute("objectClass"); + objectClass.add("top"); + objectClass.add("groupOfNames"); group.put(objectClass); group.put(members); group.put(orgUnit); try { - serverContext.createSubcontext( "cn="+cn+",ou=groups", group ); - } catch(NameAlreadyBoundException ignore) { + serverContext.createSubcontext("cn=" + cn + ",ou=groups", group); + } catch (NameAlreadyBoundException ignore) { // System.out.println(" group " + cn + " already exists."); } catch (NamingException ne) { System.err.println("Failed to create group."); @@ -192,12 +93,79 @@ public class LdapTestServer { } } - private void initConfiguration() throws NamingException { + private void createManagerUser() { + Attributes user = new BasicAttributes("cn", "manager", true); + user.put("userPassword", "acegisecurity"); + Attribute objectClass = new BasicAttribute("objectClass"); + user.put(objectClass); + objectClass.add("top"); + objectClass.add("person"); + objectClass.add("organizationalPerson"); + objectClass.add("inetOrgPerson"); + user.put("sn", "Manager"); + user.put("cn", "manager"); + + try { + serverContext.createSubcontext("cn=manager", user); + } catch (NameAlreadyBoundException ignore) { + // System.out.println("Manager user already exists."); + } catch (NamingException ne) { + System.err.println("Failed to create manager user."); + ne.printStackTrace(); + } + } + + public void createOu(String name) { + Attributes ou = new BasicAttributes("ou", name); + Attribute objectClass = new BasicAttribute("objectClass"); + objectClass.add("top"); + objectClass.add("organizationalUnit"); + ou.put(objectClass); + + try { + serverContext.createSubcontext("ou=" + name, ou); + } catch (NameAlreadyBoundException ignore) { + // System.out.println(" ou " + name + " already exists."); + } catch (NamingException ne) { + System.err.println("Failed to create ou."); + ne.printStackTrace(); + } + } + + public void createUser(String uid, String cn, String password) { + Attributes user = new BasicAttributes("uid", uid); + user.put("cn", cn); + user.put("userPassword", LdapUtils.getUtf8Bytes(password)); + + Attribute objectClass = new BasicAttribute("objectClass"); + user.put(objectClass); + objectClass.add("top"); + objectClass.add("person"); + objectClass.add("organizationalPerson"); + objectClass.add("inetOrgPerson"); + user.put("sn", uid); + + try { + serverContext.createSubcontext("uid=" + uid + ",ou=people", user); + } catch (NameAlreadyBoundException ignore) { +// System.out.println(" user " + uid + " already exists."); + } catch (NamingException ne) { + System.err.println("Failed to create user."); + ne.printStackTrace(); + } + } + + public Configuration getConfiguration() { + return cfg; + } + + private void initConfiguration() throws NamingException { // Create the partition for the acegi tests MutableDirectoryPartitionConfiguration acegiDit = new MutableDirectoryPartitionConfiguration(); acegiDit.setName("acegisecurity"); acegiDit.setSuffix("dc=acegisecurity,dc=org"); + BasicAttributes attributes = new BasicAttributes(); BasicAttribute objectClass = new BasicAttribute("objectClass"); objectClass.add("top"); @@ -221,12 +189,44 @@ public class LdapTestServer { cfg.setContextPartitionConfigurations(partitions); } - public Configuration getConfiguration() { - return cfg; + private void initTestData() { + createOu("people"); + createOu("groups"); + createUser("bob", "Bob Hamilton", "bobspassword"); + createUser("ben", "Ben Alex", "{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ="); + + String[] developers = new String[] { + "uid=ben,ou=people,dc=acegisecurity,dc=org", "uid=bob,ou=people,dc=acegisecurity,dc=org" + }; + createGroup("developers", "developer", developers); + createGroup("managers", "manager", new String[] {developers[0]}); } public static void main(String[] args) { LdapTestServer server = new LdapTestServer(); } + private void startLdapServer() { + cfg = new MutableStartupConfiguration(); + ((MutableStartupConfiguration) cfg).setWorkingDirectory(workingDir); + + System.out.println("Working directory is " + workingDir.getAbsolutePath()); + + Properties env = new Properties(); + + env.setProperty(Context.PROVIDER_URL, "dc=acegisecurity,dc=org"); + env.setProperty(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName()); + env.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); + env.setProperty(Context.SECURITY_PRINCIPAL, DirectoryPartitionNexus.ADMIN_PRINCIPAL); + env.setProperty(Context.SECURITY_CREDENTIALS, DirectoryPartitionNexus.ADMIN_PASSWORD); + + try { + initConfiguration(); + env.putAll(cfg.toJndiEnvironment()); + serverContext = new InitialDirContext(env); + } catch (NamingException e) { + System.err.println("Failed to start Apache DS"); + e.printStackTrace(); + } + } } diff --git a/core/src/test/java/org/acegisecurity/ldap/LdapUtilsTests.java b/core/src/test/java/org/acegisecurity/ldap/LdapUtilsTests.java index 4d699a7ead..6993fe7f8c 100644 --- a/core/src/test/java/org/acegisecurity/ldap/LdapUtilsTests.java +++ b/core/src/test/java/org/acegisecurity/ldap/LdapUtilsTests.java @@ -1,68 +1,78 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.acegisecurity.ldap; - -import org.jmock.MockObjectTestCase; -import org.jmock.Mock; - -import javax.naming.directory.DirContext; -import javax.naming.Context; -import javax.naming.NamingException; - -/** - * Tests {@link LdapUtils} - * - * @author Luke Taylor - * @version $Id$ - */ -public class LdapUtilsTests extends MockObjectTestCase { - - private final LdapDataAccessException tempCoverageBoost = new LdapDataAccessException(""); - - public void testRootDnsAreParsedFromUrlsCorrectly() { - assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine")); - assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/")); - assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/")); - assertEquals("dc=acegisecurity,dc=org", LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org", LdapUtils.parseRootDnFromUrl("ldap:///dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org/ou=blah", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org/ou=blah")); - } - - public void testGetRelativeNameReturnsFullDnWithEmptyBaseName() throws Exception { - Mock mockCtx = mock(DirContext.class); - - mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("")); - - assertEquals("cn=jane,dc=acegisecurity,dc=org", - LdapUtils.getRelativeName("cn=jane,dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); - } - - public void testGetRelativeNameReturnsEmptyStringForDnEqualToBaseName() throws Exception { - Mock mockCtx = mock(DirContext.class); - - mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); - - assertEquals("", LdapUtils.getRelativeName("dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); - } - - public void testCloseContextSwallowsNamingException() { - Mock mockCtx = mock(DirContext.class); - - mockCtx.expects(once()).method("close").will(throwException(new NamingException())); - - LdapUtils.closeContext((Context) mockCtx.proxy()); - } -} +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.ldap; + +import org.jmock.Mock; +import org.jmock.MockObjectTestCase; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; + + +/** + * Tests {@link LdapUtils} + * + * @author Luke Taylor + * @version $Id$ + */ +public class LdapUtilsTests extends MockObjectTestCase { + //~ Instance fields ================================================================================================ + + private final LdapDataAccessException tempCoverageBoost = new LdapDataAccessException(""); + + //~ Methods ======================================================================================================== + + public void testCloseContextSwallowsNamingException() { + Mock mockCtx = mock(DirContext.class); + + mockCtx.expects(once()).method("close").will(throwException(new NamingException())); + + LdapUtils.closeContext((Context) mockCtx.proxy()); + } + + public void testGetRelativeNameReturnsEmptyStringForDnEqualToBaseName() + throws Exception { + Mock mockCtx = mock(DirContext.class); + + mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); + + assertEquals("", LdapUtils.getRelativeName("dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); + } + + public void testGetRelativeNameReturnsFullDnWithEmptyBaseName() + throws Exception { + Mock mockCtx = mock(DirContext.class); + + mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("")); + + assertEquals("cn=jane,dc=acegisecurity,dc=org", + LdapUtils.getRelativeName("cn=jane,dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); + } + + public void testRootDnsAreParsedFromUrlsCorrectly() { + assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine")); + assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/")); + assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/")); + assertEquals("dc=acegisecurity,dc=org", + LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=acegisecurity,dc=org")); + assertEquals("dc=acegisecurity,dc=org", LdapUtils.parseRootDnFromUrl("ldap:///dc=acegisecurity,dc=org")); + assertEquals("dc=acegisecurity,dc=org", + LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=acegisecurity,dc=org")); + assertEquals("dc=acegisecurity,dc=org/ou=blah", + LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org/ou=blah")); + } +} diff --git a/core/src/test/java/org/acegisecurity/ldap/MockInitialDirContextFactory.java b/core/src/test/java/org/acegisecurity/ldap/MockInitialDirContextFactory.java index 805f731c0b..b3b46aafb7 100644 --- a/core/src/test/java/org/acegisecurity/ldap/MockInitialDirContextFactory.java +++ b/core/src/test/java/org/acegisecurity/ldap/MockInitialDirContextFactory.java @@ -1,29 +1,54 @@ -package org.acegisecurity.ldap; - -import javax.naming.directory.DirContext; - -/** - * @author Luke Taylor - * @version $Id$ - */ -public class MockInitialDirContextFactory implements InitialDirContextFactory { - DirContext ctx; - String baseDn; - - public MockInitialDirContextFactory(DirContext ctx, String baseDn) { - this.baseDn = baseDn; - this.ctx = ctx; - } - - public DirContext newInitialDirContext() { - return ctx; - } - - public DirContext newInitialDirContext(String username, String password) { - return ctx; - } - - public String getRootDn() { - return baseDn; - } -} +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.ldap; + +import javax.naming.directory.DirContext; + + +/** + * +DOCUMENT ME! + * + * @author Luke Taylor + * @version $Id$ + */ +public class MockInitialDirContextFactory implements InitialDirContextFactory { + //~ Instance fields ================================================================================================ + + DirContext ctx; + String baseDn; + + //~ Constructors =================================================================================================== + + public MockInitialDirContextFactory(DirContext ctx, String baseDn) { + this.baseDn = baseDn; + this.ctx = ctx; + } + + //~ Methods ======================================================================================================== + + public String getRootDn() { + return baseDn; + } + + public DirContext newInitialDirContext() { + return ctx; + } + + public DirContext newInitialDirContext(String username, String password) { + return ctx; + } +} diff --git a/core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java b/core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java index 4969842985..a4f6c6a58d 100644 --- a/core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java +++ b/core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java @@ -1,25 +1,41 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.ldap.search; import org.acegisecurity.ldap.AbstractLdapServerTestCase; import org.acegisecurity.ldap.DefaultInitialDirContextFactory; + import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.ldap.LdapUserDetails; + import org.springframework.dao.IncorrectResultSizeDataAccessException; + /** * Tests for FilterBasedLdapUserSearch. - * + * * @author Luke Taylor * @version $Id$ */ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase { + //~ Instance fields ================================================================================================ + private DefaultInitialDirContextFactory dirCtxFactory; - public void onSetUp() { - dirCtxFactory = getInitialCtxFactory(); - dirCtxFactory.setManagerDn(MANAGER_USER); - dirCtxFactory.setManagerPassword(MANAGER_PASSWORD); - } + //~ Constructors =================================================================================================== public FilterBasedLdapUserSearchTests(String string) { super(string); @@ -29,64 +45,66 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase { super(); } + //~ Methods ======================================================================================================== + + public void onSetUp() { + dirCtxFactory = getInitialCtxFactory(); + dirCtxFactory.setManagerDn(MANAGER_USER); + dirCtxFactory.setManagerPassword(MANAGER_PASSWORD); + } + public void testBasicSearch() { - FilterBasedLdapUserSearch locator = - new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); + FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); locator.setSearchSubtree(false); locator.setSearchTimeLimit(0); locator.setDerefLinkFlag(false); LdapUserDetails bob = locator.searchForUser("bob"); assertEquals("bob", bob.getUsername()); + // name is wrong with embedded apacheDS // assertEquals("uid=bob,ou=people,dc=acegisecurity,dc=org", bob.getDn()); } - public void testSubTreeSearchSucceeds() { - // Don't set the searchBase, so search from the root. - FilterBasedLdapUserSearch locator = - new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory); - locator.setSearchSubtree(true); + // Try some funny business with filters. + public void testExtraFilterPartToExcludeBob() throws Exception { + FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", + "(&(cn=*)(!(|(uid={0})(uid=marissa))))", dirCtxFactory); - LdapUserDetails ben = locator.searchForUser("Ben Alex"); - assertEquals("Ben Alex", ben.getUsername()); -// assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn()); - } + // Search for bob, get back ben... + LdapUserDetails ben = locator.searchForUser("bob"); + String cn = (String) ben.getAttributes().get("cn").get(); + assertEquals("Ben Alex", cn); - public void testSearchForInvalidUserFails() { - FilterBasedLdapUserSearch locator = - new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); - - try { - locator.searchForUser("Joe"); - fail("Expected UsernameNotFoundException for non-existent user."); - } catch (UsernameNotFoundException expected) { - } +// assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn()); } public void testFailsOnMultipleMatches() { - FilterBasedLdapUserSearch locator = - new FilterBasedLdapUserSearch("ou=people", "(cn=*)", dirCtxFactory); + FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(cn=*)", dirCtxFactory); try { locator.searchForUser("Ignored"); fail("Expected exception for multiple search matches."); - } catch (IncorrectResultSizeDataAccessException expected) { - } + } catch (IncorrectResultSizeDataAccessException expected) {} } - // Try some funny business with filters. + public void testSearchForInvalidUserFails() { + FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); - public void testExtraFilterPartToExcludeBob() throws Exception { - FilterBasedLdapUserSearch locator = - new FilterBasedLdapUserSearch("ou=people", - "(&(cn=*)(!(|(uid={0})(uid=marissa))))", - dirCtxFactory); + try { + locator.searchForUser("Joe"); + fail("Expected UsernameNotFoundException for non-existent user."); + } catch (UsernameNotFoundException expected) {} + } - // Search for bob, get back ben... - LdapUserDetails ben = locator.searchForUser("bob"); - String cn = (String)ben.getAttributes().get("cn").get(); - assertEquals("Ben Alex", cn); -// assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn()); + public void testSubTreeSearchSucceeds() { + // Don't set the searchBase, so search from the root. + FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory); + locator.setSearchSubtree(true); + + LdapUserDetails ben = locator.searchForUser("Ben Alex"); + assertEquals("Ben Alex", ben.getUsername()); + +// assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn()); } } diff --git a/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java index 9cd3472c07..3d834ddb09 100644 --- a/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java @@ -28,11 +28,11 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class AbstractAuthenticationTokenTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private GrantedAuthority[] authorities = null; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractAuthenticationTokenTests() { super(); @@ -42,7 +42,7 @@ public class AbstractAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractAuthenticationTokenTests.class); @@ -51,90 +51,11 @@ public class AbstractAuthenticationTokenTests extends TestCase { public final void setUp() throws Exception { super.setUp(); - authorities = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), - new GrantedAuthorityImpl("ROLE_TWO")}; - } - - public void testGetters() throws Exception { - MockAuthenticationImpl token = new MockAuthenticationImpl("Test", - "Password", authorities); - assertEquals("Test", token.getPrincipal()); - assertEquals("Password", token.getCredentials()); - assertEquals("Test", token.getName()); - } - - public void testHashCode() throws Exception { - MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test", - "Password", authorities); - MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test", - "Password", authorities); - MockAuthenticationImpl token3 = new MockAuthenticationImpl(null, null, - new GrantedAuthority[] {}); - assertEquals(token1.hashCode(), token2.hashCode()); - assertTrue(token1.hashCode() != token3.hashCode()); - - token2.setAuthenticated(true); - - assertTrue(token1.hashCode() != token2.hashCode()); - } - - public void testObjectsEquals() throws Exception { - MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test", - "Password", authorities); - MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test", - "Password", authorities); - assertEquals(token1, token2); - - MockAuthenticationImpl token3 = new MockAuthenticationImpl("Test", - "Password_Changed", authorities); - assertTrue(!token1.equals(token3)); - - MockAuthenticationImpl token4 = new MockAuthenticationImpl("Test_Changed", - "Password", authorities); - assertTrue(!token1.equals(token4)); - - MockAuthenticationImpl token5 = new MockAuthenticationImpl("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO_CHANGED")}); - assertTrue(!token1.equals(token5)); - - MockAuthenticationImpl token6 = new MockAuthenticationImpl("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); - assertTrue(!token1.equals(token6)); - - MockAuthenticationImpl token7 = new MockAuthenticationImpl("Test", - "Password", null); - assertTrue(!token1.equals(token7)); - assertTrue(!token7.equals(token1)); - - assertTrue(!token1.equals(new Integer(100))); - } - - public void testSetAuthenticated() throws Exception { - MockAuthenticationImpl token = new MockAuthenticationImpl("Test", - "Password", authorities); - assertTrue(!token.isAuthenticated()); - token.setAuthenticated(true); - assertTrue(token.isAuthenticated()); - } - - public void testToStringWithAuthorities() { - MockAuthenticationImpl token = new MockAuthenticationImpl("Test", - "Password", authorities); - assertTrue(token.toString().lastIndexOf("ROLE_TWO") != -1); - } - - public void testToStringWithNullAuthorities() { - MockAuthenticationImpl token = new MockAuthenticationImpl("Test", - "Password", null); - assertTrue(token.toString().lastIndexOf("Not granted any authorities") != -1); + authorities = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}; } public void testAuthoritiesAreImmutable() { - MockAuthenticationImpl token = new MockAuthenticationImpl("Test", - "Password", authorities); + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", "Password", authorities); GrantedAuthority[] gotAuthorities = token.getAuthorities(); assertNotSame(authorities, gotAuthorities); @@ -146,17 +67,80 @@ public class AbstractAuthenticationTokenTests extends TestCase { assertEquals(gotAuthorities[0], authorities[0]); assertEquals(gotAuthorities[1], authorities[1]); assertFalse(gotAuthorities[0].equals("ROLE_SUPER_USER")); - assertFalse(gotAuthorities[1].equals("ROLE_SUPER_USER")); + assertFalse(gotAuthorities[1].equals("ROLE_SUPER_USER")); } - //~ Inner Classes ========================================================== + public void testGetters() throws Exception { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", "Password", authorities); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals("Test", token.getName()); + } + + public void testHashCode() throws Exception { + MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test", "Password", authorities); + MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test", "Password", authorities); + MockAuthenticationImpl token3 = new MockAuthenticationImpl(null, null, new GrantedAuthority[] {}); + assertEquals(token1.hashCode(), token2.hashCode()); + assertTrue(token1.hashCode() != token3.hashCode()); + + token2.setAuthenticated(true); + + assertTrue(token1.hashCode() != token2.hashCode()); + } + + public void testObjectsEquals() throws Exception { + MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test", "Password", authorities); + MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test", "Password", authorities); + assertEquals(token1, token2); + + MockAuthenticationImpl token3 = new MockAuthenticationImpl("Test", "Password_Changed", authorities); + assertTrue(!token1.equals(token3)); + + MockAuthenticationImpl token4 = new MockAuthenticationImpl("Test_Changed", "Password", authorities); + assertTrue(!token1.equals(token4)); + + MockAuthenticationImpl token5 = new MockAuthenticationImpl("Test", "Password", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO_CHANGED") + }); + assertTrue(!token1.equals(token5)); + + MockAuthenticationImpl token6 = new MockAuthenticationImpl("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); + assertTrue(!token1.equals(token6)); + + MockAuthenticationImpl token7 = new MockAuthenticationImpl("Test", "Password", null); + assertTrue(!token1.equals(token7)); + assertTrue(!token7.equals(token1)); + + assertTrue(!token1.equals(new Integer(100))); + } + + public void testSetAuthenticated() throws Exception { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", "Password", authorities); + assertTrue(!token.isAuthenticated()); + token.setAuthenticated(true); + assertTrue(token.isAuthenticated()); + } + + public void testToStringWithAuthorities() { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", "Password", authorities); + assertTrue(token.toString().lastIndexOf("ROLE_TWO") != -1); + } + + public void testToStringWithNullAuthorities() { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", "Password", null); + assertTrue(token.toString().lastIndexOf("Not granted any authorities") != -1); + } + + //~ Inner Classes ================================================================================================== private class MockAuthenticationImpl extends AbstractAuthenticationToken { private Object credentials; private Object principal; - public MockAuthenticationImpl(Object principal, Object credentials, - GrantedAuthority[] authorities) { + public MockAuthenticationImpl(Object principal, Object credentials, GrantedAuthority[] authorities) { super(authorities); this.principal = principal; this.credentials = credentials; diff --git a/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java index 0a13be1b4d..3fd943b57e 100644 --- a/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.providers; -import java.util.List; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.Authentication; @@ -25,11 +22,16 @@ import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.concurrent.ConcurrentSessionControllerImpl; import org.acegisecurity.concurrent.NullConcurrentSessionController; + import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; +import java.util.List; +import java.util.Vector; + /** * Tests {@link ProviderManager}. @@ -38,7 +40,7 @@ import org.springframework.context.ApplicationEventPublisher; * @version $Id$ */ public class ProviderManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ProviderManagerTests() { super(); @@ -48,21 +50,45 @@ public class ProviderManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ProviderManagerTests.class); } + private ProviderManager makeProviderManager() throws Exception { + MockProvider provider1 = new MockProvider(); + List providers = new Vector(); + providers.add(provider1); + + ProviderManager mgr = new ProviderManager(); + mgr.setProviders(providers); + + mgr.afterPropertiesSet(); + + return mgr; + } + + private ProviderManager makeProviderManagerWithMockProviderWhichReturnsNullInList() { + MockProviderWhichReturnsNull provider1 = new MockProviderWhichReturnsNull(); + MockProvider provider2 = new MockProvider(); + List providers = new Vector(); + providers.add(provider1); + providers.add(provider2); + + ProviderManager mgr = new ProviderManager(); + mgr.setProviders(providers); + + return mgr; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticationFails() throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); ProviderManager mgr = makeProviderManager(); mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true)); @@ -76,13 +102,12 @@ public class ProviderManagerTests extends TestCase { } public void testAuthenticationSuccess() throws Exception { - TestingAuthenticationToken token = new TestingAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); ProviderManager mgr = makeProviderManager(); mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true)); + Authentication result = mgr.authenticate(token); if (!(result instanceof TestingAuthenticationToken)) { @@ -97,13 +122,12 @@ public class ProviderManagerTests extends TestCase { } public void testAuthenticationSuccessWhenFirstProviderReturnsNullButSecondAuthenticates() { - TestingAuthenticationToken token = new TestingAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); ProviderManager mgr = makeProviderManagerWithMockProviderWhichReturnsNullInList(); mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true)); + Authentication result = mgr.authenticate(token); if (!(result instanceof TestingAuthenticationToken)) { @@ -175,47 +199,34 @@ public class ProviderManagerTests extends TestCase { assertEquals(1, mgr.getProviders().size()); } - private ProviderManager makeProviderManager() throws Exception { - MockProvider provider1 = new MockProvider(); - List providers = new Vector(); - providers.add(provider1); + //~ Inner Classes ================================================================================================== - ProviderManager mgr = new ProviderManager(); - mgr.setProviders(providers); - - mgr.afterPropertiesSet(); - return mgr; + private class MockApplicationEventPublisher implements ApplicationEventPublisher { + private boolean expectedEvent; + + public MockApplicationEventPublisher(boolean expectedEvent) { + this.expectedEvent = expectedEvent; + } + + public void publishEvent(ApplicationEvent event) { + if (expectedEvent == false) { + throw new IllegalStateException("The ApplicationEventPublisher did not expect to receive this event"); + } + } } - private ProviderManager makeProviderManagerWithMockProviderWhichReturnsNullInList() { - MockProviderWhichReturnsNull provider1 = new MockProviderWhichReturnsNull(); - MockProvider provider2 = new MockProvider(); - List providers = new Vector(); - providers.add(provider1); - providers.add(provider2); - - ProviderManager mgr = new ProviderManager(); - mgr.setProviders(providers); - - return mgr; - } - - //~ Inner Classes ========================================================== - private class MockProvider implements AuthenticationProvider { public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (supports(authentication.getClass())) { return authentication; } else { - throw new AuthenticationServiceException( - "Don't support this class"); + throw new AuthenticationServiceException("Don't support this class"); } } public boolean supports(Class authentication) { - if (TestingAuthenticationToken.class.isAssignableFrom( - authentication)) { + if (TestingAuthenticationToken.class.isAssignableFrom(authentication)) { return true; } else { return false; @@ -229,32 +240,16 @@ public class ProviderManagerTests extends TestCase { if (supports(authentication.getClass())) { return null; } else { - throw new AuthenticationServiceException( - "Don't support this class"); + throw new AuthenticationServiceException("Don't support this class"); } } public boolean supports(Class authentication) { - if (TestingAuthenticationToken.class.isAssignableFrom( - authentication)) { + if (TestingAuthenticationToken.class.isAssignableFrom(authentication)) { return true; } else { return false; } } } - - private class MockApplicationEventPublisher implements ApplicationEventPublisher { - private boolean expectedEvent; - - public MockApplicationEventPublisher(boolean expectedEvent) { - this.expectedEvent = expectedEvent; - } - - public void publishEvent(ApplicationEvent event) { - if (expectedEvent == false) { - throw new IllegalStateException("The ApplicationEventPublisher did not expect to receive this event"); - } - } - } } diff --git a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java index b903a5eef4..142fe8b7eb 100644 --- a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class TestingAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public TestingAuthenticationProviderTests() { super(); @@ -39,22 +39,20 @@ public class TestingAuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(TestingAuthenticationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticates() { TestingAuthenticationProvider provider = new TestingAuthenticationProvider(); - TestingAuthenticationToken token = new TestingAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); Authentication result = provider.authenticate(token); if (!(result instanceof TestingAuthenticationToken)) { diff --git a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java index 74ce6b52c2..8247b57a40 100644 --- a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java @@ -28,7 +28,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class TestingAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public TestingAuthenticationTokenTests() { super(); @@ -38,7 +38,7 @@ public class TestingAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(TestingAuthenticationTokenTests.class); @@ -49,18 +49,15 @@ public class TestingAuthenticationTokenTests extends TestCase { } public void testAuthenticated() { - TestingAuthenticationToken token = new TestingAuthenticationToken("Test", - "Password", null); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password", null); assertTrue(!token.isAuthenticated()); token.setAuthenticated(true); assertTrue(token.isAuthenticated()); } public void testGetters() { - TestingAuthenticationToken token = new TestingAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); diff --git a/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java index c69838a3e1..e1a315fe98 100644 --- a/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.acegisecurity.GrantedAuthorityImpl; * @version $Id$ */ public class UsernamePasswordAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UsernamePasswordAuthenticationTokenTests() { super(); @@ -38,19 +38,18 @@ public class UsernamePasswordAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(UsernamePasswordAuthenticationTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticated() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", null); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", null); // check default given we passed some GrantedAuthorty[]s (well, we passed null) assertTrue(token.isAuthenticated()); @@ -78,10 +77,8 @@ public class UsernamePasswordAuthenticationTokenTests extends TestCase { } public void testGetters() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); @@ -92,7 +89,7 @@ public class UsernamePasswordAuthenticationTokenTests extends TestCase { Class clazz = UsernamePasswordAuthenticationToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); diff --git a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java index 22e8257f48..d94a513b39 100644 --- a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; @@ -31,7 +32,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class AnonymousAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AnonymousAuthenticationProviderTests() { super(); @@ -41,24 +42,22 @@ public class AnonymousAuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AnonymousAuthenticationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsAnInvalidKey() throws Exception { AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); aap.setKey("qwerty"); - AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); try { Authentication result = aap.authenticate(token); @@ -91,8 +90,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase { AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); aap.setKey("qwerty"); - TestingAuthenticationToken token = new TestingAuthenticationToken("user", - "password", + TestingAuthenticationToken token = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); assertFalse(aap.supports(TestingAuthenticationToken.class)); @@ -104,10 +102,8 @@ public class AnonymousAuthenticationProviderTests extends TestCase { AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); aap.setKey("qwerty"); - AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); Authentication result = aap.authenticate(token); diff --git a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationTokenTests.java index a221a89174..207905b439 100644 --- a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationTokenTests.java @@ -33,7 +33,7 @@ import java.util.Vector; * @version $Id$ */ public class AnonymousAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AnonymousAuthenticationTokenTests() { super(); @@ -43,7 +43,7 @@ public class AnonymousAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AnonymousAuthenticationTokenTests.class); @@ -56,8 +56,7 @@ public class AnonymousAuthenticationTokenTests extends TestCase { public void testConstructorRejectsNulls() { try { new AnonymousAuthenticationToken(null, "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -65,8 +64,7 @@ public class AnonymousAuthenticationTokenTests extends TestCase { try { new AnonymousAuthenticationToken("key", null, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -80,16 +78,14 @@ public class AnonymousAuthenticationTokenTests extends TestCase { } try { - new AnonymousAuthenticationToken("key", "Test", - new GrantedAuthority[] {null}); + new AnonymousAuthenticationToken("key", "Test", new GrantedAuthority[] {null}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - new AnonymousAuthenticationToken("key", "Test", - new GrantedAuthority[] {}); + new AnonymousAuthenticationToken("key", "Test", new GrantedAuthority[] {}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -100,24 +96,18 @@ public class AnonymousAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals(token1, token2); } public void testGetters() { - AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("key".hashCode(), token.getKeyHash()); assertEquals("Test", token.getPrincipal()); @@ -139,52 +129,38 @@ public class AnonymousAuthenticationTokenTests extends TestCase { } public void testNotEqualsDueToAbstractParentEqualsCheck() { - AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("key", - "DIFFERENT_PRINCIPAL", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("key", "DIFFERENT_PRINCIPAL", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testNotEqualsDueToDifferentAuthenticationClass() { - AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testNotEqualsDueToKey() { - AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token1 = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("DIFFERENT_KEY", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token2 = new AnonymousAuthenticationToken("DIFFERENT_KEY", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testSetAuthenticatedIgnored() { - AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(token.isAuthenticated()); token.setAuthenticated(false); assertTrue(!token.isAuthenticated()); diff --git a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilterTests.java index 035efe1100..097823d501 100644 --- a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousProcessingFilterTests.java @@ -48,7 +48,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class AnonymousProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AnonymousProcessingFilterTests() { super(); @@ -58,11 +58,11 @@ public class AnonymousProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { filter.init(filterConfig); filter.doFilter(request, response, filterChain); filter.destroy(); @@ -130,8 +130,7 @@ public class AnonymousProcessingFilterTests extends TestCase { public void testOperationWhenAuthenticationExistsInContextHolder() throws Exception { // Put an Authentication object into the SecurityContextHolder - Authentication originalAuth = new TestingAuthenticationToken("user", - "password", + Authentication originalAuth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); SecurityContextHolder.getContext().setAuthentication(originalAuth); @@ -148,12 +147,11 @@ public class AnonymousProcessingFilterTests extends TestCase { // Test MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("x"); - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, new MockHttpServletResponse(), new MockFilterChain(true)); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(), + new MockFilterChain(true)); // Ensure filter didn't change our original object - assertEquals(originalAuth, - SecurityContextHolder.getContext().getAuthentication()); + assertEquals(originalAuth, SecurityContextHolder.getContext().getAuthentication()); } public void testOperationWhenNoAuthenticationInSecurityContextHolder() @@ -170,24 +168,22 @@ public class AnonymousProcessingFilterTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("x"); - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, new MockHttpServletResponse(), new MockFilterChain(true)); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(), + new MockFilterChain(true)); - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); assertEquals("anonymousUsername", auth.getPrincipal()); - assertEquals(new GrantedAuthorityImpl("ROLE_ANONYMOUS"), - auth.getAuthorities()[0]); + assertEquals(new GrantedAuthorityImpl("ROLE_ANONYMOUS"), auth.getAuthorities()[0]); SecurityContextHolder.getContext().setAuthentication(null); // so anonymous fires again // Now test operation if we have removeAfterRequest = true filter.setRemoveAfterRequest(true); // set to default value - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, new MockHttpServletResponse(), new MockFilterChain(true)); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(), + new MockFilterChain(true)); assertNull(SecurityContextHolder.getContext().getAuthentication()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private boolean expectToProceed; diff --git a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java index 2e0fa05484..67b8f37adc 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,6 @@ package org.acegisecurity.providers.cas; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.Authentication; @@ -27,13 +22,21 @@ import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator; + import org.acegisecurity.ui.cas.CasProcessingFilter; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + /** * Tests {@link CasAuthenticationProvider}. @@ -42,7 +45,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class CasAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasAuthenticationProviderTests() { super(); @@ -52,16 +55,26 @@ public class CasAuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasAuthenticationProviderTests.class); } + private UserDetails makeUserDetails() { + return new User("user", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + } + + private UserDetails makeUserDetailsFromAuthoritiesPopulator() { + return new User("user", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")}); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticateStateful() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); @@ -89,13 +102,10 @@ public class CasAuthenticationProviderTests extends TestCase { assertEquals(makeUserDetailsFromAuthoritiesPopulator(), casResult.getPrincipal()); assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", casResult.getProxyGrantingTicketIou()); - assertEquals("https://localhost/portal/j_acegi_cas_security_check", - casResult.getProxyList().get(0)); + assertEquals("https://localhost/portal/j_acegi_cas_security_check", casResult.getProxyList().get(0)); assertEquals("ST-123", casResult.getCredentials()); - assertEquals(new GrantedAuthorityImpl("ROLE_A"), - casResult.getAuthorities()[0]); - assertEquals(new GrantedAuthorityImpl("ROLE_B"), - casResult.getAuthorities()[1]); + assertEquals(new GrantedAuthorityImpl("ROLE_A"), casResult.getAuthorities()[0]); + assertEquals(new GrantedAuthorityImpl("ROLE_B"), casResult.getAuthorities()[1]); assertEquals(cap.getKey().hashCode(), casResult.getKeyHash()); // Now confirm the CasAuthenticationToken is automatically re-accepted. @@ -160,8 +170,7 @@ public class CasAuthenticationProviderTests extends TestCase { Authentication result = cap.authenticate(token); fail("Should have thrown BadCredentialsException"); } catch (BadCredentialsException expected) { - assertEquals("Failed to provide a CAS service ticket to validate", - expected.getMessage()); + assertEquals("Failed to provide a CAS service ticket to validate", expected.getMessage()); } } @@ -176,17 +185,14 @@ public class CasAuthenticationProviderTests extends TestCase { cap.setTicketValidator(new MockTicketValidator(true)); cap.afterPropertiesSet(); - CasAuthenticationToken token = new CasAuthenticationToken("WRONG_KEY", - makeUserDetails(), "credentials", - new GrantedAuthority[] {new GrantedAuthorityImpl("XX")}, - makeUserDetails(), new Vector(), "IOU-xxx"); + CasAuthenticationToken token = new CasAuthenticationToken("WRONG_KEY", makeUserDetails(), "credentials", + new GrantedAuthority[] {new GrantedAuthorityImpl("XX")}, makeUserDetails(), new Vector(), "IOU-xxx"); try { Authentication result = cap.authenticate(token); fail("Should have thrown BadCredentialsException"); } catch (BadCredentialsException expected) { - assertEquals("The presented CasAuthenticationToken does not contain the expected key", - expected.getMessage()); + assertEquals("The presented CasAuthenticationToken does not contain the expected key", expected.getMessage()); } } @@ -202,8 +208,7 @@ public class CasAuthenticationProviderTests extends TestCase { cap.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A casAuthoritiesPopulator must be set", - expected.getMessage()); + assertEquals("A casAuthoritiesPopulator must be set", expected.getMessage()); } } @@ -250,8 +255,7 @@ public class CasAuthenticationProviderTests extends TestCase { cap.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A statelessTicketCache must be set", - expected.getMessage()); + assertEquals("A statelessTicketCache must be set", expected.getMessage()); } } @@ -295,8 +299,7 @@ public class CasAuthenticationProviderTests extends TestCase { cap.setTicketValidator(new MockTicketValidator(true)); cap.afterPropertiesSet(); - TestingAuthenticationToken token = new TestingAuthenticationToken("user", - "password", + TestingAuthenticationToken token = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); assertFalse(cap.supports(TestingAuthenticationToken.class)); @@ -315,8 +318,7 @@ public class CasAuthenticationProviderTests extends TestCase { cap.afterPropertiesSet(); UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("some_normal_user", - "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); + "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); assertEquals(null, cap.authenticate(token)); } @@ -326,19 +328,7 @@ public class CasAuthenticationProviderTests extends TestCase { assertTrue(cap.supports(CasAuthenticationToken.class)); } - private UserDetails makeUserDetails() { - return new User("user", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - } - - private UserDetails makeUserDetailsFromAuthoritiesPopulator() { - return new User("user", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl( - "ROLE_B")}); - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAuthoritiesPopulator implements CasAuthoritiesPopulator { public UserDetails getUserDetails(String casUserId) @@ -380,13 +370,11 @@ public class CasAuthenticationProviderTests extends TestCase { } public void removeTicketFromCache(CasAuthenticationToken token) { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } public void removeTicketFromCache(String serviceTicket) { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } } @@ -407,8 +395,7 @@ public class CasAuthenticationProviderTests extends TestCase { List list = new Vector(); list.add("https://localhost/portal/j_acegi_cas_security_check"); - return new TicketResponse("marissa", list, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + return new TicketResponse("marissa", list, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); } throw new BadCredentialsException("As requested from mock"); diff --git a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java index 631226bbb5..62dd821979 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,9 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; @@ -34,7 +36,7 @@ import java.util.Vector; * @version $Id$ */ public class CasAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasAuthenticationTokenTests() { super(); @@ -44,22 +46,30 @@ public class CasAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasAuthenticationTokenTests.class); } + private UserDetails makeUserDetails() { + return makeUserDetails("user"); + } + + private UserDetails makeUserDetails(final String name) { + return new User(name, "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testConstructorRejectsNulls() { try { new CasAuthenticationToken(null, makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -67,9 +77,8 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", null, "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -77,17 +86,15 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", makeUserDetails(), null, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - new CasAuthenticationToken("key", makeUserDetails(), "Password", null, - makeUserDetails(), new Vector(), + new CasAuthenticationToken("key", makeUserDetails(), "Password", null, makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { @@ -96,9 +103,8 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), null, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), null, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -106,9 +112,8 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, null, new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + null, new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -116,8 +121,8 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), null); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -125,9 +130,8 @@ public class CasAuthenticationTokenTests extends TestCase { try { new CasAuthenticationToken("key", makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null, new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null, new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -138,20 +142,16 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); List proxyList2 = new Vector(); proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token2 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList2, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertEquals(token1, token2); } @@ -161,28 +161,24 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList = new Vector(); proxyList.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertEquals("key".hashCode(), token.getKeyHash()); assertEquals(makeUserDetails(), token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); - assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", - token.getProxyGrantingTicketIou()); + assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", token.getProxyGrantingTicketIou()); assertEquals(proxyList, token.getProxyList()); - assertEquals(makeUserDetails().getUsername(), - token.getUserDetails().getUsername()); + assertEquals(makeUserDetails().getUsername(), token.getUserDetails().getUsername()); } public void testNoArgConstructorDoesntExist() { Class clazz = CasAuthenticationToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -193,20 +189,16 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); List proxyList2 = new Vector(); proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token2 = new CasAuthenticationToken("key", - makeUserDetails("OTHER_NAME"), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList2, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails("OTHER_NAME"), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertTrue(!token1.equals(token2)); } @@ -215,16 +207,12 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); - UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(!token1.equals(token2)); } @@ -233,20 +221,16 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); List proxyList2 = new Vector(); proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token2 = new CasAuthenticationToken("DIFFERENT_KEY", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList2, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token2 = new CasAuthenticationToken("DIFFERENT_KEY", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertTrue(!token1.equals(token2)); } @@ -255,20 +239,16 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); List proxyList2 = new Vector(); proxyList2.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token2 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList2, - "PGTIOU-SOME_OTHER_VALUE"); + CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList2, "PGTIOU-SOME_OTHER_VALUE"); assertTrue(!token1.equals(token2)); } @@ -277,55 +257,36 @@ public class CasAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - CasAuthenticationToken token1 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList1, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token1 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList1, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); List proxyList2 = new Vector(); - proxyList2.add( - "https://localhost/SOME_OTHER_PORTAL/j_acegi_cas_security_check"); + proxyList2.add("https://localhost/SOME_OTHER_PORTAL/j_acegi_cas_security_check"); - CasAuthenticationToken token2 = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), proxyList2, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token2 = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), proxyList2, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertTrue(!token1.equals(token2)); } public void testSetAuthenticated() { - CasAuthenticationToken token = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertTrue(token.isAuthenticated()); token.setAuthenticated(false); assertTrue(!token.isAuthenticated()); } public void testToString() { - CasAuthenticationToken token = new CasAuthenticationToken("key", - makeUserDetails(), "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, makeUserDetails(), new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + makeUserDetails(), new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); String result = token.toString(); assertTrue(result.lastIndexOf("Proxy List:") != -1); assertTrue(result.lastIndexOf("Proxy-Granting Ticket IOU:") != -1); assertTrue(result.lastIndexOf("Credentials (Service/Proxy Ticket):") != -1); } - - private UserDetails makeUserDetails() { - return makeUserDetails("user"); - } - - private UserDetails makeUserDetails(final String name) { - return new User(name, "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - } } diff --git a/core/src/test/java/org/acegisecurity/providers/cas/TicketResponseTests.java b/core/src/test/java/org/acegisecurity/providers/cas/TicketResponseTests.java index dfca3bbd1b..96beb43f6f 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/TicketResponseTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/TicketResponseTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import java.util.Vector; * @version $Id$ */ public class TicketResponseTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public TicketResponseTests() { super(); @@ -38,16 +38,16 @@ public class TicketResponseTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(TicketResponseTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConstructorAcceptsNullProxyGrantingTicketIOU() { TicketResponse ticket = new TicketResponse("marissa", new Vector(), null); assertEquals("", ticket.getProxyGrantingTicketIou()); @@ -61,8 +61,7 @@ public class TicketResponseTests extends TestCase { public void testConstructorRejectsNullUser() { try { - new TicketResponse(null, new Vector(), - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); + new TicketResponse(null, new Vector(), "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -78,15 +77,14 @@ public class TicketResponseTests extends TestCase { "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); assertEquals("marissa", ticket.getUser()); assertEquals(proxyList, ticket.getProxyList()); - assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", - ticket.getProxyGrantingTicketIou()); + assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", ticket.getProxyGrantingTicketIou()); } public void testNoArgConstructorDoesntExist() { Class clazz = TicketResponse.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); diff --git a/core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java b/core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java index 8643025f9d..87bc245b54 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,15 @@ package org.acegisecurity.providers.cas.cache; import junit.framework.TestCase; +import net.sf.ehcache.Cache; + import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.MockApplicationContext; -import org.acegisecurity.providers.cas.CasAuthenticationToken; -import org.acegisecurity.userdetails.User; -import net.sf.ehcache.Cache; +import org.acegisecurity.providers.cas.CasAuthenticationToken; + +import org.acegisecurity.userdetails.User; import org.springframework.context.ApplicationContext; @@ -38,7 +40,7 @@ import java.util.Vector; * @version $Id$ */ public class EhCacheBasedTicketCacheTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public EhCacheBasedTicketCacheTests() { super(); @@ -48,16 +50,34 @@ public class EhCacheBasedTicketCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private Cache getCache() { + ApplicationContext ctx = MockApplicationContext.getContext(); + + return (Cache) ctx.getBean("eHCacheBackend"); + } + + private CasAuthenticationToken getToken() { + List proxyList = new Vector(); + proxyList.add("https://localhost/newPortal/j_acegi_cas_security_check"); + + User user = new User("marissa", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + + return new CasAuthenticationToken("key", user, "ST-0-ER94xMJmn6pha35CQRoZ", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, user, + proxyList, "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); } public static void main(String[] args) { junit.textui.TestRunner.run(EhCacheBasedTicketCacheTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCacheOperation() throws Exception { EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache(); cache.setCache(getCache()); @@ -65,8 +85,7 @@ public class EhCacheBasedTicketCacheTests extends TestCase { // Check it gets stored in the cache cache.putTicketInCache(getToken()); - assertEquals(getToken(), - cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ")); + assertEquals(getToken(), cache.getByTicketId("ST-0-ER94xMJmn6pha35CQRoZ")); // Check it gets removed from the cache cache.removeTicketFromCache(getToken()); @@ -91,25 +110,4 @@ public class EhCacheBasedTicketCacheTests extends TestCase { cache.setCache(myCache); assertEquals(myCache, cache.getCache()); } - - private Cache getCache() { - ApplicationContext ctx = MockApplicationContext.getContext(); - - return (Cache) ctx.getBean("eHCacheBackend"); - } - - private CasAuthenticationToken getToken() { - List proxyList = new Vector(); - proxyList.add("https://localhost/newPortal/j_acegi_cas_security_check"); - - User user = new User("marissa", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - return new CasAuthenticationToken("key", user, - "ST-0-ER94xMJmn6pha35CQRoZ", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, user, proxyList, - "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); - } } diff --git a/core/src/test/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java b/core/src/test/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java index c15e2b637f..9c9254ffe8 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,10 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; -import org.acegisecurity.userdetails.UserDetailsService; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; import org.springframework.dao.DataAccessException; @@ -35,7 +36,7 @@ import org.springframework.dao.DataRetrievalFailureException; * @version $Id$ */ public class DaoCasAuthoritiesPopulatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public DaoCasAuthoritiesPopulatorTests() { super(); @@ -45,16 +46,16 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(DaoCasAuthoritiesPopulatorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingAuthenticationDao() throws Exception { DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); @@ -62,8 +63,7 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase { populator.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An authenticationDao must be set", - expected.getMessage()); + assertEquals("An authenticationDao must be set", expected.getMessage()); } } @@ -89,10 +89,8 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase { UserDetails results = populator.getUserDetails("marissa"); assertEquals(2, results.getAuthorities().length); - assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), - results.getAuthorities()[0]); - assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), - results.getAuthorities()[1]); + assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), results.getAuthorities()[0]); + assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), results.getAuthorities()[1]); } public void testGetGrantedAuthoritiesWhenDaoThrowsException() @@ -116,18 +114,16 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase { assertEquals(dao, populator.getUserDetailsService()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockAuthenticationDaoSimulateBackendError - implements UserDetailsService { + private class MockAuthenticationDaoSimulateBackendError implements UserDetailsService { public long getRefreshDuration() { return 0; } public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - throw new DataRetrievalFailureException( - "This mock simulator is designed to fail"); + throw new DataRetrievalFailureException("This mock simulator is designed to fail"); } } @@ -140,11 +136,9 @@ public class DaoCasAuthoritiesPopulatorTests extends TestCase { throws UsernameNotFoundException, DataAccessException { if ("marissa".equals(username)) { return new User("marissa", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } diff --git a/core/src/test/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxyTests.java b/core/src/test/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxyTests.java index 80d76b0a7f..56753b15ce 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxyTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/proxy/AcceptAnyCasProxyTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import java.util.Vector; * @version $Id$ */ public class AcceptAnyCasProxyTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AcceptAnyCasProxyTests() { super(); @@ -37,16 +37,16 @@ public class AcceptAnyCasProxyTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AcceptAnyCasProxyTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDoesNotAcceptNull() { AcceptAnyCasProxy proxyDecider = new AcceptAnyCasProxy(); diff --git a/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java b/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java index a21a0748d0..657e699171 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,19 +15,19 @@ package org.acegisecurity.providers.cas.proxy; -import java.util.List; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.providers.cas.ProxyUntrustedException; +import java.util.List; +import java.util.Vector; + /** * Tests {@link NamedCasProxyDecider}. */ public class NamedCasProxyDeciderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NamedCasProxyDeciderTests() { super(); @@ -37,7 +37,7 @@ public class NamedCasProxyDeciderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class); @@ -58,8 +58,7 @@ public class NamedCasProxyDeciderTests extends TestCase { // Build the list of valid nearest proxies List validProxies = new Vector(); validProxies.add("https://localhost/portal/j_acegi_cas_security_check"); - validProxies.add( - "https://localhost/newPortal/j_acegi_cas_security_check"); + validProxies.add("https://localhost/newPortal/j_acegi_cas_security_check"); proxyDecider.setValidProxies(validProxies); proxyDecider.afterPropertiesSet(); @@ -83,8 +82,7 @@ public class NamedCasProxyDeciderTests extends TestCase { proxyDecider.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A validProxies list must be set", - expected.getMessage()); + assertEquals("A validProxies list must be set", expected.getMessage()); } } @@ -105,8 +103,7 @@ public class NamedCasProxyDeciderTests extends TestCase { // Build the list of valid nearest proxies List validProxies = new Vector(); validProxies.add("https://localhost/portal/j_acegi_cas_security_check"); - validProxies.add( - "https://localhost/newPortal/j_acegi_cas_security_check"); + validProxies.add("https://localhost/newPortal/j_acegi_cas_security_check"); proxyDecider.setValidProxies(validProxies); assertEquals(validProxies, proxyDecider.getValidProxies()); @@ -118,14 +115,12 @@ public class NamedCasProxyDeciderTests extends TestCase { // Build the ticket returned from CAS List proxyList = new Vector(); - proxyList.add( - "https://localhost/untrustedWebApp/j_acegi_cas_security_check"); + proxyList.add("https://localhost/untrustedWebApp/j_acegi_cas_security_check"); // Build the list of valid nearest proxies List validProxies = new Vector(); validProxies.add("https://localhost/portal/j_acegi_cas_security_check"); - validProxies.add( - "https://localhost/newPortal/j_acegi_cas_security_check"); + validProxies.add("https://localhost/newPortal/j_acegi_cas_security_check"); proxyDecider.setValidProxies(validProxies); proxyDecider.afterPropertiesSet(); diff --git a/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java b/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java index da6d3e20a0..5d82a825c6 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,13 @@ package org.acegisecurity.providers.cas.proxy; -import java.util.List; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.providers.cas.ProxyUntrustedException; +import java.util.List; +import java.util.Vector; + /** * Tests {@link RejectProxyTickets}. @@ -30,7 +30,7 @@ import org.acegisecurity.providers.cas.ProxyUntrustedException; * @version $Id$ */ public class RejectProxyTicketsTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RejectProxyTicketsTests() { super(); @@ -40,16 +40,16 @@ public class RejectProxyTicketsTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RejectProxyTicketsTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAcceptsIfNoProxiesInTicket() { RejectProxyTickets proxyDecider = new RejectProxyTickets(); List proxyList = new Vector(); // no proxies in list diff --git a/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidatorTests.java b/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidatorTests.java index 4a1cb1125c..08a88a1183 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/AbstractTicketValidatorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,9 @@ import junit.framework.TestCase; import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.cas.TicketResponse; + import org.acegisecurity.ui.cas.ServiceProperties; import java.util.Vector; @@ -32,7 +34,7 @@ import java.util.Vector; * @version $Id$ */ public class AbstractTicketValidatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractTicketValidatorTests() { super(); @@ -42,16 +44,16 @@ public class AbstractTicketValidatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractTicketValidatorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingCasValidate() throws Exception { AbstractTicketValidator tv = new MockAbstractTicketValidator(); tv.setServiceProperties(new ServiceProperties()); @@ -72,16 +74,14 @@ public class AbstractTicketValidatorTests extends TestCase { tv.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("serviceProperties must be specified", - expected.getMessage()); + assertEquals("serviceProperties must be specified", expected.getMessage()); } } public void testGetters() throws Exception { AbstractTicketValidator tv = new MockAbstractTicketValidator(); tv.setCasValidate("https://company.com/cas/proxyvalidate"); - assertEquals("https://company.com/cas/proxyvalidate", - tv.getCasValidate()); + assertEquals("https://company.com/cas/proxyvalidate", tv.getCasValidate()); tv.setServiceProperties(new ServiceProperties()); assertTrue(tv.getServiceProperties() != null); @@ -96,8 +96,7 @@ public class AbstractTicketValidatorTests extends TestCase { throws Exception { AbstractTicketValidator tv = new MockAbstractTicketValidator(); tv.setCasValidate("https://company.com/cas/proxyvalidate"); - assertEquals("https://company.com/cas/proxyvalidate", - tv.getCasValidate()); + assertEquals("https://company.com/cas/proxyvalidate", tv.getCasValidate()); tv.setServiceProperties(new ServiceProperties()); assertTrue(tv.getServiceProperties() != null); @@ -107,8 +106,7 @@ public class AbstractTicketValidatorTests extends TestCase { String before = System.getProperty("javax.net.ssl.trustStore"); tv.afterPropertiesSet(); - assertEquals("/some/file/cacerts", - System.getProperty("javax.net.ssl.trustStore")); + assertEquals("/some/file/cacerts", System.getProperty("javax.net.ssl.trustStore")); if (before == null) { System.setProperty("javax.net.ssl.trustStore", ""); @@ -117,7 +115,7 @@ public class AbstractTicketValidatorTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAbstractTicketValidator extends AbstractTicketValidator { private boolean returnTicket; diff --git a/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidatorTests.java b/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidatorTests.java index 3b685d860e..ee954baf24 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/ticketvalidator/CasProxyTicketValidatorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,9 @@ import junit.framework.TestCase; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.cas.TicketResponse; + import org.acegisecurity.ui.cas.ServiceProperties; import java.util.Vector; @@ -34,7 +36,7 @@ import java.util.Vector; * @version $Id$ */ public class CasProxyTicketValidatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasProxyTicketValidatorTests() { super(); @@ -44,21 +46,20 @@ public class CasProxyTicketValidatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasProxyTicketValidatorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() { CasProxyTicketValidator tv = new CasProxyTicketValidator(); tv.setProxyCallbackUrl("http://my.com/webapp/casProxy/someValidator"); - assertEquals("http://my.com/webapp/casProxy/someValidator", - tv.getProxyCallbackUrl()); + assertEquals("http://my.com/webapp/casProxy/someValidator", tv.getProxyCallbackUrl()); } public void testNormalOperation() { @@ -71,8 +72,7 @@ public class CasProxyTicketValidatorTests extends TestCase { tv.setServiceProperties(sp); tv.setProxyCallbackUrl("http://my.com/webapp/casProxy/someValidator"); - TicketResponse response = tv.confirmTicketValid( - "ST-0-ER94xMJmn6pha35CQRoZ"); + TicketResponse response = tv.confirmTicketValid("ST-0-ER94xMJmn6pha35CQRoZ"); assertEquals("user", response.getUser()); } @@ -92,8 +92,7 @@ public class CasProxyTicketValidatorTests extends TestCase { } public void testValidationFailsOkAndOperationWithoutAProxyCallbackUrl() { - CasProxyTicketValidator tv = new MockCasProxyTicketValidator(false, - false); + CasProxyTicketValidator tv = new MockCasProxyTicketValidator(false, false); tv.setCasValidate("https://company.com/cas/proxyvalidate"); tv.setServiceProperties(new ServiceProperties()); @@ -105,14 +104,13 @@ public class CasProxyTicketValidatorTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockCasProxyTicketValidator extends CasProxyTicketValidator { private boolean returnTicket; private boolean throwAuthenticationServiceException; - public MockCasProxyTicketValidator(boolean returnTicket, - boolean throwAuthenticationServiceException) { + public MockCasProxyTicketValidator(boolean returnTicket, boolean throwAuthenticationServiceException) { this.returnTicket = returnTicket; this.throwAuthenticationServiceException = throwAuthenticationServiceException; } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java index 7a3b6f6fe3..3848fdd109 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.providers.dao; -import java.util.HashMap; -import java.util.Map; - import junit.framework.TestCase; import org.acegisecurity.AccountExpiredException; @@ -29,19 +26,25 @@ import org.acegisecurity.DisabledException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.LockedException; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache; import org.acegisecurity.providers.dao.cache.NullUserCache; import org.acegisecurity.providers.dao.salt.SystemWideSaltSource; import org.acegisecurity.providers.encoding.ShaPasswordEncoder; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.DataRetrievalFailureException; +import java.util.HashMap; +import java.util.Map; + /** * Tests {@link DaoAuthenticationProvider}. @@ -50,19 +53,18 @@ import org.springframework.dao.DataRetrievalFailureException; * @version $Id$ */ public class DaoAuthenticationProviderTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(DaoAuthenticationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticateFailsForIncorrectPasswordCase() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "KOala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "KOala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserMarissa()); @@ -77,8 +79,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsIfAccountExpired() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", - "opal"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserPeterAccountExpired()); @@ -93,8 +94,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsIfAccountLocked() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", - "opal"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserPeterAccountLocked()); @@ -109,8 +109,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsIfCredentialsExpired() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", - "opal"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserPeterCredentialsExpired()); @@ -124,8 +123,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } // Check that wrong password causes BadCredentialsException, rather than CredentialsExpiredException - token = new UsernamePasswordAuthenticationToken("peter", - "wrong_password"); + token = new UsernamePasswordAuthenticationToken("peter", "wrong_password"); try { provider.authenticate(token); @@ -136,8 +134,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsIfUserDisabled() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", - "opal"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserPeter()); @@ -152,8 +149,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsWhenAuthenticationDaoHasBackendFailure() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoSimulateBackendError()); @@ -168,8 +164,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsWithEmptyUsername() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserMarissa()); @@ -200,8 +195,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionFalse() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions @@ -217,8 +211,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionsWithDefaultOfTrue() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); assertTrue(provider.isHideUserNotFoundExceptions()); @@ -234,8 +227,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserMarissa()); @@ -250,8 +242,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticates() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); token.setDetails("192.168.0.1"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); @@ -261,8 +252,7 @@ public class DaoAuthenticationProviderTests extends TestCase { Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { - fail( - "Should have returned instance of UsernamePasswordAuthenticationToken"); + fail("Should have returned instance of UsernamePasswordAuthenticationToken"); } UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; @@ -274,8 +264,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticatesASecondTime() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserMarissa()); @@ -284,24 +273,21 @@ public class DaoAuthenticationProviderTests extends TestCase { Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { - fail( - "Should have returned instance of UsernamePasswordAuthenticationToken"); + fail("Should have returned instance of UsernamePasswordAuthenticationToken"); } // Now try to authenticate with the previous result (with its UserDetails) Authentication result2 = provider.authenticate(result); if (!(result2 instanceof UsernamePasswordAuthenticationToken)) { - fail( - "Should have returned instance of UsernamePasswordAuthenticationToken"); + fail("Should have returned instance of UsernamePasswordAuthenticationToken"); } assertEquals(result.getCredentials(), result2.getCredentials()); } public void testAuthenticatesWhenASaltIsUsed() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); SystemWideSaltSource salt = new SystemWideSaltSource(); salt.setSystemWideSalt("SYSTEM_SALT_VALUE"); @@ -314,8 +300,7 @@ public class DaoAuthenticationProviderTests extends TestCase { Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { - fail( - "Should have returned instance of UsernamePasswordAuthenticationToken"); + fail("Should have returned instance of UsernamePasswordAuthenticationToken"); } UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; @@ -328,8 +313,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testAuthenticatesWithForcePrincipalAsString() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoUserMarissa()); @@ -339,8 +323,7 @@ public class DaoAuthenticationProviderTests extends TestCase { Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { - fail( - "Should have returned instance of UsernamePasswordAuthenticationToken"); + fail("Should have returned instance of UsernamePasswordAuthenticationToken"); } UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; @@ -349,8 +332,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testDetectsNullBeingReturnedFromAuthenticationDao() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(new MockAuthenticationDaoReturnsNull()); @@ -367,16 +349,13 @@ public class DaoAuthenticationProviderTests extends TestCase { public void testGettersSetters() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setPasswordEncoder(new ShaPasswordEncoder()); - assertEquals(ShaPasswordEncoder.class, - provider.getPasswordEncoder().getClass()); + assertEquals(ShaPasswordEncoder.class, provider.getPasswordEncoder().getClass()); provider.setSaltSource(new SystemWideSaltSource()); - assertEquals(SystemWideSaltSource.class, - provider.getSaltSource().getClass()); + assertEquals(SystemWideSaltSource.class, provider.getSaltSource().getClass()); provider.setUserCache(new EhCacheBasedUserCache()); - assertEquals(EhCacheBasedUserCache.class, - provider.getUserCache().getClass()); + assertEquals(EhCacheBasedUserCache.class, provider.getUserCache().getClass()); assertFalse(provider.isForcePrincipalAsString()); provider.setForcePrincipalAsString(true); @@ -384,8 +363,7 @@ public class DaoAuthenticationProviderTests extends TestCase { } public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswordSeemsIncorrect() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala"); MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa(); MockUserCache cache = new MockUserCache(); @@ -403,14 +381,12 @@ public class DaoAuthenticationProviderTests extends TestCase { authenticationDao.setPassword("easternLongNeckTurtle"); // Now try authentication again, with the new password - token = new UsernamePasswordAuthenticationToken("marissa", - "easternLongNeckTurtle"); + token = new UsernamePasswordAuthenticationToken("marissa", "easternLongNeckTurtle"); provider.authenticate(token); // To get this far, the new password was accepted // Check the cache was updated - assertEquals("easternLongNeckTurtle", - cache.getUserFromCache("marissa").getPassword()); + assertEquals("easternLongNeckTurtle", cache.getUserFromCache("marissa").getPassword()); } public void testStartupFailsIfNoAuthenticationDao() @@ -455,7 +431,7 @@ public class DaoAuthenticationProviderTests extends TestCase { assertTrue(!provider.supports(TestingAuthenticationToken.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAuthenticationDaoReturnsNull implements UserDetailsService { public UserDetails loadUserByUsername(String username) @@ -464,47 +440,39 @@ public class DaoAuthenticationProviderTests extends TestCase { } } - private class MockAuthenticationDaoSimulateBackendError - implements UserDetailsService { + private class MockAuthenticationDaoSimulateBackendError implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - throw new DataRetrievalFailureException( - "This mock simulator is designed to fail"); + throw new DataRetrievalFailureException("This mock simulator is designed to fail"); } } private class MockAuthenticationDaoUserMarissa implements UserDetailsService { private String password = "koala"; - public void setPassword(String password) { - this.password = password; - } - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("marissa".equals(username)) { return new User("marissa", password, true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } + + public void setPassword(String password) { + this.password = password; + } } - private class MockAuthenticationDaoUserMarissaWithSalt - implements UserDetailsService { + private class MockAuthenticationDaoUserMarissaWithSalt implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("marissa".equals(username)) { - return new User("marissa", "koala{SYSTEM_SALT_VALUE}", true, - true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + return new User("marissa", "koala{SYSTEM_SALT_VALUE}", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } @@ -514,56 +482,45 @@ public class DaoAuthenticationProviderTests extends TestCase { throws UsernameNotFoundException, DataAccessException { if ("peter".equals(username)) { return new User("peter", "opal", false, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } - private class MockAuthenticationDaoUserPeterAccountExpired - implements UserDetailsService { + private class MockAuthenticationDaoUserPeterAccountExpired implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("peter".equals(username)) { return new User("peter", "opal", true, false, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } - private class MockAuthenticationDaoUserPeterAccountLocked - implements UserDetailsService { + private class MockAuthenticationDaoUserPeterAccountLocked implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("peter".equals(username)) { return new User("peter", "opal", true, true, true, false, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } - private class MockAuthenticationDaoUserPeterCredentialsExpired - implements UserDetailsService { + private class MockAuthenticationDaoUserPeterCredentialsExpired implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("peter".equals(username)) { return new User("peter", "opal", true, true, false, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java b/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java index b855716563..1768abc09f 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,13 @@ package org.acegisecurity.providers.dao.cache; import junit.framework.TestCase; +import net.sf.ehcache.Cache; + import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.MockApplicationContext; -import org.acegisecurity.userdetails.User; -import net.sf.ehcache.Cache; +import org.acegisecurity.userdetails.User; import org.springframework.context.ApplicationContext; @@ -34,7 +35,7 @@ import org.springframework.context.ApplicationContext; * @version $Id$ */ public class EhCacheBasedUserCacheTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public EhCacheBasedUserCacheTests() { super(); @@ -44,16 +45,27 @@ public class EhCacheBasedUserCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private Cache getCache() { + ApplicationContext ctx = MockApplicationContext.getContext(); + + return (Cache) ctx.getBean("eHCacheBackend"); + } + + private User getUser() { + return new User("john", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } public static void main(String[] args) { junit.textui.TestRunner.run(EhCacheBasedUserCacheTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCacheOperation() throws Exception { EhCacheBasedUserCache cache = new EhCacheBasedUserCache(); cache.setCache(getCache()); @@ -61,8 +73,7 @@ public class EhCacheBasedUserCacheTests extends TestCase { // Check it gets stored in the cache cache.putUserInCache(getUser()); - assertEquals(getUser().getPassword(), - cache.getUserFromCache(getUser().getUsername()).getPassword()); + assertEquals(getUser().getPassword(), cache.getUserFromCache(getUser().getUsername()).getPassword()); // Check it gets removed from the cache cache.removeUserFromCache(getUser()); @@ -87,16 +98,4 @@ public class EhCacheBasedUserCacheTests extends TestCase { cache.setCache(myCache); assertEquals(myCache, cache.getCache()); } - - private Cache getCache() { - ApplicationContext ctx = MockApplicationContext.getContext(); - - return (Cache) ctx.getBean("eHCacheBackend"); - } - - private User getUser() { - return new User("john", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - } } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java b/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java index 488836809d..f1577a7b0b 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.userdetails.User; @@ -29,7 +30,7 @@ import org.acegisecurity.userdetails.User; * @version $Id$ */ public class NullUserCacheTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NullUserCacheTests() { super(); @@ -39,26 +40,25 @@ public class NullUserCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private User getUser() { + return new User("john", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } public static void main(String[] args) { junit.textui.TestRunner.run(NullUserCacheTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCacheOperation() throws Exception { NullUserCache cache = new NullUserCache(); cache.putUserInCache(getUser()); assertNull(cache.getUserFromCache(null)); cache.removeUserFromCache(null); } - - private User getUser() { - return new User("john", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - } } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSourceTests.java b/core/src/test/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSourceTests.java index 18430d3786..e7efc2173b 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSourceTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/salt/ReflectionSaltSourceTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; @@ -31,7 +32,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class ReflectionSaltSourceTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ReflectionSaltSourceTests() { super(); @@ -41,16 +42,16 @@ public class ReflectionSaltSourceTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ReflectionSaltSourceTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingUserPropertyToUse() throws Exception { ReflectionSaltSource saltSource = new ReflectionSaltSource(); @@ -58,8 +59,7 @@ public class ReflectionSaltSourceTests extends TestCase { saltSource.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A userPropertyToUse must be set", - expected.getMessage()); + assertEquals("A userPropertyToUse must be set", expected.getMessage()); } } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSourceTests.java b/core/src/test/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSourceTests.java index ae88f3b352..703f00b4c3 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSourceTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/salt/SystemWideSaltSourceTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class SystemWideSaltSourceTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SystemWideSaltSourceTests() { super(); @@ -35,16 +35,16 @@ public class SystemWideSaltSourceTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SystemWideSaltSourceTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingSystemWideSalt() throws Exception { SystemWideSaltSource saltSource = new SystemWideSaltSource(); diff --git a/core/src/test/java/org/acegisecurity/providers/encoding/BasePasswordEncoderTests.java b/core/src/test/java/org/acegisecurity/providers/encoding/BasePasswordEncoderTests.java index d306c4cd14..bb6819c58f 100644 --- a/core/src/test/java/org/acegisecurity/providers/encoding/BasePasswordEncoderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/encoding/BasePasswordEncoderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,15 +21,13 @@ import org.springframework.dao.DataAccessException; /** - *

- * TestCase for BasePasswordEncoder. - *

+ *

TestCase for BasePasswordEncoder.

* * @author Ben Alex * @version $Id$ */ public class BasePasswordEncoderTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testDemergeHandlesEmptyAndNullSalts() { MockPasswordEncoder pwd = new MockPasswordEncoder(); @@ -54,8 +52,7 @@ public class BasePasswordEncoderTests extends TestCase { pwd.nowDemergePasswordAndSalt(""); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Cannot pass a null or empty String", - expected.getMessage()); + assertEquals("Cannot pass a null or empty String", expected.getMessage()); } } @@ -66,8 +63,7 @@ public class BasePasswordEncoderTests extends TestCase { pwd.nowDemergePasswordAndSalt(null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Cannot pass a null or empty String", - expected.getMessage()); + assertEquals("Cannot pass a null or empty String", expected.getMessage()); } } @@ -112,8 +108,7 @@ public class BasePasswordEncoderTests extends TestCase { pwd.nowMergePasswordAndSalt("password", "f{oo", true); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Cannot use { or } in salt.toString()", - expected.getMessage()); + assertEquals("Cannot use { or } in salt.toString()", expected.getMessage()); } } @@ -124,32 +119,28 @@ public class BasePasswordEncoderTests extends TestCase { pwd.nowMergePasswordAndSalt("password", "f}oo", true); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Cannot use { or } in salt.toString()", - expected.getMessage()); + assertEquals("Cannot use { or } in salt.toString()", expected.getMessage()); } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockPasswordEncoder extends BasePasswordEncoder { - public boolean isPasswordValid(String encPass, String rawPass, - Object salt) throws DataAccessException { - throw new UnsupportedOperationException( - "mock method not implemented"); - } - public String encodePassword(String rawPass, Object salt) throws DataAccessException { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); + } + + public boolean isPasswordValid(String encPass, String rawPass, Object salt) + throws DataAccessException { + throw new UnsupportedOperationException("mock method not implemented"); } public String[] nowDemergePasswordAndSalt(String password) { return demergePasswordAndSalt(password); } - public String nowMergePasswordAndSalt(String password, Object salt, - boolean strict) { + public String nowMergePasswordAndSalt(String password, Object salt, boolean strict) { return mergePasswordAndSalt(password, salt, strict); } } diff --git a/core/src/test/java/org/acegisecurity/providers/encoding/Md5PasswordEncoderTests.java b/core/src/test/java/org/acegisecurity/providers/encoding/Md5PasswordEncoderTests.java index e2824334a8..88dc9dc3a1 100644 --- a/core/src/test/java/org/acegisecurity/providers/encoding/Md5PasswordEncoderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/encoding/Md5PasswordEncoderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,14 @@ import junit.framework.TestCase; /** - *

- * TestCase for PlaintextPasswordEncoder. - *

+ *

TestCase for PlaintextPasswordEncoder.

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ public class Md5PasswordEncoderTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testBasicFunctionality() { Md5PasswordEncoder pe = new Md5PasswordEncoder(); diff --git a/core/src/test/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoderTests.java b/core/src/test/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoderTests.java index 35d7fbea55..e84018198e 100644 --- a/core/src/test/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/encoding/PlaintextPasswordEncoderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,14 @@ import junit.framework.TestCase; /** - *

- * TestCase for PlaintextPasswordEncoder. - *

+ *

TestCase for PlaintextPasswordEncoder.

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ public class PlaintextPasswordEncoderTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testBasicFunctionality() { PlaintextPasswordEncoder pe = new PlaintextPasswordEncoder(); diff --git a/core/src/test/java/org/acegisecurity/providers/encoding/ShaPasswordEncoderTests.java b/core/src/test/java/org/acegisecurity/providers/encoding/ShaPasswordEncoderTests.java index 05f4e4b31e..13d1612d27 100644 --- a/core/src/test/java/org/acegisecurity/providers/encoding/ShaPasswordEncoderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/encoding/ShaPasswordEncoderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,14 @@ import junit.framework.TestCase; /** - *

- * TestCase for ShaPasswordEncoder. - *

+ *

TestCase for ShaPasswordEncoder.

* * @author colin sampaleanu * @author Ben Alex * @version $Id$ */ public class ShaPasswordEncoderTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testBasicFunctionality() { ShaPasswordEncoder pe = new ShaPasswordEncoder(); diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java index dd14a8396a..195c44051e 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,32 @@ package org.acegisecurity.providers.jaas; import junit.framework.TestCase; + import org.acegisecurity.*; + import org.acegisecurity.context.HttpSessionContextIntegrationFilter; import org.acegisecurity.context.SecurityContextImpl; -import org.acegisecurity.ui.session.HttpSessionDestroyedEvent; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.acegisecurity.ui.session.HttpSessionDestroyedEvent; + import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; + import org.springframework.mock.web.MockHttpSession; -import javax.security.auth.login.LoginException; -import javax.security.auth.login.LoginContext; import java.net.URL; + import java.security.Security; + import java.util.Arrays; import java.util.List; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + /** * Tests for the JaasAuthenticationProvider @@ -41,24 +50,29 @@ import java.util.List; * @version $Id$ */ public class JaasAuthenticationProviderTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ApplicationContext context; private JaasAuthenticationProvider jaasProvider; private JaasEventCheck eventCheck; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected void setUp() throws Exception { + String resName = "/" + getClass().getName().replace('.', '/') + ".xml"; + context = new ClassPathXmlApplicationContext(resName); + eventCheck = (JaasEventCheck) context.getBean("eventCheck"); + jaasProvider = (JaasAuthenticationProvider) context.getBean("jaasAuthenticationProvider"); + } public void testBadPassword() { try { jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("user", "asdf")); fail("LoginException should have been thrown for the bad password"); - } catch (AuthenticationException e) { - } + } catch (AuthenticationException e) {} assertNotNull("Failure event not fired", eventCheck.failedEvent); - assertNotNull("Failure event exception was null", - eventCheck.failedEvent.getException()); + assertNotNull("Failure event exception was null", eventCheck.failedEvent.getException()); assertNull("Success event was fired", eventCheck.successEvent); } @@ -66,12 +80,10 @@ public class JaasAuthenticationProviderTests extends TestCase { try { jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("asdf", "password")); fail("LoginException should have been thrown for the bad user"); - } catch (AuthenticationException e) { - } + } catch (AuthenticationException e) {} assertNotNull("Failure event not fired", eventCheck.failedEvent); - assertNotNull("Failure event exception was null", - eventCheck.failedEvent.getException()); + assertNotNull("Failure event exception was null", eventCheck.failedEvent.getException()); assertNull("Success event was fired", eventCheck.successEvent); } @@ -129,10 +141,10 @@ public class JaasAuthenticationProviderTests extends TestCase { GrantedAuthorityImpl role1 = new GrantedAuthorityImpl("ROLE_1"); GrantedAuthorityImpl role2 = new GrantedAuthorityImpl("ROLE_2"); - GrantedAuthority[] defaultAuths = new GrantedAuthority[]{role1, role2, }; + GrantedAuthority[] defaultAuths = new GrantedAuthority[] {role1, role2,}; - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", - "password", defaultAuths); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password", + defaultAuths); assertTrue(jaasProvider.supports(UsernamePasswordAuthenticationToken.class)); @@ -145,17 +157,13 @@ public class JaasAuthenticationProviderTests extends TestCase { List list = Arrays.asList(auth.getAuthorities()); - assertTrue("GrantedAuthorities should contain ROLE_TEST1", - list.contains(new GrantedAuthorityImpl("ROLE_TEST1"))); + assertTrue("GrantedAuthorities should contain ROLE_TEST1", list.contains(new GrantedAuthorityImpl("ROLE_TEST1"))); - assertTrue("GrantedAuthorities should contain ROLE_TEST2", - list.contains(new GrantedAuthorityImpl("ROLE_TEST2"))); + assertTrue("GrantedAuthorities should contain ROLE_TEST2", list.contains(new GrantedAuthorityImpl("ROLE_TEST2"))); - assertTrue("GrantedAuthorities should contain ROLE_1", - list.contains(role1)); + assertTrue("GrantedAuthorities should contain ROLE_1", list.contains(role1)); - assertTrue("GrantedAuthorities should contain ROLE_2", - list.contains(role2)); + assertTrue("GrantedAuthorities should contain ROLE_2", list.contains(role2)); boolean foundit = false; @@ -164,8 +172,7 @@ public class JaasAuthenticationProviderTests extends TestCase { if (obj instanceof JaasGrantedAuthority) { JaasGrantedAuthority grant = (JaasGrantedAuthority) obj; - assertNotNull("Principal was null on JaasGrantedAuthority", - grant.getPrincipal()); + assertNotNull("Principal was null on JaasGrantedAuthority", grant.getPrincipal()); foundit = true; } } @@ -173,50 +180,32 @@ public class JaasAuthenticationProviderTests extends TestCase { assertTrue("Could not find a JaasGrantedAuthority", foundit); assertNotNull("Success event not fired", eventCheck.successEvent); - assertEquals("Auth objects are not equal", auth, - eventCheck.successEvent.getAuthentication()); + assertEquals("Auth objects are not equal", auth, eventCheck.successEvent.getAuthentication()); assertNull("Failure event was fired", eventCheck.failedEvent); } - public void testLoginExceptionResolver() { - assertNotNull(jaasProvider.getLoginExceptionResolver()); - jaasProvider.setLoginExceptionResolver(new LoginExceptionResolver() { - public AcegiSecurityException resolveException(LoginException e) { - return new LockedException("This is just a test!"); - } - }); - - try { - jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("user", "password")); - } catch (LockedException e) { - } catch (Exception e) { - fail("LockedException should have been thrown and caught"); - } - } - - public void testNullDefaultAuthorities() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", - "password", null); - - assertTrue(jaasProvider.supports(UsernamePasswordAuthenticationToken.class)); - - Authentication auth = jaasProvider.authenticate(token); - assertTrue("Only ROLE_TEST1 and ROLE_TEST2 should have been returned", - auth.getAuthorities().length == 2); - } - public void testGetApplicationContext() throws Exception { assertNotNull(jaasProvider.getApplicationContext()); } - public void testUnsupportedAuthenticationObjectReturnsNull() { - assertNull(jaasProvider.authenticate(new TestingAuthenticationToken("foo", "bar", - new GrantedAuthority[]{}))); + public void testLoginExceptionResolver() { + assertNotNull(jaasProvider.getLoginExceptionResolver()); + jaasProvider.setLoginExceptionResolver(new LoginExceptionResolver() { + public AcegiSecurityException resolveException(LoginException e) { + return new LockedException("This is just a test!"); + } + }); + + try { + jaasProvider.authenticate(new UsernamePasswordAuthenticationToken("user", "password")); + } catch (LockedException e) {} + catch (Exception e) { + fail("LockedException should have been thrown and caught"); + } } public void testLogout() throws Exception { - MockLoginContext loginContext = new MockLoginContext(jaasProvider.getLoginContextName()); JaasAuthenticationToken token = new JaasAuthenticationToken(null, null, loginContext); @@ -232,15 +221,22 @@ public class JaasAuthenticationProviderTests extends TestCase { assertTrue(loginContext.loggedOut); } - protected void setUp() throws Exception { - String resName = "/" + getClass().getName().replace('.', '/') + ".xml"; - context = new ClassPathXmlApplicationContext(resName); - eventCheck = (JaasEventCheck) context.getBean("eventCheck"); - jaasProvider = (JaasAuthenticationProvider) context.getBean("jaasAuthenticationProvider"); + public void testNullDefaultAuthorities() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password", null); + + assertTrue(jaasProvider.supports(UsernamePasswordAuthenticationToken.class)); + + Authentication auth = jaasProvider.authenticate(token); + assertTrue("Only ROLE_TEST1 and ROLE_TEST2 should have been returned", auth.getAuthorities().length == 2); } - private static class MockLoginContext extends LoginContext { + public void testUnsupportedAuthenticationObjectReturnsNull() { + assertNull(jaasProvider.authenticate(new TestingAuthenticationToken("foo", "bar", new GrantedAuthority[] {}))); + } + //~ Inner Classes ================================================================================================== + + private static class MockLoginContext extends LoginContext { boolean loggedOut = false; public MockLoginContext(String loginModule) throws LoginException { diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java b/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java index 221eea9fd9..014e8db687 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/JaasEventCheck.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,12 +29,12 @@ import org.springframework.context.ApplicationListener; * @version $Id$ */ public class JaasEventCheck implements ApplicationListener { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ JaasAuthenticationFailedEvent failedEvent; JaasAuthenticationSuccessEvent successEvent; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void onApplicationEvent(ApplicationEvent event) { if (event instanceof JaasAuthenticationFailedEvent) { diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/SecurityContextLoginModuleTests.java b/core/src/test/java/org/acegisecurity/providers/jaas/SecurityContextLoginModuleTests.java index 2530abb0ef..78edff174f 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/SecurityContextLoginModuleTests.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/SecurityContextLoginModuleTests.java @@ -35,15 +35,14 @@ import javax.security.auth.login.LoginException; * @author Ray Krueger */ public class SecurityContextLoginModuleTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private SecurityContextLoginModule module = null; - private Subject subject = new Subject(false, new HashSet(), new HashSet(), - new HashSet()); + private Subject subject = new Subject(false, new HashSet(), new HashSet(), new HashSet()); private UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("principal", "credentials"); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { module = new SecurityContextLoginModule(); @@ -67,27 +66,22 @@ public class SecurityContextLoginModuleTests extends TestCase { public void testLoginException() throws Exception { try { module.login(); - fail( - "LoginException expected, there is no Authentication in the SecurityContext"); + fail("LoginException expected, there is no Authentication in the SecurityContext"); } catch (LoginException e) {} } public void testLoginSuccess() throws Exception { SecurityContextHolder.getContext().setAuthentication(auth); - assertTrue("Login should succeed, there is an authentication set", - module.login()); - assertTrue("The authentication is not null, this should return true", - module.commit()); - assertTrue("Principals should contain the authentication", - subject.getPrincipals().contains(auth)); + assertTrue("Login should succeed, there is an authentication set", module.login()); + assertTrue("The authentication is not null, this should return true", module.commit()); + assertTrue("Principals should contain the authentication", subject.getPrincipals().contains(auth)); } public void testLogout() throws Exception { SecurityContextHolder.getContext().setAuthentication(auth); module.login(); assertTrue("Should return true as it succeeds", module.logout()); - assertEquals("Authentication should be null", null, - module.getAuthentication()); + assertEquals("Authentication should be null", null, module.getAuthentication()); assertFalse("Principals should not contain the authentication after logout", subject.getPrincipals().contains(auth)); @@ -98,8 +92,7 @@ public class SecurityContextLoginModuleTests extends TestCase { try { SecurityContextHolder.getContext().setAuthentication(null); module.login(); - fail( - "LoginException expected, the authentication is null in the SecurityContext"); + fail("LoginException expected, the authentication is null in the SecurityContext"); } catch (Exception e) {} } diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java index 197125d147..d529dd7a42 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestAuthorityGranter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import java.util.Set; * @version $Id$ */ public class TestAuthorityGranter implements AuthorityGranter { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Set grant(Principal principal) { Set rtnSet = new HashSet(); diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java index 730c17dffb..d840e986a5 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestCallbackHandler.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * @version $Id$ */ public class TestCallbackHandler implements JaasAuthenticationCallbackHandler { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void handle(Callback callback, Authentication auth) throws IOException, UnsupportedCallbackException { diff --git a/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java b/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java index e4f422c149..a1599b817a 100644 --- a/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java +++ b/core/src/test/java/org/acegisecurity/providers/jaas/TestLoginModule.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,13 +32,13 @@ import javax.security.auth.spi.LoginModule; * @version $Id$ */ public class TestLoginModule implements LoginModule { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String password; private String user; private Subject subject; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean abort() throws LoginException { return true; @@ -48,15 +48,13 @@ public class TestLoginModule implements LoginModule { return true; } - public void initialize(Subject subject, CallbackHandler callbackHandler, - Map sharedState, Map options) { + public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { this.subject = subject; try { TextInputCallback textCallback = new TextInputCallback("prompt"); NameCallback nameCallback = new NameCallback("prompt"); - PasswordCallback passwordCallback = new PasswordCallback("prompt", - false); + PasswordCallback passwordCallback = new PasswordCallback("prompt", false); callbackHandler.handle(new Callback[] {textCallback, nameCallback, passwordCallback}); diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java index db58dc8ae1..a64a2f0db7 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java @@ -1,25 +1,47 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap; +import junit.framework.TestCase; + +import org.acegisecurity.BadCredentialsException; +import org.acegisecurity.GrantedAuthority; +import org.acegisecurity.GrantedAuthorityImpl; + +import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; + +import java.util.ArrayList; + import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.GrantedAuthorityImpl; -import org.acegisecurity.BadCredentialsException; -import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; - -import java.util.ArrayList; - -import junit.framework.TestCase; /** + * +DOCUMENT ME! + * * @author Luke Taylor * @version $Id$ */ public class LdapAuthenticationProviderTests extends TestCase { + //~ Constructors =================================================================================================== public LdapAuthenticationProviderTests(String string) { super(string); @@ -29,13 +51,48 @@ public class LdapAuthenticationProviderTests extends TestCase { super(); } + //~ Methods ======================================================================================================== + + public void testDifferentCacheValueCausesException() { + LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), + new MockAuthoritiesPopulator()); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); + + // User is authenticated here + UserDetails user = ldapProvider.retrieveUser("bob", authRequest); + // Assume the user details object is cached... + + // And a subsequent authentication request comes in on the cached data + authRequest = new UsernamePasswordAuthenticationToken("bob", "wrongpassword"); + + try { + ldapProvider.additionalAuthenticationChecks(user, authRequest); + fail("Expected BadCredentialsException should have failed with wrong password"); + } catch (BadCredentialsException expected) {} + } + + public void testEmptyOrNullUserNameThrowsException() { + LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), + new MockAuthoritiesPopulator()); + + try { + ldapProvider.retrieveUser("", new UsernamePasswordAuthenticationToken("bob", "bobspassword")); + fail("Expected BadCredentialsException for empty username"); + } catch (BadCredentialsException expected) {} + + try { + ldapProvider.retrieveUser(null, new UsernamePasswordAuthenticationToken("bob", "bobspassword")); + fail("Expected BadCredentialsException for null username"); + } catch (BadCredentialsException expected) {} + } + public void testNormalUsage() { - LdapAuthenticationProvider ldapProvider - = new LdapAuthenticationProvider(new MockAuthenticator(), new MockAuthoritiesPopulator()); + LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), + new MockAuthoritiesPopulator()); assertNotNull(ldapProvider.getAuthoritiesPoulator()); - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob","bobspassword"); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); UserDetails user = ldapProvider.retrieveUser("bob", authRequest); assertEquals(2, user.getAuthorities().length); assertEquals("bobspassword", user.getPassword()); @@ -51,42 +108,26 @@ public class LdapAuthenticationProviderTests extends TestCase { ldapProvider.additionalAuthenticationChecks(user, authRequest); } - public void testDifferentCacheValueCausesException() { - LdapAuthenticationProvider ldapProvider - = new LdapAuthenticationProvider(new MockAuthenticator(), new MockAuthoritiesPopulator()); - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob","bobspassword"); - // User is authenticated here - UserDetails user = ldapProvider.retrieveUser("bob", authRequest); - // Assume the user details object is cached... + //~ Inner Classes ================================================================================================== - // And a subsequent authentication request comes in on the cached data - authRequest = new UsernamePasswordAuthenticationToken("bob","wrongpassword"); + class MockAuthenticator implements LdapAuthenticator { + Attributes userAttributes = new BasicAttributes("cn", "bob"); - try { - ldapProvider.additionalAuthenticationChecks(user, authRequest); - fail("Expected BadCredentialsException should have failed with wrong password"); - } catch(BadCredentialsException expected) { + public LdapUserDetails authenticate(String username, String password) { + if (username.equals("bob") && password.equals("bobspassword")) { + LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); + userEssence.setDn("cn=bob,ou=people,dc=acegisecurity,dc=org"); + userEssence.setPassword("{SHA}anencodedpassword"); + userEssence.setAttributes(userAttributes); + userEssence.addAuthority(new GrantedAuthorityImpl("ROLE_FROM_ENTRY")); + + return userEssence.createUserDetails(); + } + + throw new BadCredentialsException("Authentication of Bob failed."); } } - public void testEmptyOrNullUserNameThrowsException() { - LdapAuthenticationProvider ldapProvider - = new LdapAuthenticationProvider(new MockAuthenticator(), new MockAuthoritiesPopulator()); - - try { - ldapProvider.retrieveUser("", new UsernamePasswordAuthenticationToken("bob","bobspassword")); - fail("Expected BadCredentialsException for empty username"); - } catch(BadCredentialsException expected) { - } - - try { - ldapProvider.retrieveUser(null, new UsernamePasswordAuthenticationToken("bob","bobspassword")); - fail("Expected BadCredentialsException for null username"); - } catch(BadCredentialsException expected) { - } - - } - // This test kills apacheDS in embedded mode because the search returns an invalid DN // public void testIntegration() throws Exception { // BindAuthenticator authenticator = new BindAuthenticator(getInitialCtxFactory()); @@ -107,27 +148,9 @@ public class LdapAuthenticationProviderTests extends TestCase { // Authentication auth = ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("Ben Alex","benspassword")); // assertEquals(2, auth.getAuthorities().length); // } - class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator { - public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetailsll) { - return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR") }; - } - } - - class MockAuthenticator implements LdapAuthenticator { - Attributes userAttributes = new BasicAttributes("cn","bob"); - - public LdapUserDetails authenticate(String username, String password) { - if(username.equals("bob") && password.equals("bobspassword")) { - LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); - userEssence.setDn("cn=bob,ou=people,dc=acegisecurity,dc=org"); - userEssence.setPassword("{SHA}anencodedpassword"); - userEssence.setAttributes(userAttributes); - userEssence.addAuthority(new GrantedAuthorityImpl("ROLE_FROM_ENTRY")); - return userEssence.createUserDetails(); - } - throw new BadCredentialsException("Authentication of Bob failed."); + return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR")}; } } } diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java index b311208dac..574e5fb9ed 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java @@ -1,13 +1,31 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap.authenticator; -import org.acegisecurity.ldap.AbstractLdapServerTestCase; +import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthorityImpl; -import org.acegisecurity.AcegiMessageSource; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; + +import org.acegisecurity.ldap.AbstractLdapServerTestCase; + import org.acegisecurity.userdetails.ldap.LdapUserDetails; +import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; + /** * Tests for {@link BindAuthenticator}. * @@ -15,34 +33,31 @@ import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; * @version $Id$ */ public class BindAuthenticatorTests extends AbstractLdapServerTestCase { + //~ Instance fields ================================================================================================ private BindAuthenticator authenticator; + //~ Methods ======================================================================================================== + public void onSetUp() { authenticator = new BindAuthenticator(getInitialCtxFactory()); - authenticator.setMessageSource(new AcegiMessageSource()); - } - - public void testUserDnPatternReturnsCorrectDn() { - authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); - assertEquals("cn=Joe,ou=people,"+ getInitialCtxFactory().getRootDn(), - authenticator.getUserDns("Joe").get(0)); + authenticator.setMessageSource(new AcegiMessageSource()); } public void testAuthenticationWithCorrectPasswordSucceeds() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); - LdapUserDetails user = authenticator.authenticate("bob","bobspassword"); + + LdapUserDetails user = authenticator.authenticate("bob", "bobspassword"); assertEquals("bob", user.getUsername()); } - public void testAuthenticationWithWrongPasswordFails() { + public void testAuthenticationWithInvalidUserNameFails() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); try { - authenticator.authenticate("bob","wrongpassword"); - fail("Shouldn't be able to bind with wrong password"); - } catch(BadCredentialsException expected) { - } + authenticator.authenticate("nonexistentsuser", "bobspassword"); + fail("Shouldn't be able to bind with invalid username"); + } catch (BadCredentialsException expected) {} } public void testAuthenticationWithUserSearch() throws Exception { @@ -51,31 +66,35 @@ public class BindAuthenticatorTests extends AbstractLdapServerTestCase { authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails())); authenticator.afterPropertiesSet(); - authenticator.authenticate("bob","bobspassword"); + authenticator.authenticate("bob", "bobspassword"); } - public void testAuthenticationWithInvalidUserNameFails() { + public void testAuthenticationWithWrongPasswordFails() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); try { - authenticator.authenticate("nonexistentsuser","bobspassword"); - fail("Shouldn't be able to bind with invalid username"); - } catch(BadCredentialsException expected) { - } + authenticator.authenticate("bob", "wrongpassword"); + fail("Shouldn't be able to bind with wrong password"); + } catch (BadCredentialsException expected) {} } // TODO: Create separate tests for base class public void testRoleRetrieval() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); + LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper(); userMapper.setRoleAttributes(new String[] {"uid"}); authenticator.setUserDetailsMapper(userMapper); - LdapUserDetails user = authenticator.authenticate("bob","bobspassword"); + LdapUserDetails user = authenticator.authenticate("bob", "bobspassword"); assertEquals(1, user.getAuthorities().length); assertEquals(new GrantedAuthorityImpl("ROLE_BOB"), user.getAuthorities()[0]); } -} + public void testUserDnPatternReturnsCorrectDn() { + authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); + assertEquals("cn=Joe,ou=people," + getInitialCtxFactory().getRootDn(), authenticator.getUserDns("Joe").get(0)); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoderTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoderTests.java index b96228827c..2dd3cd388f 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.providers.ldap.authenticator; import junit.framework.TestCase; + /** * Tests {@link LdapShaPasswordEncoder}. * @@ -24,28 +25,21 @@ import junit.framework.TestCase; * @version $Id$ */ public class LdapShaPasswordEncoderTests extends TestCase { + //~ Instance fields ================================================================================================ + LdapShaPasswordEncoder sha; + //~ Methods ======================================================================================================== + protected void setUp() throws Exception { super.setUp(); sha = new LdapShaPasswordEncoder(); } - /** Test values generated by 'slappasswd -h {SHA} -s boabspasswurd' */ - public void testValidPasswordSucceeds() { - assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null)); - } - public void testInvalidPasswordFails() { assertFalse(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "wrongpassword", null)); } - /** Test values generated by 'slappasswd -s boabspasswurd' */ - public void testValidSaltedPasswordSucceeds() { - assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "boabspasswurd", null)); - assertTrue(sha.isPasswordValid("{SSHA}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "boabspasswurd", null)); - } - public void testInvalidSaltedPasswordFails() { assertFalse(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "wrongpassword", null)); assertFalse(sha.isPasswordValid("{SSHA}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "wrongpassword", null)); @@ -54,7 +48,21 @@ public class LdapShaPasswordEncoderTests extends TestCase { public void testNonByteArraySaltThrowsException() { try { sha.encodePassword("password", "AStringNotAByteArray"); - } catch(IllegalArgumentException expected) { - } + } catch (IllegalArgumentException expected) {} + } + + /** + * Test values generated by 'slappasswd -h {SHA} -s boabspasswurd' + */ + public void testValidPasswordSucceeds() { + assertTrue(sha.isPasswordValid("{SHA}ddSFGmjXYPbZC+NXR2kCzBRjqiE=", "boabspasswurd", null)); + } + + /** + * Test values generated by 'slappasswd -s boabspasswurd' + */ + public void testValidSaltedPasswordSucceeds() { + assertTrue(sha.isPasswordValid("{SSHA}25ro4PKC8jhQZ26jVsozhX/xaP0suHgX", "boabspasswurd", null)); + assertTrue(sha.isPasswordValid("{SSHA}PQy2j+6n5ytA+YlAKkM8Fh4p6u2JxfVd", "boabspasswurd", null)); } } diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java index 882d2b3da8..0aadada115 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java @@ -1,19 +1,45 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap.authenticator; import org.acegisecurity.ldap.LdapUserSearch; + import org.acegisecurity.userdetails.ldap.LdapUserDetails; + /** + * +DOCUMENT ME! + * * @author Luke Taylor * @version $Id$ */ public class MockUserSearch implements LdapUserSearch { + //~ Instance fields ================================================================================================ + LdapUserDetails user; + //~ Constructors =================================================================================================== + public MockUserSearch(LdapUserDetails user) { this.user = user; } + //~ Methods ======================================================================================================== + public LdapUserDetails searchForUser(String username) { return user; } diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java index 775b110834..4fd8ea5511 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java @@ -1,38 +1,60 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap.authenticator; +import org.acegisecurity.ldap.MockInitialDirContextFactory; + import org.jmock.Mock; import org.jmock.MockObjectTestCase; -import org.acegisecurity.ldap.MockInitialDirContextFactory; -import javax.naming.directory.DirContext; -import javax.naming.directory.BasicAttributes; import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; + /** + * +DOCUMENT ME! + * * @author Luke Taylor * @version $Id$ */ public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase { + //~ Methods ======================================================================================================== - public void testLdapCompareIsUsedWhenPasswordIsNotRetrieved() throws Exception { + public void testLdapCompareIsUsedWhenPasswordIsNotRetrieved() + throws Exception { Mock mockCtx = mock(DirContext.class); - PasswordComparisonAuthenticator authenticator = - new PasswordComparisonAuthenticator(new MockInitialDirContextFactory( - (DirContext)mockCtx.proxy(), - "dc=acegisecurity,dc=org") - ); + PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(new MockInitialDirContextFactory( + (DirContext) mockCtx.proxy(), "dc=acegisecurity,dc=org")); authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); // Get the mock to return an empty attribute set mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); mockCtx.expects(once()).method("lookup").with(eq("cn=Bob,ou=people")).will(returnValue(true)); - mockCtx.expects(once()).method("getAttributes").with(eq("cn=Bob,ou=people"), NULL).will(returnValue(new BasicAttributes())); + mockCtx.expects(once()).method("getAttributes").with(eq("cn=Bob,ou=people"), NULL) + .will(returnValue(new BasicAttributes())); + // Setup a single return value (i.e. success) Attributes searchResults = new BasicAttributes("", null); - mockCtx.expects(once()).method("search").with(eq("cn=Bob,ou=people"), - eq("(userPassword={0})"), NOT_NULL, NOT_NULL).will(returnValue(searchResults.getAll())); + mockCtx.expects(once()).method("search") + .with(eq("cn=Bob,ou=people"), eq("(userPassword={0})"), NOT_NULL, NOT_NULL) + .will(returnValue(searchResults.getAll())); mockCtx.expects(atLeastOnce()).method("close"); authenticator.authenticate("Bob", "bobspassword"); } diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java index 3758c2bc8d..9fdac34966 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java @@ -1,12 +1,31 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap.authenticator; -import org.acegisecurity.ldap.AbstractLdapServerTestCase; import org.acegisecurity.BadCredentialsException; + +import org.acegisecurity.ldap.AbstractLdapServerTestCase; + import org.acegisecurity.providers.encoding.PlaintextPasswordEncoder; + import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; -import org.acegisecurity.userdetails.ldap.LdapUserDetails; + /** * Tests for {@link PasswordComparisonAuthenticator}. @@ -15,8 +34,12 @@ import org.acegisecurity.userdetails.ldap.LdapUserDetails; * @version $Id$ */ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTestCase { + //~ Instance fields ================================================================================================ + private PasswordComparisonAuthenticator authenticator; + //~ Methods ======================================================================================================== + public void onSetUp() { getInitialCtxFactory().setManagerDn(MANAGER_USER); getInitialCtxFactory().setManagerPassword(MANAGER_PASSWORD); @@ -25,45 +48,51 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTest } public void tearDown() { - // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); - } - /* - public void testLdapCompareSucceedsWithCorrectPassword() { - // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"cn"}); - // Bob has a plaintext password. - authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); - authenticator.authenticate("bob", "bobspassword"); + // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); } - public void testLdapCompareSucceedsWithShaEncodedPassword() { - authenticator = new PasswordComparisonAuthenticator(); - authenticator.setInitialDirContextFactory(dirCtxFactory); - authenticator.setUserDnPatterns("uid={0},ou=people"); - // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"cn"}); + public void testAllAttributesAreRetrivedByDefault() { + LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); + //System.out.println(user.getAttributes().toString()); + assertEquals("User should have 5 attributes", 5, user.getAttributes().size()); + } + + public void testFailedSearchGivesUserNotFoundException() + throws Exception { + authenticator = new PasswordComparisonAuthenticator(getInitialCtxFactory()); + assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); + authenticator.setUserSearch(new MockUserSearch(null)); + authenticator.afterPropertiesSet(); + + try { + authenticator.authenticate("Joe", "password"); + fail("Expected exception on failed user search"); + } catch (UsernameNotFoundException expected) {} + } + + public void testLocalComparisonSucceedsWithShaEncodedPassword() { + // Ben's password is SHA encoded authenticator.authenticate("ben", "benspassword"); } - */ - public void testPasswordEncoderCantBeNull() { - try { - authenticator.setPasswordEncoder(null); - fail("Password encoder can't be null"); - } catch(IllegalArgumentException expected) { - } - } -/* - public void testLdapPasswordCompareFailsWithWrongPassword() { - // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"cn", "sn"}); + public void testLocalPasswordComparisonFailsWithWrongPassword() { try { authenticator.authenticate("Bob", "wrongpassword"); fail("Authentication should fail with wrong password."); - } catch(BadCredentialsException expected) { - } + } catch (BadCredentialsException expected) {} } -*/ + +/* + public void testLdapPasswordCompareFailsWithWrongPassword() { + // Don't retrieve the password + authenticator.setUserAttributes(new String[] {"cn", "sn"}); + try { + authenticator.authenticate("Bob", "wrongpassword"); + fail("Authentication should fail with wrong password."); + } catch(BadCredentialsException expected) { + } + } + */ public void testLocalPasswordComparisonSucceedsWithCorrectPassword() { LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); // check username is retrieved. @@ -76,74 +105,68 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTest authenticator.authenticate("Bob", "bobspassword"); } - public void testLocalComparisonSucceedsWithShaEncodedPassword() { - // Ben's password is SHA encoded - authenticator.authenticate("ben", "benspassword"); - } - - public void testLocalPasswordComparisonFailsWithWrongPassword() { - try { - authenticator.authenticate("Bob", "wrongpassword"); - fail("Authentication should fail with wrong password."); - } catch(BadCredentialsException expected) { - } - } - - public void testAllAttributesAreRetrivedByDefault() { - LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); - //System.out.println(user.getAttributes().toString()); - assertEquals("User should have 5 attributes", 5, user.getAttributes().size()); - - } - - public void testOnlySpecifiedAttributesAreRetrieved() throws Exception { + public void testOnlySpecifiedAttributesAreRetrieved() + throws Exception { authenticator.setUserAttributes(new String[] {"userPassword"}); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); + LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); - assertEquals("Should have retrieved 1 attribute (userPassword)",1, user.getAttributes().size()); + assertEquals("Should have retrieved 1 attribute (userPassword)", 1, user.getAttributes().size()); + // assertEquals("Bob Hamilton", user.getAttributes().get("cn").get()); // assertEquals("bob", user.getAttributes().get("uid").get()); } + /* + public void testLdapCompareSucceedsWithCorrectPassword() { + // Don't retrieve the password + authenticator.setUserAttributes(new String[] {"cn"}); + // Bob has a plaintext password. + authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); + authenticator.authenticate("bob", "bobspassword"); + } + public void testLdapCompareSucceedsWithShaEncodedPassword() { + authenticator = new PasswordComparisonAuthenticator(); + authenticator.setInitialDirContextFactory(dirCtxFactory); + authenticator.setUserDnPatterns("uid={0},ou=people"); + // Don't retrieve the password + authenticator.setUserAttributes(new String[] {"cn"}); + authenticator.authenticate("ben", "benspassword"); + } + */ + public void testPasswordEncoderCantBeNull() { + try { + authenticator.setPasswordEncoder(null); + fail("Password encoder can't be null"); + } catch (IllegalArgumentException expected) {} + } + public void testUseOfDifferentPasswordAttribute() { LdapUserDetailsMapper mapper = new LdapUserDetailsMapper(); mapper.setPasswordAttributeName("uid"); authenticator.setPasswordAttributeName("uid"); authenticator.setUserDetailsMapper(mapper); + LdapUserDetails bob = authenticator.authenticate("bob", "bob"); } -/* - public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { - authenticator.setUserAttributes(new String[] {"cn"}); - authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); - authenticator.setPasswordAttributeName("uid"); - authenticator.authenticate("bob", "bob"); - } - */ +/* + public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { + authenticator.setUserAttributes(new String[] {"cn"}); + authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); + authenticator.setPasswordAttributeName("uid"); + authenticator.authenticate("bob", "bob"); + } + */ public void testWithUserSearch() { authenticator = new PasswordComparisonAuthenticator(getInitialCtxFactory()); - assertTrue("User DN matches shouldn't be available", - authenticator.getUserDns("Bob").isEmpty()); + assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); + LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); userEssence.setDn("uid=Bob,ou=people,dc=acegisecurity,dc=org"); userEssence.setPassword("bobspassword"); authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails())); - authenticator.authenticate("ShouldntBeUsed","bobspassword"); + authenticator.authenticate("ShouldntBeUsed", "bobspassword"); } - - public void testFailedSearchGivesUserNotFoundException() throws Exception { - authenticator = new PasswordComparisonAuthenticator(getInitialCtxFactory()); - assertTrue("User DN matches shouldn't be available", - authenticator.getUserDns("Bob").isEmpty()); - authenticator.setUserSearch(new MockUserSearch(null)); - authenticator.afterPropertiesSet(); - - try { - authenticator.authenticate("Joe","password"); - fail("Expected exception on failed user search"); - } catch (UsernameNotFoundException expected) { - } - } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java b/core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java index a9c85dc3db..1bc4b26bf8 100644 --- a/core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java @@ -1,19 +1,41 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.providers.ldap.populator; +import org.acegisecurity.GrantedAuthority; + +import org.acegisecurity.ldap.AbstractLdapServerTestCase; + +import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; + +import java.util.HashSet; +import java.util.Set; + import javax.naming.directory.BasicAttributes; -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; -import org.acegisecurity.ldap.AbstractLdapServerTestCase; - -import java.util.Set; -import java.util.HashSet; /** + * +DOCUMENT ME! + * * @author Luke Taylor * @version $Id$ */ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTestCase { + //~ Methods ======================================================================================================== public void onSetUp() { getInitialCtxFactory().setManagerDn(MANAGER_USER); @@ -42,24 +64,24 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest // populator.getGrantedAuthorities(user.createUserDetails()); // assertEquals("User should have three roles", 3, authorities.length); // } - public void testDefaultRoleIsAssignedWhenSet() { - DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), "ou=groups"); + DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), + "ou=groups"); populator.setDefaultRole("ROLE_USER"); + LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); user.setDn("cn=notfound"); user.setUsername("notfound"); user.setAttributes(new BasicAttributes()); - GrantedAuthority[] authorities = - populator.getGrantedAuthorities(user.createUserDetails()); + GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails()); assertEquals(1, authorities.length); assertEquals("ROLE_USER", authorities[0].getAuthority()); } public void testGroupSearchReturnsExpectedRoles() { - DefaultLdapAuthoritiesPopulator populator = - new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), "ou=groups"); + DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), + "ou=groups"); populator.setRolePrefix("ROLE_"); populator.setGroupRoleAttribute("ou"); populator.setSearchSubtree(true); @@ -72,10 +94,10 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org"); user.setAttributes(new BasicAttributes()); - GrantedAuthority[] authorities = - populator.getGrantedAuthorities(user.createUserDetails()); + GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails()); assertEquals("Should have 2 roles", 2, authorities.length); + Set roles = new HashSet(); roles.add(authorities[0].toString()); roles.add(authorities[1].toString()); @@ -84,8 +106,8 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest } public void testUseOfUsernameParameterReturnsExpectedRoles() { - DefaultLdapAuthoritiesPopulator populator = - new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), "ou=groups"); + DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), + "ou=groups"); populator.setGroupRoleAttribute("ou"); populator.setConvertToUpperCase(true); populator.setGroupSearchFilter("(ou={1})"); @@ -94,8 +116,7 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest user.setUsername("manager"); user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org"); - GrantedAuthority[] authorities = - populator.getGrantedAuthorities(user.createUserDetails()); + GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails()); assertEquals("Should have 1 role", 1, authorities.length); assertTrue(authorities[0].equals("ROLE_MANAGER")); } diff --git a/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImplTests.java b/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImplTests.java index 1d0f9f978a..7b4dfe7688 100644 --- a/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImplTests.java +++ b/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationManagerImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,16 +28,16 @@ import org.acegisecurity.MockAuthenticationManager; * @version $Id$ */ public class RemoteAuthenticationManagerImplTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RemoteAuthenticationManagerImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testFailedAuthenticationReturnsRemoteAuthenticationException() { RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl(); manager.setAuthenticationManager(new MockAuthenticationManager(false)); @@ -76,8 +76,7 @@ public class RemoteAuthenticationManagerImplTests extends TestCase { RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl(); manager.setAuthenticationManager(new MockAuthenticationManager(true)); - GrantedAuthority[] result = manager.attemptAuthentication("marissa", - "password"); + GrantedAuthority[] result = manager.attemptAuthentication("marissa", "password"); assertTrue(true); } } diff --git a/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProviderTests.java index 29e9aa0913..324ac4745a 100644 --- a/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/rcp/RemoteAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -30,24 +31,22 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class RemoteAuthenticationProviderTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RemoteAuthenticationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testExceptionsGetPassedBackToCaller() { RemoteAuthenticationProvider provider = new RemoteAuthenticationProvider(); - provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager( - false)); + provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager(false)); try { - provider.authenticate(new UsernamePasswordAuthenticationToken( - "marissa", "password")); + provider.authenticate(new UsernamePasswordAuthenticationToken("marissa", "password")); fail("Should have thrown RemoteAuthenticationException"); } catch (RemoteAuthenticationException expected) { assertTrue(true); @@ -56,8 +55,7 @@ public class RemoteAuthenticationProviderTests extends TestCase { public void testGettersSetters() { RemoteAuthenticationProvider provider = new RemoteAuthenticationProvider(); - provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager( - true)); + provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager(true)); assertNotNull(provider.getRemoteAuthenticationManager()); } @@ -72,19 +70,16 @@ public class RemoteAuthenticationProviderTests extends TestCase { assertTrue(true); } - provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager( - true)); + provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager(true)); provider.afterPropertiesSet(); assertTrue(true); } public void testSuccessfulAuthenticationCreatesObject() { RemoteAuthenticationProvider provider = new RemoteAuthenticationProvider(); - provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager( - true)); + provider.setRemoteAuthenticationManager(new MockRemoteAuthenticationManager(true)); - Authentication result = provider.authenticate(new UsernamePasswordAuthenticationToken( - "marissa", "password")); + Authentication result = provider.authenticate(new UsernamePasswordAuthenticationToken("marissa", "password")); assertEquals("marissa", result.getPrincipal()); assertEquals("password", result.getCredentials()); assertEquals("foo", result.getAuthorities()[0].getAuthority()); @@ -95,18 +90,17 @@ public class RemoteAuthenticationProviderTests extends TestCase { assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class)); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockRemoteAuthenticationManager - implements RemoteAuthenticationManager { + private class MockRemoteAuthenticationManager implements RemoteAuthenticationManager { private boolean grantAccess; public MockRemoteAuthenticationManager(boolean grantAccess) { this.grantAccess = grantAccess; } - public GrantedAuthority[] attemptAuthentication(String username, - String password) throws RemoteAuthenticationException { + public GrantedAuthority[] attemptAuthentication(String username, String password) + throws RemoteAuthenticationException { if (grantAccess) { return new GrantedAuthority[] {new GrantedAuthorityImpl("foo")}; } else { diff --git a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java index 0d5acb6166..4cfe96eff2 100644 --- a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; @@ -31,7 +32,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class RememberMeAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RememberMeAuthenticationProviderTests() { super(); @@ -41,24 +42,22 @@ public class RememberMeAuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RememberMeAuthenticationProviderTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsAnInvalidKey() throws Exception { RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); aap.setKey("qwerty"); - RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); try { Authentication result = aap.authenticate(token); @@ -91,8 +90,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase { RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); aap.setKey("qwerty"); - TestingAuthenticationToken token = new TestingAuthenticationToken("user", - "password", + TestingAuthenticationToken token = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); assertFalse(aap.supports(TestingAuthenticationToken.class)); @@ -104,10 +102,8 @@ public class RememberMeAuthenticationProviderTests extends TestCase { RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); aap.setKey("qwerty"); - RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); Authentication result = aap.authenticate(token); diff --git a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationTokenTests.java index 84afe57503..420f5f5d41 100644 --- a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import java.util.List; @@ -32,7 +33,7 @@ import java.util.Vector; * @version $Id$ */ public class RememberMeAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RememberMeAuthenticationTokenTests() { super(); @@ -42,21 +43,20 @@ public class RememberMeAuthenticationTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RememberMeAuthenticationTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConstructorRejectsNulls() { try { new RememberMeAuthenticationToken(null, "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -64,8 +64,7 @@ public class RememberMeAuthenticationTokenTests extends TestCase { try { new RememberMeAuthenticationToken("key", null, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -79,16 +78,14 @@ public class RememberMeAuthenticationTokenTests extends TestCase { } try { - new RememberMeAuthenticationToken("key", "Test", - new GrantedAuthority[] {null}); + new RememberMeAuthenticationToken("key", "Test", new GrantedAuthority[] {null}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - new RememberMeAuthenticationToken("key", "Test", - new GrantedAuthority[] {}); + new RememberMeAuthenticationToken("key", "Test", new GrantedAuthority[] {}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -99,24 +96,18 @@ public class RememberMeAuthenticationTokenTests extends TestCase { List proxyList1 = new Vector(); proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check"); - RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals(token1, token2); } public void testGetters() { - RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("key".hashCode(), token.getKeyHash()); assertEquals("Test", token.getPrincipal()); @@ -130,7 +121,7 @@ public class RememberMeAuthenticationTokenTests extends TestCase { Class clazz = RememberMeAuthenticationToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -138,52 +129,38 @@ public class RememberMeAuthenticationTokenTests extends TestCase { } public void testNotEqualsDueToAbstractParentEqualsCheck() { - RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key", - "DIFFERENT_PRINCIPAL", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key", "DIFFERENT_PRINCIPAL", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testNotEqualsDueToDifferentAuthenticationClass() { - RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testNotEqualsDueToKey() { - RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("DIFFERENT_KEY", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("DIFFERENT_KEY", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(token1.equals(token2)); } public void testSetAuthenticatedIgnored() { - RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key", - "Test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key", "Test", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(token.isAuthenticated()); token.setAuthenticated(false); assertTrue(!token.isAuthenticated()); diff --git a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java index 26c9473ed1..4e025c660c 100644 --- a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ package org.acegisecurity.providers.x509; -import java.security.cert.X509Certificate; - import junit.framework.TestCase; import org.acegisecurity.Authentication; @@ -24,10 +22,14 @@ import org.acegisecurity.AuthenticationException; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; +import java.security.cert.X509Certificate; + /** * Tests {@link X509AuthenticationProvider} @@ -36,7 +38,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class X509AuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public X509AuthenticationProviderTests() { super(); @@ -46,7 +48,7 @@ public class X509AuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public final void setUp() throws Exception { super.setUp(); @@ -54,8 +56,7 @@ public class X509AuthenticationProviderTests extends TestCase { public void testAuthenticationIsNullWithUnsupportedToken() { X509AuthenticationProvider provider = new X509AuthenticationProvider(); - Authentication request = new UsernamePasswordAuthenticationToken("dummy", - "dummy"); + Authentication request = new UsernamePasswordAuthenticationToken("dummy", "dummy"); Authentication result = provider.authenticate(request); assertNull(result); } @@ -108,10 +109,9 @@ public class X509AuthenticationProviderTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - public static class MockAuthoritiesPopulator - implements X509AuthoritiesPopulator { + public static class MockAuthoritiesPopulator implements X509AuthoritiesPopulator { private boolean rejectCertificate; public MockAuthoritiesPopulator(boolean rejectCertificate) { @@ -125,8 +125,7 @@ public class X509AuthenticationProviderTests extends TestCase { } return new User("user", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl( - "ROLE_B")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")}); } } } diff --git a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationTokenTests.java index 3ced755330..84b1df057b 100644 --- a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class X509AuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public X509AuthenticationTokenTests() {} @@ -33,7 +33,7 @@ public class X509AuthenticationTokenTests extends TestCase { super(s); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void setUp() throws Exception { super.setUp(); diff --git a/core/src/test/java/org/acegisecurity/providers/x509/X509TestUtils.java b/core/src/test/java/org/acegisecurity/providers/x509/X509TestUtils.java index 4a4d8cf6fb..ebed899809 100644 --- a/core/src/test/java/org/acegisecurity/providers/x509/X509TestUtils.java +++ b/core/src/test/java/org/acegisecurity/providers/x509/X509TestUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ package org.acegisecurity.providers.x509; -import java.security.cert.X509Certificate; -import java.security.cert.CertificateFactory; import java.io.ByteArrayInputStream; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + + /** * Certificate creation utility for use in X.509 tests. * @@ -26,80 +28,65 @@ import java.io.ByteArrayInputStream; * @version $Id$ */ public class X509TestUtils { + //~ Methods ======================================================================================================== - public static X509AuthenticationToken createToken() throws Exception { + /** + * Builds an X.509 certificate. In human-readable form it is:
Certificate:  Data:     Version: 3 (0x2)
+     *      Serial Number: 1 (0x1)     Signature Algorithm: sha1WithRSAEncryption
+     *      Issuer: CN=Monkey Machine CA, C=UK, ST=Scotland, L=Glasgow,
+     *          O=monkeymachine.co.uk/emailAddress=ca@monkeymachine.co.uk     Validity
+     *          Not Before: Mar  6 23:28:22 2005 GMT         Not After : Mar  6 23:28:22 2006 GMT
+     *      Subject: C=UK, ST=Scotland, L=Glasgow, O=Monkey Machine Ltd,
+     *          OU=Open Source Development Lab., CN=Luke Taylor/emailAddress=luke@monkeymachine
+     *      Subject Public Key Info:         Public Key Algorithm: rsaEncryption         RSA Public Key: (512 bit)
+     *              [omitted]     X509v3 extensions:         X509v3 Basic Constraints:         CA:FALSE
+     *          Netscape Cert Type:         SSL Client         X509v3 Key Usage:
+     *          Digital Signature, Non Repudiation, Key Encipherment         X509v3 Subject Key Identifier:
+     *          6E:E6:5B:57:33:CF:0E:2F:15:C2:F4:DF:EC:14:BE:FB:CF:54:56:3C         X509v3 Authority Key Identifier:
+     *          keyid:AB:78:EC:AF:10:1B:8A:9B:1F:C7:B1:25:8F:16:28:F2:17:9A:AD:36
+     *          DirName:/CN=Monkey Machine CA/C=UK/ST=Scotland/L=Glasgow/O=monkeymachine.co.uk/emailAddress=ca@monkeymachine.co.uk
+     *          serial:00         Netscape CA Revocation Url:         https://monkeymachine.co.uk/ca-crl.pem
+     *   Signature Algorithm: sha1WithRSAEncryption            [signature omitted]
+ * + * @return DOCUMENT ME! + * + * @throws Exception DOCUMENT ME! + */ + public static X509Certificate buildTestCertificate() + throws Exception { + String cert = "-----BEGIN CERTIFICATE-----\n" + + "MIIEQTCCAymgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkzEaMBgGA1UEAxMRTW9u\n" + + "a2V5IE1hY2hpbmUgQ0ExCzAJBgNVBAYTAlVLMREwDwYDVQQIEwhTY290bGFuZDEQ\n" + + "MA4GA1UEBxMHR2xhc2dvdzEcMBoGA1UEChMTbW9ua2V5bWFjaGluZS5jby51azEl\n" + + "MCMGCSqGSIb3DQEJARYWY2FAbW9ua2V5bWFjaGluZS5jby51azAeFw0wNTAzMDYy\n" + + "MzI4MjJaFw0wNjAzMDYyMzI4MjJaMIGvMQswCQYDVQQGEwJVSzERMA8GA1UECBMI\n" + + "U2NvdGxhbmQxEDAOBgNVBAcTB0dsYXNnb3cxGzAZBgNVBAoTEk1vbmtleSBNYWNo\n" + + "aW5lIEx0ZDElMCMGA1UECxMcT3BlbiBTb3VyY2UgRGV2ZWxvcG1lbnQgTGFiLjEU\n" + + "MBIGA1UEAxMLTHVrZSBUYXlsb3IxITAfBgkqhkiG9w0BCQEWEmx1a2VAbW9ua2V5\n" + + "bWFjaGluZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDItxZr07mm65ttYH7RMaVo\n" + + "VeMCq4ptfn+GFFEk4+54OkDuh1CHlk87gEc1jx3ZpQPJRTJx31z3YkiAcP+RDzxr\n" + + "AgMBAAGjggFIMIIBRDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIHgDALBgNV\n" + + "HQ8EBAMCBeAwHQYDVR0OBBYEFG7mW1czzw4vFcL03+wUvvvPVFY8MIHABgNVHSME\n" + + "gbgwgbWAFKt47K8QG4qbH8exJY8WKPIXmq02oYGZpIGWMIGTMRowGAYDVQQDExFN\n" + + "b25rZXkgTWFjaGluZSBDQTELMAkGA1UEBhMCVUsxETAPBgNVBAgTCFNjb3RsYW5k\n" + + "MRAwDgYDVQQHEwdHbGFzZ293MRwwGgYDVQQKExNtb25rZXltYWNoaW5lLmNvLnVr\n" + + "MSUwIwYJKoZIhvcNAQkBFhZjYUBtb25rZXltYWNoaW5lLmNvLnVrggEAMDUGCWCG\n" + + "SAGG+EIBBAQoFiZodHRwczovL21vbmtleW1hY2hpbmUuY28udWsvY2EtY3JsLnBl\n" + + "bTANBgkqhkiG9w0BAQUFAAOCAQEAZ961bEgm2rOq6QajRLeoljwXDnt0S9BGEWL4\n" + + "PMU2FXDog9aaPwfmZ5fwKaSebwH4HckTp11xwe/D9uBZJQ74Uf80UL9z2eo0GaSR\n" + + "nRB3QPZfRvop0I4oPvwViKt3puLsi9XSSJ1w9yswnIf89iONT7ZyssPg48Bojo8q\n" + + "lcKwXuDRBWciODK/xWhvQbaegGJ1BtXcEHtvNjrUJLwSMDSr+U5oUYdMohG0h1iJ\n" + + "R+JQc49I33o2cTc77wfEWLtVdXAyYY4GSJR6VfgvV40x85ItaNS3HHfT/aXU1x4m\n" + + "W9YQkWlA6t0blGlC+ghTOY1JbgWnEfXMmVgg9a9cWaYQ+NQwqA==\n" + "-----END CERTIFICATE-----"; + + ByteArrayInputStream in = new ByteArrayInputStream(cert.getBytes()); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + return (X509Certificate) cf.generateCertificate(in); + } + + public static X509AuthenticationToken createToken() + throws Exception { return new X509AuthenticationToken(buildTestCertificate()); } - /** - * Builds an X.509 certificate. In human-readable form it is: - *
-      * Certificate:
-      *   Data:
-      *      Version: 3 (0x2)
-      *      Serial Number: 1 (0x1)
-      *      Signature Algorithm: sha1WithRSAEncryption
-      *      Issuer: CN=Monkey Machine CA, C=UK, ST=Scotland, L=Glasgow,
-      *          O=monkeymachine.co.uk/emailAddress=ca@monkeymachine.co.uk
-      *      Validity
-      *          Not Before: Mar  6 23:28:22 2005 GMT
-      *          Not After : Mar  6 23:28:22 2006 GMT
-      *      Subject: C=UK, ST=Scotland, L=Glasgow, O=Monkey Machine Ltd,
-      *          OU=Open Source Development Lab., CN=Luke Taylor/emailAddress=luke@monkeymachine
-      *      Subject Public Key Info:
-      *          Public Key Algorithm: rsaEncryption
-      *          RSA Public Key: (512 bit)
-      *              [omitted]
-      *      X509v3 extensions:
-      *          X509v3 Basic Constraints:
-      *          CA:FALSE
-      *          Netscape Cert Type:
-      *          SSL Client
-      *          X509v3 Key Usage:
-      *          Digital Signature, Non Repudiation, Key Encipherment
-      *          X509v3 Subject Key Identifier:
-      *          6E:E6:5B:57:33:CF:0E:2F:15:C2:F4:DF:EC:14:BE:FB:CF:54:56:3C
-      *          X509v3 Authority Key Identifier:
-      *          keyid:AB:78:EC:AF:10:1B:8A:9B:1F:C7:B1:25:8F:16:28:F2:17:9A:AD:36
-      *          DirName:/CN=Monkey Machine CA/C=UK/ST=Scotland/L=Glasgow/O=monkeymachine.co.uk/emailAddress=ca@monkeymachine.co.uk
-      *          serial:00
-      *          Netscape CA Revocation Url:
-      *          https://monkeymachine.co.uk/ca-crl.pem
-      *   Signature Algorithm: sha1WithRSAEncryption
-      *             [signature omitted]
-      * 
- */ - public static X509Certificate buildTestCertificate() throws Exception - { - String cert = "-----BEGIN CERTIFICATE-----\n" + - "MIIEQTCCAymgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkzEaMBgGA1UEAxMRTW9u\n" + - "a2V5IE1hY2hpbmUgQ0ExCzAJBgNVBAYTAlVLMREwDwYDVQQIEwhTY290bGFuZDEQ\n" + - "MA4GA1UEBxMHR2xhc2dvdzEcMBoGA1UEChMTbW9ua2V5bWFjaGluZS5jby51azEl\n" + - "MCMGCSqGSIb3DQEJARYWY2FAbW9ua2V5bWFjaGluZS5jby51azAeFw0wNTAzMDYy\n" + - "MzI4MjJaFw0wNjAzMDYyMzI4MjJaMIGvMQswCQYDVQQGEwJVSzERMA8GA1UECBMI\n" + - "U2NvdGxhbmQxEDAOBgNVBAcTB0dsYXNnb3cxGzAZBgNVBAoTEk1vbmtleSBNYWNo\n" + - "aW5lIEx0ZDElMCMGA1UECxMcT3BlbiBTb3VyY2UgRGV2ZWxvcG1lbnQgTGFiLjEU\n" + - "MBIGA1UEAxMLTHVrZSBUYXlsb3IxITAfBgkqhkiG9w0BCQEWEmx1a2VAbW9ua2V5\n" + - "bWFjaGluZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDItxZr07mm65ttYH7RMaVo\n" + - "VeMCq4ptfn+GFFEk4+54OkDuh1CHlk87gEc1jx3ZpQPJRTJx31z3YkiAcP+RDzxr\n" + - "AgMBAAGjggFIMIIBRDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIHgDALBgNV\n" + - "HQ8EBAMCBeAwHQYDVR0OBBYEFG7mW1czzw4vFcL03+wUvvvPVFY8MIHABgNVHSME\n" + - "gbgwgbWAFKt47K8QG4qbH8exJY8WKPIXmq02oYGZpIGWMIGTMRowGAYDVQQDExFN\n" + - "b25rZXkgTWFjaGluZSBDQTELMAkGA1UEBhMCVUsxETAPBgNVBAgTCFNjb3RsYW5k\n" + - "MRAwDgYDVQQHEwdHbGFzZ293MRwwGgYDVQQKExNtb25rZXltYWNoaW5lLmNvLnVr\n" + - "MSUwIwYJKoZIhvcNAQkBFhZjYUBtb25rZXltYWNoaW5lLmNvLnVrggEAMDUGCWCG\n" + - "SAGG+EIBBAQoFiZodHRwczovL21vbmtleW1hY2hpbmUuY28udWsvY2EtY3JsLnBl\n" + - "bTANBgkqhkiG9w0BAQUFAAOCAQEAZ961bEgm2rOq6QajRLeoljwXDnt0S9BGEWL4\n" + - "PMU2FXDog9aaPwfmZ5fwKaSebwH4HckTp11xwe/D9uBZJQ74Uf80UL9z2eo0GaSR\n" + - "nRB3QPZfRvop0I4oPvwViKt3puLsi9XSSJ1w9yswnIf89iONT7ZyssPg48Bojo8q\n" + - "lcKwXuDRBWciODK/xWhvQbaegGJ1BtXcEHtvNjrUJLwSMDSr+U5oUYdMohG0h1iJ\n" + - "R+JQc49I33o2cTc77wfEWLtVdXAyYY4GSJR6VfgvV40x85ItaNS3HHfT/aXU1x4m\n" + - "W9YQkWlA6t0blGlC+ghTOY1JbgWnEfXMmVgg9a9cWaYQ+NQwqA==\n" + - "-----END CERTIFICATE-----"; - - ByteArrayInputStream in = new ByteArrayInputStream(cert.getBytes()); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - return (X509Certificate)cf.generateCertificate(in); - - } - } diff --git a/core/src/test/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCacheTests.java b/core/src/test/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCacheTests.java index 6ad2fb0987..db1867a4ba 100644 --- a/core/src/test/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCacheTests.java +++ b/core/src/test/java/org/acegisecurity/providers/x509/cache/EhCacheBasedX509UserCacheTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,17 @@ package org.acegisecurity.providers.x509.cache; import junit.framework.TestCase; +import net.sf.ehcache.Cache; + import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.MockApplicationContext; + import org.acegisecurity.providers.x509.X509TestUtils; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; -import net.sf.ehcache.Cache; - import org.springframework.context.ApplicationContext; @@ -36,7 +38,7 @@ import org.springframework.context.ApplicationContext; * @version $Id$ */ public class EhCacheBasedX509UserCacheTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public EhCacheBasedX509UserCacheTests() { super(); @@ -46,7 +48,18 @@ public class EhCacheBasedX509UserCacheTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private Cache getCache() { + ApplicationContext ctx = MockApplicationContext.getContext(); + + return (Cache) ctx.getBean("eHCacheBackend"); + } + + private UserDetails getUser() { + return new User("marissa", "password", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + } public final void setUp() throws Exception { super.setUp(); @@ -59,9 +72,7 @@ public class EhCacheBasedX509UserCacheTests extends TestCase { // Check it gets stored in the cache cache.putUserInCache(X509TestUtils.buildTestCertificate(), getUser()); - assertEquals(getUser().getPassword(), - cache.getUserFromCache(X509TestUtils.buildTestCertificate()) - .getPassword()); + assertEquals(getUser().getPassword(), cache.getUserFromCache(X509TestUtils.buildTestCertificate()).getPassword()); // Check it gets removed from the cache cache.removeUserFromCache(X509TestUtils.buildTestCertificate()); @@ -70,16 +81,4 @@ public class EhCacheBasedX509UserCacheTests extends TestCase { // Check it doesn't return values for null user assertNull(cache.getUserFromCache(null)); } - - private Cache getCache() { - ApplicationContext ctx = MockApplicationContext.getContext(); - - return (Cache) ctx.getBean("eHCacheBackend"); - } - - private UserDetails getUser() { - return new User("marissa", "password", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - } } diff --git a/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java b/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java index ceaf48a031..68493ef9da 100644 --- a/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java +++ b/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,20 +15,23 @@ package org.acegisecurity.providers.x509.populator; -import java.security.cert.X509Certificate; - import junit.framework.TestCase; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.x509.X509TestUtils; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.dao.DataAccessException; +import java.security.cert.X509Certificate; + /** * Tests for {@link DaoX509AuthoritiesPopulator} @@ -37,7 +40,7 @@ import org.springframework.dao.DataAccessException; * @version $Id$ */ public class DaoX509AuthoritiesPopulatorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public DaoX509AuthoritiesPopulatorTests() { super(); @@ -47,7 +50,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public final void setUp() throws Exception { super.setUp(); @@ -111,8 +114,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase { try { populator.getUserDetails(cert); - fail( - "Should have thrown IllegalArgumentException for regexp without group"); + fail("Should have thrown IllegalArgumentException for regexp without group"); } catch (IllegalArgumentException e) { // ignored } @@ -129,19 +131,16 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockAuthenticationDaoMatchesNameOrEmail - implements UserDetailsService { + private class MockAuthenticationDaoMatchesNameOrEmail implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - if ("Luke Taylor".equals(username) - || "luke@monkeymachine".equals(username)) { + if ("Luke Taylor".equals(username) || "luke@monkeymachine".equals(username)) { return new User("luke", "monkey", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } } diff --git a/core/src/test/java/org/acegisecurity/runas/NullRunAsManagerTests.java b/core/src/test/java/org/acegisecurity/runas/NullRunAsManagerTests.java index ddab1bf308..0e589ea9f7 100644 --- a/core/src/test/java/org/acegisecurity/runas/NullRunAsManagerTests.java +++ b/core/src/test/java/org/acegisecurity/runas/NullRunAsManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import org.acegisecurity.SecurityConfig; * @version $Id$ */ public class NullRunAsManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NullRunAsManagerTests() { super(); @@ -37,16 +37,16 @@ public class NullRunAsManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(NullRunAsManagerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAlwaysReturnsNull() { NullRunAsManager runAs = new NullRunAsManager(); assertNull(runAs.buildRunAs(null, null, null)); diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java index fa75ca0d44..98eb8183ef 100644 --- a/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -29,7 +30,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * Tests {@link RunAsImplAuthenticationProvider}. */ public class RunAsImplAuthenticationProviderTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RunAsImplAuthenticationProviderTests() { super(); @@ -39,7 +40,7 @@ public class RunAsImplAuthenticationProviderTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class); @@ -50,10 +51,9 @@ public class RunAsImplAuthenticationProviderTests extends TestCase { } public void testAuthenticationFailDueToWrongKey() { - RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + UsernamePasswordAuthenticationToken.class); RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); provider.setKey("hello_world"); @@ -66,10 +66,9 @@ public class RunAsImplAuthenticationProviderTests extends TestCase { } public void testAuthenticationSuccess() { - RunAsUserToken token = new RunAsUserToken("my_password", "Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsUserToken token = new RunAsUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + UsernamePasswordAuthenticationToken.class); RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); provider.setKey("my_password"); diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java index 4c332cdd19..1cb1889ea3 100644 --- a/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java +++ b/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.RunAsManager; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -33,7 +34,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class RunAsManagerImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RunAsManagerImplTests() { super(); @@ -43,16 +44,16 @@ public class RunAsManagerImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RunAsManagerImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAlwaysSupportsClass() { RunAsManagerImpl runAs = new RunAsManagerImpl(); assertTrue(runAs.supports(String.class)); @@ -63,15 +64,13 @@ public class RunAsManagerImplTests extends TestCase { ConfigAttributeDefinition def = new ConfigAttributeDefinition(); def.addConfigAttribute(new SecurityConfig("SOMETHING_WE_IGNORE")); - UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); RunAsManagerImpl runAs = new RunAsManagerImpl(); runAs.setKey("my_password"); - Authentication resultingToken = runAs.buildRunAs(inputToken, - new Object(), def); + Authentication resultingToken = runAs.buildRunAs(inputToken, new Object(), def); assertEquals(null, resultingToken); } @@ -79,26 +78,22 @@ public class RunAsManagerImplTests extends TestCase { ConfigAttributeDefinition def = new ConfigAttributeDefinition(); def.addConfigAttribute(new SecurityConfig("RUN_AS_SOMETHING")); - UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ONE"), new GrantedAuthorityImpl("TWO")}); RunAsManagerImpl runAs = new RunAsManagerImpl(); runAs.setKey("my_password"); runAs.setRolePrefix("FOOBAR_"); - Authentication resultingToken = runAs.buildRunAs(inputToken, - new Object(), def); + Authentication resultingToken = runAs.buildRunAs(inputToken, new Object(), def); if (!(resultingToken instanceof RunAsUserToken)) { fail("Should have returned a RunAsUserToken"); } assertEquals(inputToken.getPrincipal(), resultingToken.getPrincipal()); - assertEquals(inputToken.getCredentials(), - resultingToken.getCredentials()); - assertEquals("FOOBAR_RUN_AS_SOMETHING", - resultingToken.getAuthorities()[0].getAuthority()); + assertEquals(inputToken.getCredentials(), resultingToken.getCredentials()); + assertEquals("FOOBAR_RUN_AS_SOMETHING", resultingToken.getAuthorities()[0].getAuthority()); assertEquals("ONE", resultingToken.getAuthorities()[1].getAuthority()); assertEquals("TWO", resultingToken.getAuthorities()[2].getAuthority()); @@ -111,29 +106,23 @@ public class RunAsManagerImplTests extends TestCase { ConfigAttributeDefinition def = new ConfigAttributeDefinition(); def.addConfigAttribute(new SecurityConfig("RUN_AS_SOMETHING")); - UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", - "Password", + UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", "Password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); RunAsManagerImpl runAs = new RunAsManagerImpl(); runAs.setKey("my_password"); - Authentication resultingToken = runAs.buildRunAs(inputToken, - new Object(), def); + Authentication resultingToken = runAs.buildRunAs(inputToken, new Object(), def); if (!(resultingToken instanceof RunAsUserToken)) { fail("Should have returned a RunAsUserToken"); } assertEquals(inputToken.getPrincipal(), resultingToken.getPrincipal()); - assertEquals(inputToken.getCredentials(), - resultingToken.getCredentials()); - assertEquals("ROLE_RUN_AS_SOMETHING", - resultingToken.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_ONE", - resultingToken.getAuthorities()[1].getAuthority()); - assertEquals("ROLE_TWO", - resultingToken.getAuthorities()[2].getAuthority()); + assertEquals(inputToken.getCredentials(), resultingToken.getCredentials()); + assertEquals("ROLE_RUN_AS_SOMETHING", resultingToken.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_ONE", resultingToken.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TWO", resultingToken.getAuthorities()[2].getAuthority()); RunAsUserToken resultCast = (RunAsUserToken) resultingToken; assertEquals("my_password".hashCode(), resultCast.getKeyHash()); diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java index a1f06528c8..dd57dd0f1e 100644 --- a/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java +++ b/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -29,7 +30,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; * @version $Id$ */ public class RunAsUserTokenTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RunAsUserTokenTests() { super(); @@ -39,44 +40,40 @@ public class RunAsUserTokenTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RunAsUserTokenTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAuthenticationSetting() { - RunAsUserToken token = new RunAsUserToken("my_password", "Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsUserToken token = new RunAsUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + UsernamePasswordAuthenticationToken.class); assertTrue(token.isAuthenticated()); token.setAuthenticated(false); assertTrue(!token.isAuthenticated()); } public void testGetters() { - RunAsUserToken token = new RunAsUserToken("my_password", "Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsUserToken token = new RunAsUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + UsernamePasswordAuthenticationToken.class); assertEquals("Test", token.getPrincipal()); assertEquals("Password", token.getCredentials()); assertEquals("my_password".hashCode(), token.getKeyHash()); - assertEquals(UsernamePasswordAuthenticationToken.class, - token.getOriginalAuthentication()); + assertEquals(UsernamePasswordAuthenticationToken.class, token.getOriginalAuthentication()); } - public void testNoArgConstructorDoesntExist() { Class clazz = RunAsUserToken.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -84,10 +81,9 @@ public class RunAsUserTokenTests extends TestCase { } public void testToString() { - RunAsUserToken token = new RunAsUserToken("my_password", "Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsUserToken token = new RunAsUserToken("my_password", "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}, + UsernamePasswordAuthenticationToken.class); assertTrue(token.toString().lastIndexOf("Original Class:") != -1); } } diff --git a/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java b/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java index 0c9433364a..b7ff1dcf42 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,12 @@ import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.intercept.web.FilterInvocation; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + import java.io.IOException; import java.util.Iterator; @@ -31,9 +35,6 @@ import java.util.Vector; import javax.servlet.ServletException; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - /** * Tests {@link ChannelDecisionManagerImpl}. @@ -42,16 +43,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class ChannelDecisionManagerImplTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ChannelDecisionManagerImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCannotSetEmptyChannelProcessorsList() throws Exception { ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl(); @@ -60,8 +61,7 @@ public class ChannelDecisionManagerImplTests extends TestCase { cdm.setChannelProcessors(new Vector()); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A list of ChannelProcessors is required", - expected.getMessage()); + assertEquals("A list of ChannelProcessors is required", expected.getMessage()); } } @@ -87,8 +87,7 @@ public class ChannelDecisionManagerImplTests extends TestCase { cdm.setChannelProcessors(null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A list of ChannelProcessors is required", - expected.getMessage()); + assertEquals("A list of ChannelProcessors is required", expected.getMessage()); } } @@ -131,8 +130,7 @@ public class ChannelDecisionManagerImplTests extends TestCase { FilterInvocation fi = new FilterInvocation(request, response, chain); ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); - cad.addConfigAttribute(new SecurityConfig( - "SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT")); + cad.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT")); cdm.decide(fi, cad); assertFalse(fi.getResponse().isCommitted()); @@ -175,12 +173,11 @@ public class ChannelDecisionManagerImplTests extends TestCase { cdm.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A list of ChannelProcessors is required", - expected.getMessage()); + assertEquals("A list of ChannelProcessors is required", expected.getMessage()); } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockChannelProcessor implements ChannelProcessor { private String configAttribute; @@ -195,8 +192,7 @@ public class ChannelDecisionManagerImplTests extends TestCase { super(); } - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) throws IOException, ServletException { Iterator iter = config.getConfigAttributes(); diff --git a/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java index fa111b6d64..41bc62ad91 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,14 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttributeDefinition; - - import org.acegisecurity.SecurityConfig; import org.acegisecurity.intercept.web.FilterInvocation; import org.acegisecurity.intercept.web.FilterInvocationDefinitionSource; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + import java.io.IOException; import java.util.Iterator; @@ -37,9 +38,6 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - /** * Tests {@link ChannelProcessingFilter}. @@ -48,16 +46,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class ChannelProcessingFilterTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ChannelProcessingFilterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingChannelDecisionManager() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); @@ -65,44 +63,38 @@ public class ChannelProcessingFilterTests extends TestCase { ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("MOCK")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); try { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("channelDecisionManager must be specified", - expected.getMessage()); + assertEquals("channelDecisionManager must be specified", expected.getMessage()); } } public void testDetectsMissingFilterInvocationDefinitionSource() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "MOCK")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "MOCK")); try { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("filterInvocationDefinitionSource must be specified", - expected.getMessage()); + assertEquals("filterInvocationDefinitionSource must be specified", expected.getMessage()); } } public void testDetectsSupportedConfigAttribute() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "SUPPORTS_MOCK_ONLY")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SUPPORTS_MOCK_ONLY")); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("SUPPORTS_MOCK_ONLY")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); @@ -113,15 +105,13 @@ public class ChannelProcessingFilterTests extends TestCase { public void testDetectsUnsupportedConfigAttribute() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "SUPPORTS_MOCK_ONLY")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SUPPORTS_MOCK_ONLY")); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("SUPPORTS_MOCK_ONLY")); attr.addConfigAttribute(new SecurityConfig("INVALID_ATTRIBUTE")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); @@ -136,14 +126,12 @@ public class ChannelProcessingFilterTests extends TestCase { public void testDoFilterWhenManagerDoesCommitResponse() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(true, - "SOME_ATTRIBUTE")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE")); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); @@ -161,14 +149,12 @@ public class ChannelProcessingFilterTests extends TestCase { public void testDoFilterWhenManagerDoesNotCommitResponse() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "SOME_ATTRIBUTE")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE")); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); @@ -186,14 +172,12 @@ public class ChannelProcessingFilterTests extends TestCase { public void testDoFilterWhenNullConfigAttributeReturned() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "NOT_USED")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED")); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("NOT_USED")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, true); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, true); filter.setFilterInvocationDefinitionSource(fids); @@ -213,8 +197,7 @@ public class ChannelProcessingFilterTests extends TestCase { ChannelProcessingFilter filter = new ChannelProcessingFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { assertEquals("HttpServletRequest required", expected.getMessage()); @@ -226,8 +209,7 @@ public class ChannelProcessingFilterTests extends TestCase { ChannelProcessingFilter filter = new ChannelProcessingFilter(); try { - filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain()); + filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { assertEquals("HttpServletResponse required", expected.getMessage()); @@ -236,15 +218,13 @@ public class ChannelProcessingFilterTests extends TestCase { public void testGetterSetters() throws Exception { ChannelProcessingFilter filter = new ChannelProcessingFilter(); - filter.setChannelDecisionManager(new MockChannelDecisionManager(false, - "MOCK")); + filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "MOCK")); assertTrue(filter.getChannelDecisionManager() != null); ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); attr.addConfigAttribute(new SecurityConfig("MOCK")); - MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", - attr, false); + MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", attr, false); filter.setFilterInvocationDefinitionSource(fids); assertTrue(filter.getFilterInvocationDefinitionSource() != null); @@ -254,14 +234,13 @@ public class ChannelProcessingFilterTests extends TestCase { filter.destroy(); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockChannelDecisionManager implements ChannelDecisionManager { private String supportAttribute; private boolean commitAResponse; - public MockChannelDecisionManager(boolean commitAResponse, - String supportAttribute) { + public MockChannelDecisionManager(boolean commitAResponse, String supportAttribute) { this.commitAResponse = commitAResponse; this.supportAttribute = supportAttribute; } @@ -270,8 +249,7 @@ public class ChannelProcessingFilterTests extends TestCase { super(); } - public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) + public void decide(FilterInvocation invocation, ConfigAttributeDefinition config) throws IOException, ServletException { if (commitAResponse) { invocation.getHttpResponse().sendRedirect("/redirected"); @@ -308,14 +286,13 @@ public class ChannelProcessingFilterTests extends TestCase { } } - private class MockFilterInvocationDefinitionMap - implements FilterInvocationDefinitionSource { + private class MockFilterInvocationDefinitionMap implements FilterInvocationDefinitionSource { private ConfigAttributeDefinition toReturn; private String servletPath; private boolean provideIterator; - public MockFilterInvocationDefinitionMap(String servletPath, - ConfigAttributeDefinition toReturn, boolean provideIterator) { + public MockFilterInvocationDefinitionMap(String servletPath, ConfigAttributeDefinition toReturn, + boolean provideIterator) { this.servletPath = servletPath; this.toReturn = toReturn; this.provideIterator = provideIterator; diff --git a/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java index 8ea645ca98..06720ff726 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,10 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; - - import org.acegisecurity.SecurityConfig; import org.acegisecurity.intercept.web.FilterInvocation; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -35,16 +34,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class InsecureChannelProcessorTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(InsecureChannelProcessorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDecideDetectsAcceptableChannel() throws Exception { ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); @@ -151,8 +150,7 @@ public class InsecureChannelProcessorTests extends TestCase { public void testSupports() { InsecureChannelProcessor processor = new InsecureChannelProcessor(); - assertTrue(processor.supports( - new SecurityConfig("REQUIRES_INSECURE_CHANNEL"))); + assertTrue(processor.supports(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"))); assertFalse(processor.supports(null)); assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); } diff --git a/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpEntryPointTests.java b/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpEntryPointTests.java index f03c9dc391..1b4a386d1e 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,16 @@ package org.acegisecurity.securechannel; import junit.framework.TestCase; - - import org.acegisecurity.MockPortResolver; import org.acegisecurity.util.PortMapperImpl; -import java.util.HashMap; -import java.util.Map; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import java.util.HashMap; +import java.util.Map; + /** * Tests {@link RetryWithHttpEntryPoint}. @@ -37,16 +35,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class RetryWithHttpEntryPointTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RetryWithHttpEntryPointTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingPortMapper() throws Exception { RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint(); ep.setPortMapper(null); @@ -97,8 +95,7 @@ public class RetryWithHttpEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("http://www.example.com/bigWebApp/hello/pathInfo.html?open=true", - response.getRedirectedUrl()); + assertEquals("http://www.example.com/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl()); } public void testNormalOperationWithNullPathInfoAndNullQueryString() @@ -119,8 +116,7 @@ public class RetryWithHttpEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("http://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); } public void testOperationWhenTargetPortIsUnknown() @@ -168,7 +164,6 @@ public class RetryWithHttpEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("http://www.example.com:8888/bigWebApp/hello/pathInfo.html?open=true", - response.getRedirectedUrl()); + assertEquals("http://www.example.com:8888/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPointTests.java b/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPointTests.java index 18e3a20330..0b45e448e4 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/RetryWithHttpsEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,16 @@ package org.acegisecurity.securechannel; import junit.framework.TestCase; - - import org.acegisecurity.MockPortResolver; import org.acegisecurity.util.PortMapperImpl; -import java.util.HashMap; -import java.util.Map; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import java.util.HashMap; +import java.util.Map; + /** * Tests {@link RetryWithHttpsEntryPoint}. @@ -37,16 +35,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class RetryWithHttpsEntryPointTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(RetryWithHttpsEntryPointTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingPortMapper() throws Exception { RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint(); ep.setPortMapper(null); @@ -97,8 +95,7 @@ public class RetryWithHttpsEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com/bigWebApp/hello/pathInfo.html?open=true", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl()); } public void testNormalOperationWithNullPathInfoAndNullQueryString() @@ -119,8 +116,7 @@ public class RetryWithHttpsEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); } public void testOperationWhenTargetPortIsUnknown() @@ -168,7 +164,6 @@ public class RetryWithHttpsEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response); - assertEquals("https://www.example.com:9999/bigWebApp/hello/pathInfo.html?open=true", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:9999/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java index ef4f0fe75e..8edd45f56b 100644 --- a/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java +++ b/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,10 @@ import junit.framework.TestCase; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockFilterChain; - - import org.acegisecurity.SecurityConfig; import org.acegisecurity.intercept.web.FilterInvocation; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -35,16 +34,16 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class SecureChannelProcessorTests extends TestCase { - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SecureChannelProcessorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDecideDetectsAcceptableChannel() throws Exception { ConfigAttributeDefinition cad = new ConfigAttributeDefinition(); cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE")); @@ -151,8 +150,7 @@ public class SecureChannelProcessorTests extends TestCase { public void testSupports() { SecureChannelProcessor processor = new SecureChannelProcessor(); - assertTrue(processor.supports( - new SecurityConfig("REQUIRES_SECURE_CHANNEL"))); + assertTrue(processor.supports(new SecurityConfig("REQUIRES_SECURE_CHANNEL"))); assertFalse(processor.supports(null)); assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED"))); } diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java index fe4ce296de..5f2bb3a2ed 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.MockAclManager; import org.acegisecurity.MockApplicationContext; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.MockAclObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.springframework.context.ApplicationContext; @@ -43,20 +46,18 @@ import javax.servlet.jsp.tagext.Tag; * @version $Id$ */ public class AclTagTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final MyAclTag aclTag = new MyAclTag(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testInclusionDeniedWhenAclManagerUnawareOfObject() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); - aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION) - .toString()); + aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString()); aclTag.setDomainObject(new Integer(54)); assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); @@ -65,8 +66,7 @@ public class AclTagTests extends TestCase { public void testInclusionDeniedWhenNoListOfPermissionsGiven() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); aclTag.setHasPermission(null); @@ -78,14 +78,12 @@ public class AclTagTests extends TestCase { public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() throws JspException { - Authentication auth = new TestingAuthenticationToken("john", "crow", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); - aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) - + "," + new Integer(SimpleAclEntry.READ)); - assertEquals(new Integer(SimpleAclEntry.ADMINISTRATION) + "," - + new Integer(SimpleAclEntry.READ), aclTag.getHasPermission()); + aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ)); + assertEquals(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ), + aclTag.getHasPermission()); aclTag.setDomainObject("object1"); assertEquals("object1", aclTag.getDomainObject()); assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); @@ -95,8 +93,7 @@ public class AclTagTests extends TestCase { public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString()); @@ -110,8 +107,7 @@ public class AclTagTests extends TestCase { throws JspException { SecurityContextHolder.getContext().setAuthentication(null); - aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION) - .toString()); + aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString()); aclTag.setDomainObject("object1"); assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); @@ -127,8 +123,7 @@ public class AclTagTests extends TestCase { public void testJspExceptionThrownIfHasPermissionNotValidFormat() throws JspException { - Authentication auth = new TestingAuthenticationToken("john", "crow", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); aclTag.setHasPermission("0,5, 6"); // shouldn't be any space @@ -145,12 +140,10 @@ public class AclTagTests extends TestCase { public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); - aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) - + "," + new Integer(SimpleAclEntry.READ)); + aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ)); aclTag.setDomainObject("object1"); assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag()); @@ -159,8 +152,7 @@ public class AclTagTests extends TestCase { public void testOperationWhenPrincipalHoldsPermissionOfSingleList() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString()); @@ -170,7 +162,7 @@ public class AclTagTests extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry { // just so AclTag iterates some different types of AclEntrys @@ -178,16 +170,15 @@ public class AclTagTests extends TestCase { private class MyAclTag extends AclTag { protected ApplicationContext getContext(PageContext pageContext) { - ConfigurableApplicationContext context = MockApplicationContext - .getContext(); + ConfigurableApplicationContext context = MockApplicationContext.getContext(); // Create an AclManager AclManager aclManager = new MockAclManager("object1", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ) + }); // Register the AclManager into our ApplicationContext context.getBeanFactory().registerSingleton("aclManager", aclManager); diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java index f76323d748..4f961334bd 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,11 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.TestingAuthenticationToken; + import org.acegisecurity.userdetails.User; import javax.servlet.jsp.JspException; @@ -34,18 +37,16 @@ import javax.servlet.jsp.tagext.Tag; * @version $Id$ */ public class AuthenticationTagTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final MyAuthenticationTag authenticationTag = new MyAuthenticationTag(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void testOperationAndMethodPrefixWhenPrincipalIsAUserDetailsInstance() throws JspException { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(new User("marissaUserDetails", "koala", true, true, true, + true, new GrantedAuthority[] {}), "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("username"); @@ -55,8 +56,7 @@ public class AuthenticationTagTests extends TestCase { } public void testOperationWhenPrincipalIsAString() throws JspException { - Authentication auth = new TestingAuthenticationToken("marissaAsString", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissaAsString", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("principal"); @@ -66,10 +66,8 @@ public class AuthenticationTagTests extends TestCase { public void testOperationWhenPrincipalIsAUserDetailsInstance() throws JspException { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(new User("marissaUserDetails", "koala", true, true, true, + true, new GrantedAuthority[] {}), "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("username"); @@ -78,8 +76,7 @@ public class AuthenticationTagTests extends TestCase { } public void testOperationWhenPrincipalIsNull() throws JspException { - Authentication auth = new TestingAuthenticationToken(null, "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(null, "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("principal"); @@ -104,10 +101,8 @@ public class AuthenticationTagTests extends TestCase { } public void testThrowsExceptionForUnrecognisedMethodPrefix() { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(new User("marissaUserDetails", "koala", true, true, true, + true, new GrantedAuthority[] {}), "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("username"); authenticationTag.setMethodPrefix("qrq"); @@ -121,10 +116,8 @@ public class AuthenticationTagTests extends TestCase { } public void testThrowsExceptionForUnrecognisedOperation() { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(new User("marissaUserDetails", "koala", true, true, true, + true, new GrantedAuthority[] {}), "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authenticationTag.setOperation("qsq"); @@ -136,7 +129,7 @@ public class AuthenticationTagTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MyAuthenticationTag extends AuthenticationTag { String lastMessage = null; diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagAttributeTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagAttributeTests.java index 7878d54fe1..1e75ec8631 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagAttributeTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagAttributeTests.java @@ -35,20 +35,20 @@ import javax.servlet.jsp.tagext.Tag; * @version $Id$ */ public class AuthorizeTagAttributeTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final AuthorizeTag authorizeTag = new AuthorizeTag(); private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); currentUser = new TestingAuthenticationToken("abc", "123", - new GrantedAuthority[] {new GrantedAuthorityImpl( - "ROLE_SUPERVISOR"), new GrantedAuthorityImpl( - "ROLE_RESTRICTED"),}); + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_SUPERVISOR"), new GrantedAuthorityImpl("ROLE_RESTRICTED"), + }); SecurityContextHolder.getContext().setAuthentication(currentUser); } @@ -60,45 +60,39 @@ public class AuthorizeTagAttributeTests extends TestCase { public void testAssertsIfAllGrantedSecond() throws JspException { authorizeTag.setIfAllGranted("ROLE_SUPERVISOR,ROLE_SUPERTELLER"); authorizeTag.setIfAnyGranted("ROLE_RESTRICTED"); - assertEquals("prevents request - principal is missing ROLE_SUPERTELLER", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - principal is missing ROLE_SUPERTELLER", Tag.SKIP_BODY, + authorizeTag.doStartTag()); } public void testAssertsIfAnyGrantedLast() throws JspException { authorizeTag.setIfAnyGranted("ROLE_BANKER"); - assertEquals("prevents request - principal is missing ROLE_BANKER", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - principal is missing ROLE_BANKER", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testAssertsIfNotGrantedFirst() throws JspException { authorizeTag.setIfNotGranted("ROLE_RESTRICTED"); authorizeTag.setIfAllGranted("ROLE_SUPERVISOR,ROLE_RESTRICTED"); authorizeTag.setIfAnyGranted("ROLE_SUPERVISOR"); - assertEquals("prevents request - principal has ROLE_RESTRICTED", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - principal has ROLE_RESTRICTED", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testAssertsIfNotGrantedIgnoresWhitespaceInAttribute() throws JspException { - authorizeTag.setIfAnyGranted( - "\tROLE_SUPERVISOR \t, \r\n\t ROLE_TELLER "); - assertEquals("allows request - principal has ROLE_SUPERVISOR", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + authorizeTag.setIfAnyGranted("\tROLE_SUPERVISOR \t, \r\n\t ROLE_TELLER "); + assertEquals("allows request - principal has ROLE_SUPERVISOR", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); } public void testIfAllGrantedIgnoresWhitespaceInAttribute() throws JspException { - authorizeTag.setIfAllGranted( - "\nROLE_SUPERVISOR\t,ROLE_RESTRICTED\t\n\r "); - assertEquals("allows request - principal has ROLE_RESTRICTED " - + "and ROLE_SUPERVISOR", Tag.EVAL_BODY_INCLUDE, + authorizeTag.setIfAllGranted("\nROLE_SUPERVISOR\t,ROLE_RESTRICTED\t\n\r "); + assertEquals("allows request - principal has ROLE_RESTRICTED " + "and ROLE_SUPERVISOR", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); } public void testIfNotGrantedIgnoresWhitespaceInAttribute() throws JspException { authorizeTag.setIfNotGranted(" \t ROLE_TELLER \r"); - assertEquals("allows request - principal does not have ROLE_TELLER", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("allows request - principal does not have ROLE_TELLER", Tag.EVAL_BODY_INCLUDE, + authorizeTag.doStartTag()); } } diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagCustomGrantedAuthorityTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagCustomGrantedAuthorityTests.java index a853c6ff2b..d03a86be08 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagCustomGrantedAuthorityTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagCustomGrantedAuthorityTests.java @@ -34,19 +34,18 @@ import javax.servlet.jsp.tagext.Tag; * @version $Id$ */ public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final AuthorizeTag authorizeTag = new AuthorizeTag(); private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); currentUser = new TestingAuthenticationToken("abc", "123", - new GrantedAuthority[] {new CustomGrantedAuthority( - "ROLE_TELLER")}); + new GrantedAuthority[] {new CustomGrantedAuthority("ROLE_TELLER")}); SecurityContextHolder.getContext().setAuthentication(currentUser); } @@ -58,16 +57,14 @@ public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase { public void testAllowsRequestWhenCustomAuthorityPresentsCorrectRole() throws JspException { authorizeTag.setIfAnyGranted("ROLE_TELLER"); - assertEquals("authorized - ROLE_TELLER in both sets", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("authorized - ROLE_TELLER in both sets", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); } public void testRejectsRequestWhenCustomAuthorityReturnsNull() throws JspException { authorizeTag.setIfAnyGranted("ROLE_TELLER"); SecurityContextHolder.getContext() - .setAuthentication(new TestingAuthenticationToken( - "abc", "123", + .setAuthentication(new TestingAuthenticationToken("abc", "123", new GrantedAuthority[] {new CustomGrantedAuthority(null)})); try { @@ -78,7 +75,7 @@ public class AuthorizeTagCustomGrantedAuthorityTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private static class CustomGrantedAuthority implements GrantedAuthority { private final String authority; diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagExpressionLanguageTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagExpressionLanguageTests.java index 2f4cab5ab2..2d9a42c84a 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagExpressionLanguageTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagExpressionLanguageTests.java @@ -34,13 +34,13 @@ import javax.servlet.jsp.tagext.Tag; * Test case to implement commons-el expression language expansion. */ public class AuthorizeTagExpressionLanguageTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final AuthorizeTag authorizeTag = new AuthorizeTag(); private MockPageContext pageContext; private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); @@ -63,8 +63,8 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase { pageContext.setAttribute("authority", "ROLE_TELLER"); authorizeTag.setIfAllGranted("${authority}"); - assertEquals("allows body - authority var contains ROLE_TELLER", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("allows body - authority var contains ROLE_TELLER", Tag.EVAL_BODY_INCLUDE, + authorizeTag.doStartTag()); } public void testAnyGrantedUsesExpressionLanguageWhenExpressionIsEL() @@ -72,8 +72,8 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase { pageContext.setAttribute("authority", "ROLE_TELLER"); authorizeTag.setIfAnyGranted("${authority}"); - assertEquals("allows body - authority var contains ROLE_TELLER", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("allows body - authority var contains ROLE_TELLER", Tag.EVAL_BODY_INCLUDE, + authorizeTag.doStartTag()); } public void testNotGrantedUsesExpressionLanguageWhenExpressionIsEL() @@ -81,7 +81,6 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase { pageContext.setAttribute("authority", "ROLE_TELLER"); authorizeTag.setIfNotGranted("${authority}"); - assertEquals("allows body - authority var contains ROLE_TELLER", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("allows body - authority var contains ROLE_TELLER", Tag.SKIP_BODY, authorizeTag.doStartTag()); } } diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagTests.java index 07400c1c77..26792f52e0 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagTests.java +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthorizeTagTests.java @@ -35,20 +35,20 @@ import javax.servlet.jsp.tagext.Tag; * @version $Id$ */ public class AuthorizeTagTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final AuthorizeTag authorizeTag = new AuthorizeTag(); private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); currentUser = new TestingAuthenticationToken("abc", "123", - new GrantedAuthority[] {new GrantedAuthorityImpl( - "ROLE_SUPERVISOR"), new GrantedAuthorityImpl( - "ROLE_TELLER"),}); + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_SUPERVISOR"), new GrantedAuthorityImpl("ROLE_TELLER"), + }); SecurityContextHolder.getContext().setAuthentication(currentUser); } @@ -62,8 +62,7 @@ public class AuthorizeTagTests extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); authorizeTag.setIfAllGranted("ROLE_TELLER"); - assertEquals("prevents request - no principal in Context", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - no principal in Context", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testDefaultsToNotOutputtingBodyWhenNoRequiredAuthorities() @@ -72,27 +71,25 @@ public class AuthorizeTagTests extends TestCase { assertEquals("", authorizeTag.getIfAnyGranted()); assertEquals("", authorizeTag.getIfNotGranted()); - assertEquals("prevents body output - no authorities granted", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents body output - no authorities granted", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testOutputsBodyIfOneRolePresent() throws JspException { authorizeTag.setIfAnyGranted("ROLE_TELLER"); - assertEquals("authorized - ROLE_TELLER in both sets", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("authorized - ROLE_TELLER in both sets", Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); } public void testOutputsBodyWhenAllGranted() throws JspException { authorizeTag.setIfAllGranted("ROLE_SUPERVISOR,ROLE_TELLER"); - assertEquals("allows request - all required roles granted on principal", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("allows request - all required roles granted on principal", Tag.EVAL_BODY_INCLUDE, + authorizeTag.doStartTag()); } public void testOutputsBodyWhenNotGrantedSatisfied() throws JspException { authorizeTag.setIfNotGranted("ROLE_BANKER"); - assertEquals("allows request - principal doesn't have ROLE_BANKER", - Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag()); + assertEquals("allows request - principal doesn't have ROLE_BANKER", Tag.EVAL_BODY_INCLUDE, + authorizeTag.doStartTag()); } public void testPreventsBodyOutputIfNoSecurityContext() @@ -100,27 +97,23 @@ public class AuthorizeTagTests extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); authorizeTag.setIfAnyGranted("ROLE_BANKER"); - assertEquals("prevents output - no context defined", Tag.SKIP_BODY, - authorizeTag.doStartTag()); + assertEquals("prevents output - no context defined", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testSkipsBodyIfNoAnyRolePresent() throws JspException { authorizeTag.setIfAnyGranted("ROLE_BANKER"); - assertEquals("unauthorized - ROLE_BANKER not in granted authorities", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("unauthorized - ROLE_BANKER not in granted authorities", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testSkipsBodyWhenMissingAnAllGranted() throws JspException { authorizeTag.setIfAllGranted("ROLE_SUPERVISOR,ROLE_TELLER,ROLE_BANKER"); - assertEquals("prevents request - missing ROLE_BANKER on principal", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - missing ROLE_BANKER on principal", Tag.SKIP_BODY, authorizeTag.doStartTag()); } public void testSkipsBodyWhenNotGrantedUnsatisfied() throws JspException { authorizeTag.setIfNotGranted("ROLE_TELLER"); - assertEquals("prevents request - principal has ROLE_TELLER", - Tag.SKIP_BODY, authorizeTag.doStartTag()); + assertEquals("prevents request - principal has ROLE_TELLER", Tag.SKIP_BODY, authorizeTag.doStartTag()); } } diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java index a34e5c4fd6..508b6b47a4 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java +++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java @@ -31,20 +31,20 @@ import javax.servlet.jsp.JspException; * DOCUMENT ME! */ public class AuthzImplAttributeTest extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final Authz authz = new AuthzImpl(); private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); currentUser = new TestingAuthenticationToken("abc", "123", - new GrantedAuthority[] {new GrantedAuthorityImpl( - "ROLE_SUPERVISOR"), new GrantedAuthorityImpl( - "ROLE_RESTRICTED"),}); + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_SUPERVISOR"), new GrantedAuthorityImpl("ROLE_RESTRICTED"), + }); SecurityContextHolder.getContext().setAuthentication(currentUser); } @@ -79,14 +79,12 @@ public class AuthzImplAttributeTest extends TestCase { public void testAssertsIfNotGrantedIgnoresWhitespaceInAttribute() { //allows request - principal has ROLE_SUPERVISOR - assertTrue(authz.anyGranted( - "\tROLE_SUPERVISOR \t, \r\n\t ROLE_TELLER ")); + assertTrue(authz.anyGranted("\tROLE_SUPERVISOR \t, \r\n\t ROLE_TELLER ")); } public void testIfAllGrantedIgnoresWhitespaceInAttribute() { //allows request - principal has ROLE_RESTRICTED and ROLE_SUPERVISOR - assertTrue(authz.allGranted( - "\nROLE_SUPERVISOR\t,ROLE_RESTRICTED\t\n\r ")); + assertTrue(authz.allGranted("\nROLE_SUPERVISOR\t,ROLE_RESTRICTED\t\n\r ")); } public void testIfNotGrantedIgnoresWhitespaceInAttribute() diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java index 72399381ba..00ea581993 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java +++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java @@ -29,20 +29,20 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * DOCUMENT ME! */ public class AuthzImplAuthorizeTagTest extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authz authz = new AuthzImpl(); private TestingAuthenticationToken currentUser; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); currentUser = new TestingAuthenticationToken("abc", "123", - new GrantedAuthority[] {new GrantedAuthorityImpl( - "ROLE_SUPERVISOR"), new GrantedAuthorityImpl( - "ROLE_TELLER"),}); + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_SUPERVISOR"), new GrantedAuthorityImpl("ROLE_TELLER"), + }); SecurityContextHolder.getContext().setAuthentication(currentUser); } diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java index 7335fdd7a6..9ce925c68f 100644 --- a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java +++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,12 +40,12 @@ import org.springframework.context.support.StaticApplicationContext; * DOCUMENT ME! */ public class AuthzImplTest extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Authz authz = new AuthzImpl(); private ConfigurableApplicationContext ctx; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== protected void setUp() throws Exception { super.setUp(); @@ -56,19 +56,18 @@ public class AuthzImplTest extends TestCase { // Create an AclManager AclManager aclManager = new MockAclManager("object1", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ) + }); // Register the AclManager into our ApplicationContext ctx.getBeanFactory().registerSingleton("aclManager", aclManager); } public void testIllegalArgumentExceptionThrownIfHasPermissionNotValidFormat() { - Authentication auth = new TestingAuthenticationToken("john", "crow", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); @@ -85,14 +84,12 @@ public class AuthzImplTest extends TestCase { } public void testInclusionDeniedWhenAclManagerUnawareOfObject() { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); - boolean result = authz.hasPermission(new Integer(54), - new Long(SimpleAclEntry.ADMINISTRATION).toString()); + boolean result = authz.hasPermission(new Integer(54), new Long(SimpleAclEntry.ADMINISTRATION).toString()); assertFalse(result); @@ -100,8 +97,7 @@ public class AuthzImplTest extends TestCase { } public void testInclusionDeniedWhenNoListOfPermissionsGiven() { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); @@ -113,14 +109,12 @@ public class AuthzImplTest extends TestCase { } public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() { - Authentication auth = new TestingAuthenticationToken("john", "crow", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); - String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + "," - + new Integer(SimpleAclEntry.READ); + String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ); boolean result = authz.hasPermission("object1", permissions); @@ -130,8 +124,7 @@ public class AuthzImplTest extends TestCase { } public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); @@ -169,14 +162,12 @@ public class AuthzImplTest extends TestCase { } public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); - String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + "," - + new Integer(SimpleAclEntry.READ); + String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ); boolean result = authz.hasPermission("object1", permissions); @@ -186,8 +177,7 @@ public class AuthzImplTest extends TestCase { } public void testOperationWhenPrincipalHoldsPermissionOfSingleList() { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); authz.setAppCtx(ctx); @@ -204,26 +194,22 @@ public class AuthzImplTest extends TestCase { * Test method for 'com.alibaba.exodus2.web.common.security.pulltool.AuthzImpl.getPrincipal()' */ public void testOperationWhenPrincipalIsAString() { - Authentication auth = new TestingAuthenticationToken("marissaAsString", - "koala", new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken("marissaAsString", "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); assertEquals("marissaAsString", authz.getPrincipal()); } public void testOperationWhenPrincipalIsAUserDetailsInstance() { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(new User("marissaUserDetails", "koala", true, true, true, + true, new GrantedAuthority[] {}), "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); assertEquals("marissaUserDetails", authz.getPrincipal()); } public void testOperationWhenPrincipalIsNull() { - Authentication auth = new TestingAuthenticationToken(null, "koala", - new GrantedAuthority[] {}); + Authentication auth = new TestingAuthenticationToken(null, "koala", new GrantedAuthority[] {}); SecurityContextHolder.getContext().setAuthentication(auth); assertNull(authz.getPrincipal()); @@ -237,7 +223,7 @@ public class AuthzImplTest extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry { private static final long serialVersionUID = 1L; diff --git a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java index b36fca0923..4b2c5a30e5 100644 --- a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java @@ -59,7 +59,7 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class AbstractProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractProcessingFilterTests() { super(); @@ -69,7 +69,7 @@ public class AbstractProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private MockHttpServletRequest createMockRequest() { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -82,9 +82,9 @@ public class AbstractProcessingFilterTests extends TestCase { return request; } - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { filter.init(filterConfig); filter.doFilter(request, response, filterChain); filter.destroy(); @@ -120,8 +120,7 @@ public class AbstractProcessingFilterTests extends TestCase { MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(); filter.setFilterProcessesUrl("/j_acegi_security_check"); - request.setRequestURI( - "/mycontext/j_acegi_security_check;jsessionid=I8MIONOSTHOR"); + request.setRequestURI("/mycontext/j_acegi_security_check;jsessionid=I8MIONOSTHOR"); assertTrue(filter.requiresAuthentication(request, response)); } @@ -130,12 +129,10 @@ public class AbstractProcessingFilterTests extends TestCase { AbstractProcessingFilter filter = new MockAbstractProcessingFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -144,12 +141,10 @@ public class AbstractProcessingFilterTests extends TestCase { AbstractProcessingFilter filter = new MockAbstractProcessingFilter(); try { - filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain()); + filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } @@ -170,26 +165,22 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setAuthenticationFailureUrl("/myApp/failed.jsp"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/myApp/failed.jsp", response.getRedirectedUrl()); assertNull(SecurityContextHolder.getContext().getAuthentication()); //Prepare again, this time using the exception mapping - filter = new MockAbstractProcessingFilter(new AccountExpiredException( - "You're account is expired")); + filter = new MockAbstractProcessingFilter(new AccountExpiredException("You're account is expired")); filter.setAuthenticationFailureUrl("/myApp/failed.jsp"); Properties exceptionMappings = filter.getExceptionMappings(); - exceptionMappings.setProperty(AccountExpiredException.class.getName(), - "/myApp/accountExpired.jsp"); + exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/myApp/accountExpired.jsp"); filter.setExceptionMappings(exceptionMappings); response = new MockHttpServletResponse(); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/myApp/accountExpired.jsp", response.getRedirectedUrl()); assertNull(SecurityContextHolder.getContext().getAuthentication()); @@ -215,21 +206,17 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setDefaultTargetUrl("/logged_in.jsp"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/logged_in.jsp", response.getRedirectedUrl()); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); - assertEquals("test", - SecurityContextHolder.getContext().getAuthentication().getPrincipal() - .toString()); + assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()); } public void testGettersSetters() { AbstractProcessingFilter filter = new MockAbstractProcessingFilter(); assertNotNull(filter.getRememberMeServices()); filter.setRememberMeServices(new TokenBasedRememberMeServices()); - assertEquals(TokenBasedRememberMeServices.class, - filter.getRememberMeServices().getClass()); + assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass()); filter.setAuthenticationFailureUrl("/x"); assertEquals("/x", filter.getAuthenticationFailureUrl()); @@ -265,8 +252,7 @@ public class AbstractProcessingFilterTests extends TestCase { MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); } public void testNormalOperationWithDefaultFilterProcessesUrl() @@ -290,13 +276,10 @@ public class AbstractProcessingFilterTests extends TestCase { filter.afterPropertiesSet(); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/logged_in.jsp", response.getRedirectedUrl()); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); - assertEquals("test", - SecurityContextHolder.getContext().getAuthentication().getPrincipal() - .toString()); + assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()); } public void testStartupDetectsInvalidAuthenticationFailureUrl() @@ -310,8 +293,7 @@ public class AbstractProcessingFilterTests extends TestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("authenticationFailureUrl must be specified", - expected.getMessage()); + assertEquals("authenticationFailureUrl must be specified", expected.getMessage()); } } @@ -326,8 +308,7 @@ public class AbstractProcessingFilterTests extends TestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("authenticationManager must be specified", - expected.getMessage()); + assertEquals("authenticationManager must be specified", expected.getMessage()); } } @@ -342,8 +323,7 @@ public class AbstractProcessingFilterTests extends TestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("defaultTargetUrl must be specified", - expected.getMessage()); + assertEquals("defaultTargetUrl must be specified", expected.getMessage()); } } @@ -359,8 +339,7 @@ public class AbstractProcessingFilterTests extends TestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("filterProcessesUrl must be specified", - expected.getMessage()); + assertEquals("filterProcessesUrl must be specified", expected.getMessage()); } } @@ -382,13 +361,10 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setDefaultTargetUrl("/logged_in.jsp"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/logged_in.jsp", response.getRedirectedUrl()); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); - assertEquals("test", - SecurityContextHolder.getContext().getAuthentication().getPrincipal() - .toString()); + assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()); // Now try again but this time have filter deny access // Setup our HTTP request @@ -402,8 +378,7 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setAuthenticationFailureUrl("/failed.jsp"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertNull(SecurityContextHolder.getContext().getAuthentication()); } @@ -411,9 +386,7 @@ public class AbstractProcessingFilterTests extends TestCase { throws Exception { // Setup our HTTP request MockHttpServletRequest request = createMockRequest(); - request.getSession() - .setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, - makeSavedRequestForUrl()); + request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, makeSavedRequestForUrl()); // Setup our filter configuration MockFilterConfig config = new MockFilterConfig(null); @@ -431,8 +404,7 @@ public class AbstractProcessingFilterTests extends TestCase { assertTrue(filter.isAlwaysUseDefaultTargetUrl()); // check changed // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); assertEquals("/foobar", response.getRedirectedUrl()); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); } @@ -441,9 +413,7 @@ public class AbstractProcessingFilterTests extends TestCase { throws Exception { // Setup our HTTP request MockHttpServletRequest request = createMockRequest(); - request.getSession() - .setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, - makeSavedRequestForUrl()); + request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SAVED_REQUEST_KEY, makeSavedRequestForUrl()); // Setup our filter configuration MockFilterConfig config = new MockFilterConfig(null); @@ -457,14 +427,12 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setFilterProcessesUrl("/j_mock_post"); // Test - executeFilterInContainerSimulator(config, filter, request, response, - chain); - assertEquals(makeSavedRequestForUrl().getFullRequestUrl(), - response.getRedirectedUrl()); + executeFilterInContainerSimulator(config, filter, request, response, chain); + assertEquals(makeSavedRequestForUrl().getFullRequestUrl(), response.getRedirectedUrl()); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAbstractProcessingFilter extends AbstractProcessingFilter { private AuthenticationException exceptionToThrow; @@ -472,12 +440,10 @@ public class AbstractProcessingFilterTests extends TestCase { public MockAbstractProcessingFilter(boolean grantAccess) { this.grantAccess = grantAccess; - this.exceptionToThrow = new BadCredentialsException( - "Mock requested to do so"); + this.exceptionToThrow = new BadCredentialsException("Mock requested to do so"); } - public MockAbstractProcessingFilter( - AuthenticationException exceptionToThrow) { + public MockAbstractProcessingFilter(AuthenticationException exceptionToThrow) { this.grantAccess = false; this.exceptionToThrow = exceptionToThrow; } @@ -502,8 +468,7 @@ public class AbstractProcessingFilterTests extends TestCase { public void init(FilterConfig arg0) throws ServletException {} - public boolean requiresAuthentication(HttpServletRequest request, - HttpServletResponse response) { + public boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { return super.requiresAuthentication(request, response); } } diff --git a/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java b/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java index ab60766b9b..b4c2dc368b 100644 --- a/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java @@ -46,7 +46,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class ExceptionTranslationFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ExceptionTranslationFilterTests() { super(); @@ -56,7 +56,7 @@ public class ExceptionTranslationFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ExceptionTranslationFilterTests.class); @@ -86,14 +86,12 @@ public class ExceptionTranslationFilterTests extends TestCase { // Setup SecurityContextHolder, as filter needs to check if user is anonymous SecurityContextHolder.getContext() - .setAuthentication(new AnonymousAuthenticationToken( - "ignored", "ignored", + .setAuthentication(new AnonymousAuthenticationToken("ignored", "ignored", new GrantedAuthority[] {new GrantedAuthorityImpl("IGNORED")})); // Test ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, chain); @@ -119,17 +117,14 @@ public class ExceptionTranslationFilterTests extends TestCase { // Test ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); filter.setAccessDeniedHandler(adh); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, chain); assertEquals(403, response.getStatus()); assertEquals(AccessDeniedException.class, - request.getAttribute( - AccessDeniedHandlerImpl.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY) - .getClass()); + request.getAttribute(AccessDeniedHandlerImpl.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY).getClass()); } public void testDoFilterWithNonHttpServletRequestDetected() @@ -137,8 +132,7 @@ public class ExceptionTranslationFilterTests extends TestCase { ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain(false, false, false, false)); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain(false, false, false, false)); fail("Should have thrown ServletException"); } catch (ServletException expected) { assertEquals("HttpServletRequest required", expected.getMessage()); @@ -161,8 +155,7 @@ public class ExceptionTranslationFilterTests extends TestCase { public void testGettersSetters() { ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); assertTrue(filter.getAuthenticationEntryPoint() != null); filter.setPortResolver(new MockPortResolver(80, 443)); @@ -185,8 +178,7 @@ public class ExceptionTranslationFilterTests extends TestCase { // Test ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); filter.setPortResolver(new MockPortResolver(80, 443)); filter.afterPropertiesSet(); @@ -213,8 +205,7 @@ public class ExceptionTranslationFilterTests extends TestCase { // Test ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); filter.setPortResolver(new MockPortResolver(8080, 8443)); filter.afterPropertiesSet(); @@ -233,16 +224,14 @@ public class ExceptionTranslationFilterTests extends TestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("authenticationEntryPoint must be specified", - expected.getMessage()); + assertEquals("authenticationEntryPoint must be specified", expected.getMessage()); } } public void testStartupDetectsMissingPortResolver() throws Exception { ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); filter.setPortResolver(null); try { @@ -263,8 +252,7 @@ public class ExceptionTranslationFilterTests extends TestCase { // Test ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp")); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, chain); @@ -287,13 +275,11 @@ public class ExceptionTranslationFilterTests extends TestCase { filter.afterPropertiesSet(); try { - filter.doFilter(new MockHttpServletRequest(), - new MockHttpServletResponse(), + filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false, false, false, true)); fail("Should have thrown IOException"); } catch (IOException e) { - assertNull("The IOException thrown should not have been wrapped", - e.getCause()); + assertNull("The IOException thrown should not have been wrapped", e.getCause()); } } @@ -305,17 +291,15 @@ public class ExceptionTranslationFilterTests extends TestCase { filter.afterPropertiesSet(); try { - filter.doFilter(new MockHttpServletRequest(), - new MockHttpServletResponse(), + filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false, false, true, false)); fail("Should have thrown ServletException"); } catch (ServletException e) { - assertNull("The ServletException thrown should not have been wrapped", - e.getCause()); + assertNull("The ServletException thrown should not have been wrapped", e.getCause()); } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private boolean throwAccessDenied; @@ -323,9 +307,8 @@ public class ExceptionTranslationFilterTests extends TestCase { private boolean throwIOException; private boolean throwServletException; - public MockFilterChain(boolean throwAccessDenied, - boolean throwAuthenticationFailure, boolean throwServletException, - boolean throwIOException) { + public MockFilterChain(boolean throwAccessDenied, boolean throwAuthenticationFailure, + boolean throwServletException, boolean throwIOException) { this.throwAccessDenied = throwAccessDenied; this.throwAuthenticationFailure = throwAuthenticationFailure; this.throwServletException = throwServletException; diff --git a/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPointTests.java index f79f52adbe..ab8f9ee278 100644 --- a/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ import junit.framework.TestCase; import org.acegisecurity.DisabledException; - - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -32,7 +30,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class BasicProcessingFilterEntryPointTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicProcessingFilterEntryPointTests() { super(); @@ -42,16 +40,16 @@ public class BasicProcessingFilterEntryPointTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(BasicProcessingFilterEntryPointTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingRealmName() throws Exception { BasicProcessingFilterEntryPoint ep = new BasicProcessingFilterEntryPoint(); @@ -75,6 +73,7 @@ public class BasicProcessingFilterEntryPointTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("/some_path"); + MockHttpServletResponse response = new MockHttpServletResponse(); ep.afterPropertiesSet(); @@ -85,7 +84,6 @@ public class BasicProcessingFilterEntryPointTests extends TestCase { assertEquals(401, response.getStatus()); assertEquals(msg, response.getErrorMessage()); - assertEquals("Basic realm=\"hello\"", - response.getHeader("WWW-Authenticate")); + assertEquals("Basic realm=\"hello\"", response.getHeader("WWW-Authenticate")); } } diff --git a/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterTests.java index 7884cecf7e..8f23854f68 100644 --- a/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterTests.java @@ -59,11 +59,11 @@ import javax.servlet.ServletRequest; * @version $Id$ */ public class BasicProcessingFilterTests extends MockObjectTestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private BasicProcessingFilter filter; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicProcessingFilterTests() { super(); @@ -73,19 +73,17 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private MockHttpServletResponse executeFilterInContainerSimulator( - Filter filter, ServletRequest request, boolean expectChainToProceed) - throws ServletException, IOException { + private MockHttpServletResponse executeFilterInContainerSimulator(Filter filter, ServletRequest request, + boolean expectChainToProceed) throws ServletException, IOException { filter.init(new MockFilterConfig()); MockHttpServletResponse response = new MockHttpServletResponse(); Mock mockChain = mock(FilterChain.class); FilterChain chain = (FilterChain) mockChain.proxy(); - mockChain.expects(expectChainToProceed ? once() : never()) - .method("doFilter"); + mockChain.expects(expectChainToProceed ? once() : never()).method("doFilter"); filter.doFilter(request, response, chain); filter.destroy(); @@ -130,12 +128,10 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { BasicProcessingFilter filter = new BasicProcessingFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -144,12 +140,10 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { BasicProcessingFilter filter = new BasicProcessingFilter(); try { - filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain()); + filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } @@ -170,8 +164,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { filter.setAuthenticationManager(new MockAuthenticationManager()); assertTrue(filter.getAuthenticationManager() != null); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "sx")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("sx")); assertTrue(filter.getAuthenticationEntryPoint() != null); } @@ -180,8 +173,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { // Setup our HTTP request String token = "NOT_A_VALID_TOKEN_AS_MISSING_COLON"; MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); @@ -195,8 +187,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { // Setup our HTTP request String token = "marissa:koala"; MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); @@ -206,8 +197,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { assertNotNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals("marissa", - ((UserDetails) SecurityContextHolder.getContext().getAuthentication() - .getPrincipal()).getUsername()); + ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()); } public void testOtherAuthorizationSchemeIsIgnored() @@ -231,8 +221,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An AuthenticationEntryPoint is required", - expected.getMessage()); + assertEquals("An AuthenticationEntryPoint is required", expected.getMessage()); } } @@ -240,13 +229,11 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { throws Exception { try { BasicProcessingFilter filter = new BasicProcessingFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "x")); + filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("x")); filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("An AuthenticationManager is required", - expected.getMessage()); + assertEquals("An AuthenticationManager is required", expected.getMessage()); } } @@ -255,8 +242,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { // Setup our HTTP request String token = "marissa:koala"; MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); @@ -265,21 +251,18 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { assertNotNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals("marissa", - ((UserDetails) SecurityContextHolder.getContext().getAuthentication() - .getPrincipal()).getUsername()); + ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()); // NOW PERFORM FAILED AUTHENTICATION // Setup our HTTP request token = "otherUser:WRONG_PASSWORD"; request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); // Test - the filter chain will not be invoked, as we get a 403 forbidden response - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -290,8 +273,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { // Setup our HTTP request String token = "marissa:WRONG_PASSWORD"; MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); @@ -299,8 +281,7 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { assertTrue(filter.isIgnoreFailure()); // Test - the filter chain will be invoked, as we've set ignoreFailure = true - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, true); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, true); assertNull(SecurityContextHolder.getContext().getAuthentication()); } @@ -310,24 +291,21 @@ public class BasicProcessingFilterTests extends MockObjectTestCase { // Setup our HTTP request String token = "marissa:WRONG_PASSWORD"; MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", - "Basic " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes()))); request.setServletPath("/some_file.html"); request.setSession(new MockHttpSession()); assertFalse(filter.isIgnoreFailure()); // Test - the filter chain will not be invoked, as we get a 403 forbidden response - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private class MockApplicationEventPublisher - implements ApplicationEventPublisher { + private class MockApplicationEventPublisher implements ApplicationEventPublisher { public MockApplicationEventPublisher() {} public void publishEvent(ApplicationEvent event) {} diff --git a/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPointTests.java index 260791b6d3..c202858bf1 100644 --- a/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,12 @@ package org.acegisecurity.ui.cas; import junit.framework.TestCase; -import java.net.URLEncoder; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import java.net.URLEncoder; + + /** * Tests {@link CasProcessingFilterEntryPoint}. * @@ -29,7 +30,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class CasProcessingFilterEntryPointTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasProcessingFilterEntryPointTests() { super(); @@ -39,16 +40,16 @@ public class CasProcessingFilterEntryPointTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasProcessingFilterEntryPointTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingLoginFormUrl() throws Exception { CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint(); ep.setServiceProperties(new ServiceProperties()); @@ -69,8 +70,7 @@ public class CasProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("serviceProperties must be specified", - expected.getMessage()); + assertEquals("serviceProperties must be specified", expected.getMessage()); } } @@ -86,8 +86,7 @@ public class CasProcessingFilterEntryPointTests extends TestCase { public void testNormalOperationWithRenewFalse() throws Exception { ServiceProperties sp = new ServiceProperties(); sp.setSendRenew(false); - sp.setService( - "https://mycompany.com/bigWebApp/j_acegi_cas_security_check"); + sp.setService("https://mycompany.com/bigWebApp/j_acegi_cas_security_check"); CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint(); ep.setLoginUrl("https://cas/login"); @@ -102,16 +101,14 @@ public class CasProcessingFilterEntryPointTests extends TestCase { ep.commence(request, response, null); assertEquals("https://cas/login?service=" - + URLEncoder.encode( - "https://mycompany.com/bigWebApp/j_acegi_cas_security_check", - "UTF-8"), response.getRedirectedUrl()); + + URLEncoder.encode("https://mycompany.com/bigWebApp/j_acegi_cas_security_check", "UTF-8"), + response.getRedirectedUrl()); } public void testNormalOperationWithRenewTrue() throws Exception { ServiceProperties sp = new ServiceProperties(); sp.setSendRenew(true); - sp.setService( - "https://mycompany.com/bigWebApp/j_acegi_cas_security_check"); + sp.setService("https://mycompany.com/bigWebApp/j_acegi_cas_security_check"); CasProcessingFilterEntryPoint ep = new CasProcessingFilterEntryPoint(); ep.setLoginUrl("https://cas/login"); @@ -124,7 +121,8 @@ public class CasProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response, null); - assertEquals("https://cas/login?service=" + URLEncoder.encode("https://mycompany.com/bigWebApp/j_acegi_cas_security_check", "UTF-8") + "&renew=true", + assertEquals("https://cas/login?service=" + + URLEncoder.encode("https://mycompany.com/bigWebApp/j_acegi_cas_security_check", "UTF-8") + "&renew=true", response.getRedirectedUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterTests.java index a57f1337b9..62131f5708 100644 --- a/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/cas/CasProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class CasProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public CasProcessingFilterTests() { super(); @@ -41,20 +41,19 @@ public class CasProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(CasProcessingFilterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() { CasProcessingFilter filter = new CasProcessingFilter(); - assertEquals("/j_acegi_cas_security_check", - filter.getDefaultFilterProcessesUrl()); + assertEquals("/j_acegi_cas_security_check", filter.getDefaultFilterProcessesUrl()); } public void testNormalOperation() throws Exception { diff --git a/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java b/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java index 3671dbcfcd..944b2e267a 100644 --- a/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java +++ b/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class ServicePropertiesTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ServicePropertiesTests() { super(); @@ -35,16 +35,16 @@ public class ServicePropertiesTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(ServicePropertiesTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingLoginFormUrl() throws Exception { ServiceProperties sp = new ServiceProperties(); diff --git a/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPointTests.java index 2bdc4c7143..d8d169e94c 100644 --- a/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPointTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,16 @@ import junit.framework.TestCase; import org.acegisecurity.DisabledException; - - import org.acegisecurity.util.StringSplitUtils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; -import org.springframework.util.StringUtils; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.util.StringUtils; + import java.util.Map; @@ -40,7 +39,7 @@ import java.util.Map; * @version $Id$ */ public class DigestProcessingFilterEntryPointTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public DigestProcessingFilterEntryPointTests() { super(); @@ -50,16 +49,30 @@ public class DigestProcessingFilterEntryPointTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private void checkNonceValid(String nonce) { + // Check the nonce seems to be generated correctly + // format of nonce is: + // base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) + assertTrue(Base64.isArrayByteBase64(nonce.getBytes())); + + String decodedNonce = new String(Base64.decodeBase64(nonce.getBytes())); + String[] nonceTokens = StringUtils.delimitedListToStringArray(decodedNonce, ":"); + assertEquals(2, nonceTokens.length); + + String expectedNonceSignature = DigestUtils.md5Hex(nonceTokens[0] + ":" + "key"); + assertEquals(expectedNonceSignature, nonceTokens[1]); } public static void main(String[] args) { junit.textui.TestRunner.run(DigestProcessingFilterEntryPointTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsMissingKey() throws Exception { DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint(); ep.setRealmName("realm"); @@ -103,6 +116,7 @@ public class DigestProcessingFilterEntryPointTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("/some_path"); + MockHttpServletResponse response = new MockHttpServletResponse(); ep.afterPropertiesSet(); @@ -132,12 +146,12 @@ public class DigestProcessingFilterEntryPointTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("/some_path"); + MockHttpServletResponse response = new MockHttpServletResponse(); ep.afterPropertiesSet(); - ep.commence(request, response, - new NonceExpiredException("expired nonce")); + ep.commence(request, response, new NonceExpiredException("expired nonce")); // Check response is properly formed assertEquals(401, response.getStatus()); @@ -146,8 +160,7 @@ public class DigestProcessingFilterEntryPointTests extends TestCase { // Break up response header String header = response.getHeader("WWW-Authenticate").toString().substring(7); String[] headerEntries = StringUtils.commaDelimitedListToStringArray(header); - Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, - "=", "\""); + Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\""); assertEquals("hello", headerMap.get("realm")); assertEquals("auth", headerMap.get("qop")); @@ -155,20 +168,4 @@ public class DigestProcessingFilterEntryPointTests extends TestCase { checkNonceValid((String) headerMap.get("nonce")); } - - private void checkNonceValid(String nonce) { - // Check the nonce seems to be generated correctly - // format of nonce is: - // base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) - assertTrue(Base64.isArrayByteBase64(nonce.getBytes())); - - String decodedNonce = new String(Base64.decodeBase64(nonce.getBytes())); - String[] nonceTokens = StringUtils.delimitedListToStringArray(decodedNonce, - ":"); - assertEquals(2, nonceTokens.length); - - String expectedNonceSignature = DigestUtils.md5Hex(nonceTokens[0] + ":" - + "key"); - assertEquals(expectedNonceSignature, nonceTokens[1]); - } } diff --git a/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterTests.java index 0f9fce2415..27a38da519 100644 --- a/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterTests.java @@ -58,7 +58,7 @@ import javax.servlet.ServletRequest; * @version $Id$ */ public class DigestProcessingFilterTests extends MockObjectTestCase { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static final String NC = "00000002"; private static final String CNONCE = "c822c727a648aba7"; @@ -72,13 +72,13 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { /** A standard valid nonce with a validity period of 60 seconds */ private static final String NONCE = generateNonce(60); - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ // private ApplicationContext ctx; private DigestProcessingFilter filter; private MockHttpServletRequest request; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public DigestProcessingFilterTests() {} @@ -86,28 +86,23 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private String createAuthorizationHeader(String username, String realm, - String nonce, String uri, String responseDigest, String qop, String nc, - String cnonce) { - return "Digest username=\"" + username + "\", realm=\"" + realm - + "\", nonce=\"" + nonce + "\", uri=\"" + uri + "\", response=\"" - + responseDigest + "\", qop=" + qop + ", nc=" + nc + ", cnonce=\"" - + cnonce + "\""; + private String createAuthorizationHeader(String username, String realm, String nonce, String uri, + String responseDigest, String qop, String nc, String cnonce) { + return "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + uri + + "\", response=\"" + responseDigest + "\", qop=" + qop + ", nc=" + nc + ", cnonce=\"" + cnonce + "\""; } - private MockHttpServletResponse executeFilterInContainerSimulator( - Filter filter, ServletRequest request, boolean expectChainToProceed) - throws ServletException, IOException { + private MockHttpServletResponse executeFilterInContainerSimulator(Filter filter, ServletRequest request, + boolean expectChainToProceed) throws ServletException, IOException { filter.init(new MockFilterConfig()); MockHttpServletResponse response = new MockHttpServletResponse(); Mock mockChain = mock(FilterChain.class); FilterChain chain = (FilterChain) mockChain.proxy(); - mockChain.expects(expectChainToProceed ? once() : never()) - .method("doFilter"); + mockChain.expects(expectChainToProceed ? once() : never()).method("doFilter"); filter.doFilter(request, response, chain); filter.destroy(); @@ -117,8 +112,7 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { private static String generateNonce(int validitySeconds) { long expiryTime = System.currentTimeMillis() + (validitySeconds * 1000); - String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" - + KEY)); + String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" + KEY)); String nonceValue = expiryTime + ":" + signatureValue; return new String(Base64.encodeBase64(nonceValue.getBytes())); @@ -160,12 +154,10 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { DigestProcessingFilter filter = new DigestProcessingFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -174,39 +166,32 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { DigestProcessingFilter filter = new DigestProcessingFilter(); try { - filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain()); + filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } public void testExpiredNonceReturnsForbiddenWithStaleHeader() throws Exception { String nonce = generateNonce(0); - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, nonce, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, nonce, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); Thread.sleep(1000); // ensures token expired - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); - String header = response.getHeader("WWW-Authenticate").toString() - .substring(7); + String header = response.getHeader("WWW-Authenticate").toString().substring(7); String[] headerEntries = StringUtils.commaDelimitedListToStringArray(header); - Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, - "=", "\""); + Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\""); assertEquals("true", headerMap.get("stale")); } @@ -235,11 +220,9 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { throws Exception { String token = "NOT_A_VALID_TOKEN_AS_MISSING_COLON"; - request.addHeader("Authorization", - "Digest " + new String(Base64.encodeBase64(token.getBytes()))); + request.addHeader("Authorization", "Digest " + new String(Base64.encodeBase64(token.getBytes()))); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertEquals(401, response.getStatus()); assertNull(SecurityContextHolder.getContext().getAuthentication()); @@ -248,8 +231,7 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testMalformedHeaderReturnsForbidden() throws Exception { request.addHeader("Authorization", "Digest scsdcsdc"); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -259,16 +241,13 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { throws Exception { String nonce = "NOT_BASE_64_ENCODED"; - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, nonce, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, nonce, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -276,18 +255,14 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testNonceWithIncorrectSignatureForNumericFieldReturnsForbidden() throws Exception { - String nonce = new String(Base64.encodeBase64( - "123456:incorrectStringPassword".getBytes())); - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, nonce, NC, - CNONCE); + String nonce = new String(Base64.encodeBase64("123456:incorrectStringPassword".getBytes())); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, nonce, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -295,18 +270,14 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testNonceWithNonNumericFirstElementReturnsForbidden() throws Exception { - String nonce = new String(Base64.encodeBase64( - "hello:ignoredSecondElement".getBytes())); - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, nonce, NC, - CNONCE); + String nonce = new String(Base64.encodeBase64("hello:ignoredSecondElement".getBytes())); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, nonce, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -314,18 +285,14 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testNonceWithoutTwoColonSeparatedElementsReturnsForbidden() throws Exception { - String nonce = new String(Base64.encodeBase64( - "a base 64 string without a colon".getBytes())); - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, nonce, NC, - CNONCE); + String nonce = new String(Base64.encodeBase64("a base 64 string without a colon".getBytes())); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, nonce, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -333,40 +300,33 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testNormalOperationWhenPasswordIsAlreadyEncoded() throws Exception { - String encodedPassword = DigestProcessingFilter.encodePasswordInA1Format(USERNAME, - REALM, PASSWORD); - String responseDigest = DigestProcessingFilter.generateDigest(true, - USERNAME, REALM, encodedPassword, "GET", REQUEST_URI, QOP, - NONCE, NC, CNONCE); + String encodedPassword = DigestProcessingFilter.encodePasswordInA1Format(USERNAME, REALM, PASSWORD); + String responseDigest = DigestProcessingFilter.generateDigest(true, USERNAME, REALM, encodedPassword, "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); executeFilterInContainerSimulator(filter, request, true); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(USERNAME, - ((UserDetails) SecurityContextHolder.getContext().getAuthentication() - .getPrincipal()).getUsername()); + ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()); } public void testNormalOperationWhenPasswordNotAlreadyEncoded() throws Exception { - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, NONCE, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); executeFilterInContainerSimulator(filter, request, true); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(USERNAME, - ((UserDetails) SecurityContextHolder.getContext().getAuthentication() - .getPrincipal()).getUsername()); + ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()); } public void testOtherAuthorizationSchemeIsIgnored() @@ -386,8 +346,7 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A DigestProcessingFilterEntryPoint is required", - expected.getMessage()); + assertEquals("A DigestProcessingFilterEntryPoint is required", expected.getMessage()); } } @@ -399,37 +358,31 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { filter.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("A UserDetailsService is required", - expected.getMessage()); + assertEquals("A UserDetailsService is required", expected.getMessage()); } } public void testSuccessLoginThenFailureLoginResultsInSessionLosingToken() throws Exception { - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, NONCE, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); executeFilterInContainerSimulator(filter, request, true); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); // Now retry, giving an invalid nonce - responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, - REALM, "WRONG_PASSWORD", "GET", REQUEST_URI, QOP, NONCE, NC, - CNONCE); + responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, "WRONG_PASSWORD", "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request = new MockHttpServletRequest(); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); // Check we lost our previous authentication assertNull(SecurityContextHolder.getContext().getAuthentication()); @@ -440,16 +393,13 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { throws Exception { String cnonce = "NOT_SAME_AS_USED_FOR_DIGEST_COMPUTATION"; - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, PASSWORD, "GET", REQUEST_URI, QOP, NONCE, NC, - "DIFFERENT_CNONCE"); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", + REQUEST_URI, QOP, NONCE, NC, "DIFFERENT_CNONCE"); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, cnonce)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, cnonce)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -457,16 +407,13 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testWrongDigestReturnsForbidden() throws Exception { String password = "WRONG_PASSWORD"; - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, REALM, password, "GET", REQUEST_URI, QOP, NONCE, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, password, "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); @@ -474,32 +421,26 @@ public class DigestProcessingFilterTests extends MockObjectTestCase { public void testWrongRealmReturnsForbidden() throws Exception { String realm = "WRONG_REALM"; - String responseDigest = DigestProcessingFilter.generateDigest(false, - USERNAME, realm, PASSWORD, "GET", REQUEST_URI, QOP, NONCE, NC, - CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, realm, PASSWORD, "GET", + REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, realm, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, realm, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); } public void testWrongUsernameReturnsForbidden() throws Exception { - String responseDigest = DigestProcessingFilter.generateDigest(false, - "NOT_A_KNOWN_USER", REALM, PASSWORD, "GET", REQUEST_URI, QOP, - NONCE, NC, CNONCE); + String responseDigest = DigestProcessingFilter.generateDigest(false, "NOT_A_KNOWN_USER", REALM, PASSWORD, + "GET", REQUEST_URI, QOP, NONCE, NC, CNONCE); request.addHeader("Authorization", - createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, - responseDigest, QOP, NC, CNONCE)); + createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE)); - MockHttpServletResponse response = executeFilterInContainerSimulator(filter, - request, false); + MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false); assertNull(SecurityContextHolder.getContext().getAuthentication()); assertEquals(401, response.getStatus()); diff --git a/core/src/test/java/org/acegisecurity/ui/rememberme/NullRememberMeServicesTests.java b/core/src/test/java/org/acegisecurity/ui/rememberme/NullRememberMeServicesTests.java index 58dd19d230..e493166729 100644 --- a/core/src/test/java/org/acegisecurity/ui/rememberme/NullRememberMeServicesTests.java +++ b/core/src/test/java/org/acegisecurity/ui/rememberme/NullRememberMeServicesTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class NullRememberMeServicesTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public NullRememberMeServicesTests() { super(); @@ -35,17 +35,17 @@ public class NullRememberMeServicesTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(NullRememberMeServicesTests.class); } public void testAlwaysReturnsNull() { - NullRememberMeServices services = new NullRememberMeServices(); - assertNull(services.autoLogin(null,null)); - services.loginFail(null,null); - services.loginSuccess(null,null,null); - assertTrue(true); + NullRememberMeServices services = new NullRememberMeServices(); + assertNull(services.autoLogin(null, null)); + services.loginFail(null, null); + services.loginSuccess(null, null, null); + assertTrue(true); } } diff --git a/core/src/test/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilterTests.java index dd7e074529..8f2935340b 100644 --- a/core/src/test/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/rememberme/RememberMeProcessingFilterTests.java @@ -49,7 +49,7 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class RememberMeProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public RememberMeProcessingFilterTests() { super(); @@ -59,11 +59,11 @@ public class RememberMeProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { filter.init(filterConfig); filter.doFilter(request, response, filterChain); filter.destroy(); @@ -107,13 +107,11 @@ public class RememberMeProcessingFilterTests extends TestCase { filter.setAuthenticationManager(new MockAuthenticationManager()); // check default is NullRememberMeServices - assertEquals(NullRememberMeServices.class, - filter.getRememberMeServices().getClass()); + assertEquals(NullRememberMeServices.class, filter.getRememberMeServices().getClass()); // check getter/setter filter.setRememberMeServices(new TokenBasedRememberMeServices()); - assertEquals(TokenBasedRememberMeServices.class, - filter.getRememberMeServices().getClass()); + assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass()); // check detects if made null filter.setRememberMeServices(null); @@ -132,12 +130,10 @@ public class RememberMeProcessingFilterTests extends TestCase { filter.setAuthenticationManager(new MockAuthenticationManager()); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -152,22 +148,19 @@ public class RememberMeProcessingFilterTests extends TestCase { filter.doFilter(request, null, new MockFilterChain()); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } public void testOperationWhenAuthenticationExistsInContextHolder() throws Exception { // Put an Authentication object into the SecurityContextHolder - Authentication originalAuth = new TestingAuthenticationToken("user", - "password", + Authentication originalAuth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")}); SecurityContextHolder.getContext().setAuthentication(originalAuth); // Setup our filter correctly - Authentication remembered = new TestingAuthenticationToken("remembered", - "password", + Authentication remembered = new TestingAuthenticationToken("remembered", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")}); RememberMeProcessingFilter filter = new RememberMeProcessingFilter(); filter.setAuthenticationManager(new MockAuthenticationManager()); @@ -177,18 +170,16 @@ public class RememberMeProcessingFilterTests extends TestCase { // Test MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("x"); - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, new MockHttpServletResponse(), new MockFilterChain(true)); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(), + new MockFilterChain(true)); // Ensure filter didn't change our original object - assertEquals(originalAuth, - SecurityContextHolder.getContext().getAuthentication()); + assertEquals(originalAuth, SecurityContextHolder.getContext().getAuthentication()); } public void testOperationWhenNoAuthenticationInContextHolder() throws Exception { - Authentication remembered = new TestingAuthenticationToken("remembered", - "password", + Authentication remembered = new TestingAuthenticationToken("remembered", "password", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")}); RememberMeProcessingFilter filter = new RememberMeProcessingFilter(); filter.setAuthenticationManager(new MockAuthenticationManager()); @@ -197,15 +188,14 @@ public class RememberMeProcessingFilterTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("x"); - executeFilterInContainerSimulator(new MockFilterConfig(), filter, - request, new MockHttpServletResponse(), new MockFilterChain(true)); + executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(), + new MockFilterChain(true)); // Ensure filter setup with our remembered authentication object - assertEquals(remembered, - SecurityContextHolder.getContext().getAuthentication()); + assertEquals(remembered, SecurityContextHolder.getContext().getAuthentication()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private boolean expectToProceed; @@ -235,16 +225,13 @@ public class RememberMeProcessingFilterTests extends TestCase { this.authToReturn = authToReturn; } - public Authentication autoLogin(HttpServletRequest request, - HttpServletResponse response) { + public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) { return authToReturn; } - public void loginFail(HttpServletRequest request, - HttpServletResponse response) {} + public void loginFail(HttpServletRequest request, HttpServletResponse response) {} - public void loginSuccess(HttpServletRequest request, - HttpServletResponse response, + public void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {} } } diff --git a/core/src/test/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServicesTests.java b/core/src/test/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServicesTests.java index fe7baf34f4..41a2ef114a 100644 --- a/core/src/test/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServicesTests.java +++ b/core/src/test/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServicesTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,11 @@ import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; - import org.acegisecurity.providers.TestingAuthenticationToken; -import org.acegisecurity.userdetails.UserDetailsService; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; import org.apache.commons.codec.binary.Base64; @@ -33,24 +33,24 @@ import org.apache.commons.codec.digest.DigestUtils; import org.springframework.dao.DataAccessException; -import org.springframework.util.StringUtils; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.util.StringUtils; + import java.util.Date; import javax.servlet.http.Cookie; /** - * Tests {@link - * org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices}. + * Tests {@link org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices}. * * @author Ben Alex * @version $Id$ */ public class TokenBasedRememberMeServicesTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public TokenBasedRememberMeServicesTests() { super(); @@ -60,7 +60,30 @@ public class TokenBasedRememberMeServicesTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private long determineExpiryTimeFromBased64EncodedToken(String validToken) { + String cookieAsPlainText = new String(Base64.decodeBase64(validToken.getBytes())); + String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":"); + + if (cookieTokens.length == 3) { + try { + return new Long(cookieTokens[1]).longValue(); + } catch (NumberFormatException nfe) {} + } + + return -1; + } + + private String generateCorrectCookieContentForToken(long expiryTime, String username, String password, String key) { + // format is: + // username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key) + String signatureValue = new String(DigestUtils.md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)); + String tokenValue = username + ":" + expiryTime + ":" + signatureValue; + String tokenValueBase64 = new String(Base64.encodeBase64(tokenValue.getBytes())); + + return tokenValueBase64; + } public static void main(String[] args) { junit.textui.TestRunner.run(TokenBasedRememberMeServicesTests.class); @@ -75,6 +98,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("dc"); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -95,6 +119,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { Cookie cookie = new Cookie("unrelated_cookie", "foobar"); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -106,8 +131,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { } public void testAutoLoginIfExpired() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -116,10 +140,10 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.afterPropertiesSet(); Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - generateCorrectCookieContentForToken(System.currentTimeMillis() - - 1000000, "someone", "password", "key")); + generateCorrectCookieContentForToken(System.currentTimeMillis() - 1000000, "someone", "password", "key")); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -133,8 +157,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { public void testAutoLoginIfMissingThreeTokensInCookieValue() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -146,6 +169,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { new String(Base64.encodeBase64("x".getBytes()))); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -158,8 +182,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { } public void testAutoLoginIfNotBase64Encoded() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -171,6 +194,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { "NOT_BASE_64_ENCODED"); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -184,8 +208,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { public void testAutoLoginIfSignatureBlocksDoesNotMatchExpectedValue() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -194,10 +217,11 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.afterPropertiesSet(); Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - generateCorrectCookieContentForToken(System.currentTimeMillis() - + 1000000, "someone", "password", "WRONG_KEY")); + generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", + "WRONG_KEY")); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -211,8 +235,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { public void testAutoLoginIfTokenDoesNotContainANumberInCookieValue() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -221,10 +244,10 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.afterPropertiesSet(); Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - new String(Base64.encodeBase64( - "username:NOT_A_NUMBER:signature".getBytes()))); + new String(Base64.encodeBase64("username:NOT_A_NUMBER:signature".getBytes()))); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -243,10 +266,10 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.afterPropertiesSet(); Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - generateCorrectCookieContentForToken(System.currentTimeMillis() - + 1000000, "someone", "password", "key")); + generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key")); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -259,8 +282,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { } public void testAutoLoginWithValidToken() throws Exception { - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); @@ -269,10 +291,10 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.afterPropertiesSet(); Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, - generateCorrectCookieContentForToken(System.currentTimeMillis() - + 1000000, "someone", "password", "key")); + generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key")); MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(new Cookie[] {cookie}); + MockHttpServletResponse response = new MockHttpServletResponse(); Authentication result = services.autoLogin(request, response); @@ -292,8 +314,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { services.setKey("d"); assertEquals("d", services.getKey()); - assertEquals(TokenBasedRememberMeServices.DEFAULT_PARAMETER, - services.getParameter()); + assertEquals(TokenBasedRememberMeServices.DEFAULT_PARAMETER, services.getParameter()); services.setParameter("some_param"); assertEquals("some_param", services.getParameter()); @@ -305,6 +326,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("fv"); + MockHttpServletResponse response = new MockHttpServletResponse(); services.loginFail(request, response); @@ -317,8 +339,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("d"); - request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, - "false"); + request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, "false"); MockHttpServletResponse response = new MockHttpServletResponse(); services.loginSuccess(request, response, @@ -344,9 +365,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { assertNotNull(cookie); assertEquals(60 * 60 * 24 * 365 * 5, cookie.getMaxAge()); // 5 years assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes())); - assertTrue(new Date().before( - new Date(determineExpiryTimeFromBased64EncodedToken( - cookie.getValue())))); + assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue())))); } public void testLoginSuccessNormalWithUserDetailsBasedPrincipal() { @@ -356,8 +375,7 @@ public class TokenBasedRememberMeServicesTests extends TestCase { request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, "true"); MockHttpServletResponse response = new MockHttpServletResponse(); - UserDetails user = new User("someone", "password", true, true, true, - true, + UserDetails user = new User("someone", "password", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}); services.loginSuccess(request, response, new TestingAuthenticationToken(user, "ignored", @@ -367,47 +385,16 @@ public class TokenBasedRememberMeServicesTests extends TestCase { assertNotNull(cookie); assertEquals(60 * 60 * 24 * 365 * 5, cookie.getMaxAge()); // 5 years assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes())); - assertTrue(new Date().before( - new Date(determineExpiryTimeFromBased64EncodedToken( - cookie.getValue())))); + assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue())))); } - private long determineExpiryTimeFromBased64EncodedToken(String validToken) { - String cookieAsPlainText = new String(Base64.decodeBase64( - validToken.getBytes())); - String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, - ":"); - - if (cookieTokens.length == 3) { - try { - return new Long(cookieTokens[1]).longValue(); - } catch (NumberFormatException nfe) {} - } - - return -1; - } - - private String generateCorrectCookieContentForToken(long expiryTime, - String username, String password, String key) { - // format is: - // username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key) - String signatureValue = new String(DigestUtils.md5Hex(username + ":" - + expiryTime + ":" + password + ":" + key)); - String tokenValue = username + ":" + expiryTime + ":" + signatureValue; - String tokenValueBase64 = new String(Base64.encodeBase64( - tokenValue.getBytes())); - - return tokenValueBase64; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAuthenticationDao implements UserDetailsService { private UserDetails toReturn; private boolean throwException; - public MockAuthenticationDao(UserDetails toReturn, - boolean throwException) { + public MockAuthenticationDao(UserDetails toReturn, boolean throwException) { this.toReturn = toReturn; this.throwException = throwException; } diff --git a/core/src/test/java/org/acegisecurity/ui/session/HttpSessionEventPublisherTests.java b/core/src/test/java/org/acegisecurity/ui/session/HttpSessionEventPublisherTests.java index b6debd5a28..7a50455014 100644 --- a/core/src/test/java/org/acegisecurity/ui/session/HttpSessionEventPublisherTests.java +++ b/core/src/test/java/org/acegisecurity/ui/session/HttpSessionEventPublisherTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,9 @@ package org.acegisecurity.ui.session; import junit.framework.TestCase; -import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockHttpSession; +import org.springframework.mock.web.MockServletContext; + import org.springframework.web.context.support.StaticWebApplicationContext; import javax.servlet.ServletContextEvent; @@ -32,7 +33,28 @@ import javax.servlet.http.HttpSessionEvent; * @version $Id$ */ public class HttpSessionEventPublisherTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void testDelayedContextInitializationSucceeds() { + HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); + MockServletContext servletContext = new MockServletContext(); + + // shouldn't fail, even with null context + publisher.contextInitialized(new ServletContextEvent(servletContext)); + + StaticWebApplicationContext context = new StaticWebApplicationContext(); + context.setServletContext(servletContext); + } + + public void testGetContextThrowsExceptionIfContextNotSet() { + HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); + publisher.contextInitialized(new ServletContextEvent(new MockServletContext())); + + try { + publisher.getContext(); + fail("IllegalStateException expected when no context set"); + } catch (IllegalStateException expected) {} + } /** * It's not that complicated so we'll just run it straight through here. @@ -43,8 +65,7 @@ public class HttpSessionEventPublisherTests extends TestCase { StaticWebApplicationContext context = new StaticWebApplicationContext(); MockServletContext servletContext = new MockServletContext(); - servletContext.setAttribute(StaticWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, - context); + servletContext.setAttribute(StaticWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context); context.setServletContext(servletContext); context.registerSingleton("listener", TestListener.class, null); @@ -72,30 +93,4 @@ public class HttpSessionEventPublisherTests extends TestCase { publisher.contextDestroyed(new ServletContextEvent(servletContext)); } - - - public void testDelayedContextInitializationSucceeds() { - HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); - MockServletContext servletContext = new MockServletContext(); - - // shouldn't fail, even with null context - publisher.contextInitialized(new ServletContextEvent(servletContext)); - - - StaticWebApplicationContext context = new StaticWebApplicationContext(); - context.setServletContext(servletContext); - - - } - - public void testGetContextThrowsExceptionIfContextNotSet() { - HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); - publisher.contextInitialized(new ServletContextEvent(new MockServletContext())); - - try { - publisher.getContext(); - fail("IllegalStateException expected when no context set"); - } catch (IllegalStateException expected) { - } - } } diff --git a/core/src/test/java/org/acegisecurity/ui/session/TestListener.java b/core/src/test/java/org/acegisecurity/ui/session/TestListener.java index 9d825d8f8e..e0e70e6060 100644 --- a/core/src/test/java/org/acegisecurity/ui/session/TestListener.java +++ b/core/src/test/java/org/acegisecurity/ui/session/TestListener.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,25 +25,17 @@ import org.springframework.context.ApplicationListener; * @author Ray Krueger */ public class TestListener implements ApplicationListener { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private HttpSessionCreatedEvent createdEvent; private HttpSessionDestroyedEvent destroyedEvent; - //~ Methods ================================================================ - - public void setCreatedEvent(HttpSessionCreatedEvent createdEvent) { - this.createdEvent = createdEvent; - } + //~ Methods ======================================================================================================== public HttpSessionCreatedEvent getCreatedEvent() { return createdEvent; } - public void setDestroyedEvent(HttpSessionDestroyedEvent destroyedEvent) { - this.destroyedEvent = destroyedEvent; - } - public HttpSessionDestroyedEvent getDestroyedEvent() { return destroyedEvent; } @@ -55,4 +47,12 @@ public class TestListener implements ApplicationListener { destroyedEvent = (HttpSessionDestroyedEvent) event; } } + + public void setCreatedEvent(HttpSessionCreatedEvent createdEvent) { + this.createdEvent = createdEvent; + } + + public void setDestroyedEvent(HttpSessionDestroyedEvent destroyedEvent) { + this.destroyedEvent = destroyedEvent; + } } diff --git a/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java index 5467cadf4d..48c5ca43e5 100644 --- a/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,14 +24,20 @@ import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.DisabledException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.acegisecurity.util.MockFilterChain; + import org.springframework.dao.DataAccessException; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -43,7 +49,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class SwitchUserProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SwitchUserProcessingFilterTests() { super(); @@ -53,25 +59,32 @@ public class SwitchUserProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private MockHttpServletRequest createMockSwitchRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setScheme("http"); + request.setServerName("localhost"); + request.setRequestURI("/j_acegi_switch_user"); + + return request; } public static void main(String[] args) { junit.textui.TestRunner.run(SwitchUserProcessingFilterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAttemptSwitchToUnknownUser() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "user-that-doesnt-exist"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "user-that-doesnt-exist"); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setUserDetailsService(new MockAuthenticationDaoUserJackLord()); @@ -86,15 +99,13 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testAttemptSwitchToUserThatIsDisabled() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); // this user is disabled - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "mcgarrett"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "mcgarrett"); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setUserDetailsService(new MockAuthenticationDaoUserJackLord()); @@ -111,15 +122,13 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testAttemptSwitchToUserWithAccountExpired() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); // this user is disabled - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "wofat"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "wofat"); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setUserDetailsService(new MockAuthenticationDaoUserJackLord()); @@ -136,15 +145,13 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testAttemptSwitchToUserWithExpiredCredentials() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); // this user is disabled - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "steve"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "steve"); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setUserDetailsService(new MockAuthenticationDaoUserJackLord()); @@ -160,13 +167,11 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testAttemptSwitchUser() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "jacklord"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "jacklord"); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setUserDetailsService(new MockAuthenticationDaoUserJackLord()); @@ -208,24 +213,22 @@ public class SwitchUserProcessingFilterTests extends TestCase { SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); filter.setSwitchUserUrl("/j_acegi_switch_user"); - request.setRequestURI( - "/webapp/j_acegi_switch_user;jsessionid=8JHDUD723J8"); + request.setRequestURI("/webapp/j_acegi_switch_user;jsessionid=8JHDUD723J8"); assertTrue(filter.requiresSwitchUser(request)); } public void testExitRequestUserJackLordToDano() throws Exception { // original user - GrantedAuthority[] auths = {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}; - UsernamePasswordAuthenticationToken source = new UsernamePasswordAuthenticationToken("dano", - "hawaii50", auths); + GrantedAuthority[] auths = {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}; + UsernamePasswordAuthenticationToken source = new UsernamePasswordAuthenticationToken("dano", "hawaii50", auths); // set current user (Admin) - GrantedAuthority[] adminAuths = {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO"), new SwitchUserGrantedAuthority("PREVIOUS_ADMINISTRATOR", - source)}; - UsernamePasswordAuthenticationToken admin = new UsernamePasswordAuthenticationToken("jacklord", - "hawaii50", adminAuths); + GrantedAuthority[] adminAuths = { + new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"), + new SwitchUserGrantedAuthority("PREVIOUS_ADMINISTRATOR", source) + }; + UsernamePasswordAuthenticationToken admin = new UsernamePasswordAuthenticationToken("jacklord", "hawaii50", + adminAuths); SecurityContextHolder.getContext().setAuthentication(admin); @@ -247,8 +250,7 @@ public class SwitchUserProcessingFilterTests extends TestCase { filter.doFilter(request, response, chain); // check current user, should be back to original user (dano) - Authentication targetAuth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication targetAuth = SecurityContextHolder.getContext().getAuthentication(); assertNotNull(targetAuth); assertEquals("dano", targetAuth.getPrincipal()); } @@ -281,13 +283,11 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testRedirectToTargetUrl() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = createMockSwitchRequest(); - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "jacklord"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "jacklord"); request.setRequestURI("/webapp/j_acegi_switch_user"); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -328,15 +328,13 @@ public class SwitchUserProcessingFilterTests extends TestCase { public void testSwitchRequestFromDanoToJackLord() throws Exception { // set current user - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", - "hawaii50"); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50"); SecurityContextHolder.getContext().setAuthentication(auth); // http request MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("/webapp/j_acegi_switch_user"); - request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, - "jacklord"); + request.addParameter(SwitchUserProcessingFilter.ACEGI_SECURITY_SWITCH_USERNAME_KEY, "jacklord"); // http response MockHttpServletResponse response = new MockHttpServletResponse(); @@ -352,31 +350,17 @@ public class SwitchUserProcessingFilterTests extends TestCase { filter.doFilter(request, response, chain); // check current user - Authentication targetAuth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication targetAuth = SecurityContextHolder.getContext().getAuthentication(); assertNotNull(targetAuth); assertTrue(targetAuth.getPrincipal() instanceof UserDetails); - assertEquals("jacklord", ((User)targetAuth.getPrincipal()).getUsername()); + assertEquals("jacklord", ((User) targetAuth.getPrincipal()).getUsername()); } - private MockHttpServletRequest createMockSwitchRequest() { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setScheme("http"); - request.setServerName("localhost"); - request.setRequestURI("/j_acegi_switch_user"); - - return request; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAuthenticationDaoUserJackLord implements UserDetailsService { private String password = "hawaii50"; - public void setPassword(String password) { - this.password = password; - } - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { // jacklord, dano (active) @@ -385,24 +369,23 @@ public class SwitchUserProcessingFilterTests extends TestCase { // steve (credentials expired) if ("jacklord".equals(username) || "dano".equals(username)) { return new User(username, password, true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else if ("mcgarrett".equals(username)) { return new User(username, password, false, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else if ("wofat".equals(username)) { return new User(username, password, true, false, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else if ("steve".equals(username)) { return new User(username, password, true, true, false, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); } else { - throw new UsernameNotFoundException("Could not find: " - + username); + throw new UsernameNotFoundException("Could not find: " + username); } } + + public void setPassword(String password) { + this.password = password; + } } } diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java index 5c864cd34b..342a42bdc1 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java @@ -36,7 +36,7 @@ import java.util.Map; * @version $Id$ */ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationProcessingFilterEntryPointTests.class); @@ -120,22 +120,19 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response, null); - assertEquals("https://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); request.setServerPort(8080); response = new MockHttpServletResponse(); ep.setPortResolver(new MockPortResolver(8080, 8443)); ep.commence(request, response, null); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); // Now test an unusual custom HTTP:HTTPS is handled properly request.setServerPort(8888); response = new MockHttpServletResponse(); ep.commence(request, response, null); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); PortMapperImpl portMapper = new PortMapperImpl(); Map map = new HashMap(); @@ -152,8 +149,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response, null); - assertEquals("https://www.example.com:9999/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:9999/bigWebApp/hello", response.getRedirectedUrl()); } public void testHttpsOperationFromOriginalHttpsUrl() @@ -176,15 +172,13 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response, null); - assertEquals("https://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); request.setServerPort(8443); response = new MockHttpServletResponse(); ep.setPortResolver(new MockPortResolver(8080, 8443)); ep.commence(request, response, null); - assertEquals("https://www.example.com:8443/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl()); } public void testNormalOperation() throws Exception { @@ -206,8 +200,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { ep.afterPropertiesSet(); ep.commence(request, response, null); - assertEquals("http://www.example.com/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl()); } public void testOperationWhenHttpsRequestsButHttpsPortUnknown() @@ -233,7 +226,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { ep.commence(request, response, null); // Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to HTTP port mapping - assertEquals("http://www.example.com:8888/bigWebApp/hello", - response.getRedirectedUrl()); + assertEquals("http://www.example.com:8888/bigWebApp/hello", response.getRedirectedUrl()); } } diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterTests.java index e5d5d0d738..05b45b9796 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.MockAuthenticationManager; + import org.acegisecurity.ui.WebAuthenticationDetails; import org.springframework.mock.web.MockHttpServletRequest; @@ -31,7 +32,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class AuthenticationProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthenticationProcessingFilterTests() { super(); @@ -41,28 +42,25 @@ public class AuthenticationProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticationProcessingFilterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testGetters() { AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter(); - assertEquals("/j_acegi_security_check", - filter.getDefaultFilterProcessesUrl()); + assertEquals("/j_acegi_security_check", filter.getDefaultFilterProcessesUrl()); } public void testNormalOperation() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); - request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, - "marissa"); - request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, - "koala"); + request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, "marissa"); + request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, "koala"); MockAuthenticationManager authMgr = new MockAuthenticationManager(true); @@ -72,14 +70,12 @@ public class AuthenticationProcessingFilterTests extends TestCase { Authentication result = filter.attemptAuthentication(request); assertTrue(result != null); - assertEquals("127.0.0.1", - ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()); + assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()); } public void testNullPasswordHandledGracefully() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); - request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, - "marissa"); + request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, "marissa"); MockAuthenticationManager authMgr = new MockAuthenticationManager(true); @@ -93,8 +89,7 @@ public class AuthenticationProcessingFilterTests extends TestCase { public void testNullUsernameHandledGracefully() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); - request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, - "koala"); + request.addParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, "koala"); MockAuthenticationManager authMgr = new MockAuthenticationManager(true); diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilterTests.java index 5900e3044e..094555b547 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilterTests.java @@ -1,233 +1,230 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.ui.webapp; import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.MockAuthenticationManager; + import org.acegisecurity.ui.WebAuthenticationDetails; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; + /** * Tests SiteminderAuthenticationProcessingFilter. - * + * * @author Ben Alex * @author Scott McCrory - * @version CVS $Id: SiteminderAuthenticationProcessingFilterTests.java,v 1.1 - * 2005/09/25 22:48:33 smccrory Exp $ + * @version CVS $Id$ */ public class SiteminderAuthenticationProcessingFilterTests extends TestCase { + //~ Constructors =================================================================================================== - /** - * Basic constructor. - */ - public SiteminderAuthenticationProcessingFilterTests() { - super(); - } +/** + * Basic constructor. + */ + public SiteminderAuthenticationProcessingFilterTests() { + super(); + } - /** - * Argument constructor. - * - * @param arg0 - */ - public SiteminderAuthenticationProcessingFilterTests(String arg0) { - super(arg0); - } +/** + * Argument constructor. + * + * @param arg0 + */ + public SiteminderAuthenticationProcessingFilterTests(String arg0) { + super(arg0); + } - /** - * @see junit.framework.TestCase#setUp() - */ - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== - /** - * Runs the tests as a command-line program. - * - * @param args - */ - public static void main(String[] args) { - junit.textui.TestRunner - .run(SiteminderAuthenticationProcessingFilterTests.class); - } + /** + * Runs the tests as a command-line program. + * + * @param args + */ + public static void main(String[] args) { + junit.textui.TestRunner.run(SiteminderAuthenticationProcessingFilterTests.class); + } - /** - * Tests the class' getters. - */ - public void testAccessors() { + /** + * + * @see junit.framework.TestCase#setUp() + */ + public final void setUp() throws Exception { + super.setUp(); + } - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - - filter.setAlwaysUseDefaultTargetUrl(true); - assertTrue(filter.isAlwaysUseDefaultTargetUrl()); - - filter.setAuthenticationFailureUrl("foo"); - assertEquals("foo", filter.getAuthenticationFailureUrl()); - - filter.setContinueChainBeforeSuccessfulAuthentication(true); - assertTrue(filter.isContinueChainBeforeSuccessfulAuthentication()); - - filter.setDefaultTargetUrl("bar"); - assertEquals("bar", filter.getDefaultTargetUrl()); - - filter.setFilterProcessesUrl("foobar"); - assertEquals("foobar", filter.getFilterProcessesUrl()); - - filter.setFormPasswordParameterKey("passwordParamKey"); - assertEquals("passwordParamKey", filter.getFormPasswordParameterKey()); - - filter.setFormUsernameParameterKey("usernameParamKey"); - assertEquals("usernameParamKey", filter.getFormUsernameParameterKey()); - - filter.setSiteminderPasswordHeaderKey("passwordHeaderKey"); - assertEquals("passwordHeaderKey", filter.getSiteminderPasswordHeaderKey()); - - filter.setSiteminderUsernameHeaderKey("usernameHeaderKey"); - assertEquals("usernameHeaderKey", filter.getSiteminderUsernameHeaderKey()); + /** + * Tests the class' getters. + */ + public void testAccessors() { + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - } + filter.setAlwaysUseDefaultTargetUrl(true); + assertTrue(filter.isAlwaysUseDefaultTargetUrl()); - /** - * Tests normal form processing. - * - * @throws Exception - */ - public void testFormNormalOperation() throws Exception { + filter.setAuthenticationFailureUrl("foo"); + assertEquals("foo", filter.getAuthenticationFailureUrl()); - MockHttpServletRequest request = new MockHttpServletRequest(); - request - .addParameter( - SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, - "marissa"); - request - .addParameter( - SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, - "koala"); + filter.setContinueChainBeforeSuccessfulAuthentication(true); + assertTrue(filter.isContinueChainBeforeSuccessfulAuthentication()); - MockAuthenticationManager authMgr = new MockAuthenticationManager(true); + filter.setDefaultTargetUrl("bar"); + assertEquals("bar", filter.getDefaultTargetUrl()); - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - filter.setAuthenticationManager(authMgr); - filter.init(null); + filter.setFilterProcessesUrl("foobar"); + assertEquals("foobar", filter.getFilterProcessesUrl()); - Authentication result = filter.attemptAuthentication(request); - assertTrue(result != null); - assertEquals("127.0.0.1", ((WebAuthenticationDetails) result - .getDetails()).getRemoteAddress()); + filter.setFormPasswordParameterKey("passwordParamKey"); + assertEquals("passwordParamKey", filter.getFormPasswordParameterKey()); - } + filter.setFormUsernameParameterKey("usernameParamKey"); + assertEquals("usernameParamKey", filter.getFormUsernameParameterKey()); - /** - * Tests form null password handling. - * - * @throws Exception - */ - public void testFormNullPasswordHandledGracefully() throws Exception { + filter.setSiteminderPasswordHeaderKey("passwordHeaderKey"); + assertEquals("passwordHeaderKey", filter.getSiteminderPasswordHeaderKey()); - MockHttpServletRequest request = new MockHttpServletRequest(); - request - .addParameter( - SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, - "marissa"); + filter.setSiteminderUsernameHeaderKey("usernameHeaderKey"); + assertEquals("usernameHeaderKey", filter.getSiteminderUsernameHeaderKey()); + } - MockAuthenticationManager authMgr = new MockAuthenticationManager(true); + /** + * Tests normal form processing. + * + * @throws Exception + */ + public void testFormNormalOperation() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, "marissa"); + request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, "koala"); - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - filter.setAuthenticationManager(authMgr); - filter.init(null); + MockAuthenticationManager authMgr = new MockAuthenticationManager(true); - Authentication result = filter.attemptAuthentication(request); - assertTrue(result != null); + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authMgr); + filter.init(null); - } + Authentication result = filter.attemptAuthentication(request); + assertTrue(result != null); + assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()); + } - /** - * Tests the overridden testRequiresAuthentication method. - * - * @throws Exception - */ - public void testRequiresAuthentication() throws Exception { - - // Create a Siteminder-style request from an unauthenticated user for a strange URI - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - request.addHeader("SM_USER", "A123456"); + /** + * Tests form null password handling. + * + * @throws Exception + */ + public void testFormNullPasswordHandledGracefully() + throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, "marissa"); - // Create the Siteminder filter, set a mock authentication manager to automatically grant access - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - filter.setDefaultTargetUrl("/defaultTargetUri"); - MockAuthenticationManager authMgrThatGrantsAccess = new MockAuthenticationManager(true); - filter.setAuthenticationManager(authMgrThatGrantsAccess); + MockAuthenticationManager authMgr = new MockAuthenticationManager(true); - filter.setSiteminderUsernameHeaderKey("SM_USER"); - filter.setSiteminderPasswordHeaderKey("SM_USER"); - filter.init(null); - - // Requests for an unknown URL should NOT require (re)authentication - request.setRequestURI("http://an.unknown.url"); - boolean requiresAuthentication = filter.requiresAuthentication(request, response); - assertFalse(requiresAuthentication); + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authMgr); + filter.init(null); - // Requests for the filter processing URI SHOULD require (re)authentication - request.setRequestURI(request.getContextPath() + filter.getFilterProcessesUrl()); - requiresAuthentication = filter.requiresAuthentication(request, response); - assertTrue(requiresAuthentication); + Authentication result = filter.attemptAuthentication(request); + assertTrue(result != null); + } - // Requests for the default target URI SHOULD require (re)authentication - request.setRequestURI(request.getContextPath() + filter.getDefaultTargetUrl()); - requiresAuthentication = filter.requiresAuthentication(request, response); - assertTrue(requiresAuthentication); + /** + * Tests form null username handling. + * + * @throws Exception + */ + public void testFormNullUsernameHandledGracefully() + throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, "koala"); - } + MockAuthenticationManager authMgr = new MockAuthenticationManager(true); - /** - * Tests form null username handling. - * - * @throws Exception - */ - public void testFormNullUsernameHandledGracefully() throws Exception { + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authMgr); + filter.init(null); - MockHttpServletRequest request = new MockHttpServletRequest(); - request - .addParameter( - SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, - "koala"); + Authentication result = filter.attemptAuthentication(request); + assertTrue(result != null); + } - MockAuthenticationManager authMgr = new MockAuthenticationManager(true); + /** + * Tests the overridden testRequiresAuthentication method. + * + * @throws Exception + */ + public void testRequiresAuthentication() throws Exception { + // Create a Siteminder-style request from an unauthenticated user for a strange URI + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - filter.setAuthenticationManager(authMgr); - filter.init(null); + request.addHeader("SM_USER", "A123456"); - Authentication result = filter.attemptAuthentication(request); - assertTrue(result != null); + // Create the Siteminder filter, set a mock authentication manager to automatically grant access + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); + filter.setDefaultTargetUrl("/defaultTargetUri"); - } + MockAuthenticationManager authMgrThatGrantsAccess = new MockAuthenticationManager(true); + filter.setAuthenticationManager(authMgrThatGrantsAccess); - /** - * Tests normal Siteminder header processing. - * - * @throws Exception - */ - public void testSiteminderNormalOperation() throws Exception { + filter.setSiteminderUsernameHeaderKey("SM_USER"); + filter.setSiteminderPasswordHeaderKey("SM_USER"); + filter.init(null); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("SM_USER", "A123456"); + // Requests for an unknown URL should NOT require (re)authentication + request.setRequestURI("http://an.unknown.url"); - MockAuthenticationManager authMgr = new MockAuthenticationManager(true); + boolean requiresAuthentication = filter.requiresAuthentication(request, response); + assertFalse(requiresAuthentication); - SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); - filter.setAuthenticationManager(authMgr); - filter.setSiteminderUsernameHeaderKey("SM_USER"); - filter.setSiteminderPasswordHeaderKey("SM_USER"); - filter.init(null); + // Requests for the filter processing URI SHOULD require (re)authentication + request.setRequestURI(request.getContextPath() + filter.getFilterProcessesUrl()); + requiresAuthentication = filter.requiresAuthentication(request, response); + assertTrue(requiresAuthentication); - Authentication result = filter.attemptAuthentication(request); - assertTrue(result != null); - assertEquals("127.0.0.1", ((WebAuthenticationDetails) result - .getDetails()).getRemoteAddress()); + // Requests for the default target URI SHOULD require (re)authentication + request.setRequestURI(request.getContextPath() + filter.getDefaultTargetUrl()); + requiresAuthentication = filter.requiresAuthentication(request, response); + assertTrue(requiresAuthentication); + } - } + /** + * Tests normal Siteminder header processing. + * + * @throws Exception + */ + public void testSiteminderNormalOperation() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("SM_USER", "A123456"); + MockAuthenticationManager authMgr = new MockAuthenticationManager(true); + + SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authMgr); + filter.setSiteminderUsernameHeaderKey("SM_USER"); + filter.setSiteminderPasswordHeaderKey("SM_USER"); + filter.init(null); + + Authentication result = filter.attemptAuthentication(request); + assertTrue(result != null); + assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()); + } } diff --git a/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPointTests.java index 5df19ae68e..cfc564614b 100644 --- a/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPointTests.java @@ -1,8 +1,24 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.ui.x509; import junit.framework.TestCase; import org.acegisecurity.BadCredentialsException; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -16,7 +32,7 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class X509ProcessingFilterEntryPointTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public X509ProcessingFilterEntryPointTests() { super(); @@ -26,7 +42,7 @@ public class X509ProcessingFilterEntryPointTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public final void setUp() throws Exception { super.setUp(); @@ -39,6 +55,5 @@ public class X509ProcessingFilterEntryPointTests extends TestCase { entryPoint.commence(request, response, new BadCredentialsException("As thrown by security enforcement filter")); assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); - } } diff --git a/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterTests.java index 3a087cc2c6..d2e0214e76 100644 --- a/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/x509/X509ProcessingFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,14 @@ import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationManager; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.MockAuthenticationManager; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.x509.X509AuthenticationToken; import org.acegisecurity.providers.x509.X509TestUtils; + import org.acegisecurity.ui.AbstractProcessingFilter; + import org.acegisecurity.util.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; @@ -43,7 +47,7 @@ import javax.servlet.ServletException; * @version $Id$ */ public class X509ProcessingFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public X509ProcessingFilterTests() { super(); @@ -53,7 +57,7 @@ public class X509ProcessingFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public final void setUp() throws Exception { super.setUp(); @@ -77,12 +81,11 @@ public class X509ProcessingFilterTests extends TestCase { SecurityContextHolder.getContext().setAuthentication(null); filter.doFilter(request, response, chain); - Object lastException = request.getSession().getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY); + Object lastException = request.getSession() + .getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY); - assertNull("Authentication should be null", - SecurityContextHolder.getContext().getAuthentication()); - assertTrue("BadCredentialsException should have been thrown", - lastException instanceof BadCredentialsException); + assertNull("Authentication should be null", SecurityContextHolder.getContext().getAuthentication()); + assertTrue("BadCredentialsException should have been thrown", lastException instanceof BadCredentialsException); } public void testDoFilterWithNonHttpServletRequestDetected() @@ -90,12 +93,10 @@ public class X509ProcessingFilterTests extends TestCase { X509ProcessingFilter filter = new X509ProcessingFilter(); try { - filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain(false)); + filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain(false)); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletRequest", - expected.getMessage()); + assertEquals("Can only process HttpServletRequest", expected.getMessage()); } } @@ -104,12 +105,10 @@ public class X509ProcessingFilterTests extends TestCase { X509ProcessingFilter filter = new X509ProcessingFilter(); try { - filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain(false)); + filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain(false)); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Can only process HttpServletResponse", - expected.getMessage()); + assertEquals("Can only process HttpServletResponse", expected.getMessage()); } } @@ -133,8 +132,7 @@ public class X509ProcessingFilterTests extends TestCase { filter.doFilter(request, response, chain); filter.destroy(); - Authentication result = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication result = SecurityContextHolder.getContext().getAuthentication(); assertNull(result); } @@ -170,25 +168,21 @@ public class X509ProcessingFilterTests extends TestCase { filter.doFilter(request, response, chain); filter.destroy(); - Authentication result = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication result = SecurityContextHolder.getContext().getAuthentication(); assertNotNull(result); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== - private static class MockX509AuthenticationManager - implements AuthenticationManager { + private static class MockX509AuthenticationManager implements AuthenticationManager { public Authentication authenticate(Authentication a) { if (!(a instanceof X509AuthenticationToken)) { - TestCase.fail("Needed an X509Authentication token but found " - + a); + TestCase.fail("Needed an X509Authentication token but found " + a); } if (a.getCredentials() == null) { - throw new BadCredentialsException( - "Mock authentication manager rejecting null certificate"); + throw new BadCredentialsException("Mock authentication manager rejecting null certificate"); } return a; diff --git a/core/src/test/java/org/acegisecurity/userdetails/UserTests.java b/core/src/test/java/org/acegisecurity/userdetails/UserTests.java index 5f268bd1fe..85e8f0d5c9 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/UserTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/UserTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; @@ -30,7 +31,7 @@ import org.acegisecurity.userdetails.UserDetails; * @version $Id$ */ public class UserTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UserTests() { super(); @@ -40,20 +41,19 @@ public class UserTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(UserTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testEquals() { User user1 = new User("marissa", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertFalse(user1.equals(null)); assertFalse(user1.equals("A STRING")); @@ -62,39 +62,31 @@ public class UserTests extends TestCase { assertTrue(user1.equals( new User("marissa", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("DIFFERENT_USERNAME", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( - new User("marissa", "DIFFERENT_PASSWORD", true, true, true, - true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new User("marissa", "DIFFERENT_PASSWORD", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("marissa", "koala", false, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("marissa", "koala", true, false, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("marissa", "koala", true, true, false, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("marissa", "koala", true, true, true, false, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}))); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}))); assertFalse(user1.equals( new User("marissa", "koala", true, true, true, true, @@ -105,7 +97,7 @@ public class UserTests extends TestCase { Class clazz = User.class; try { - clazz.getDeclaredConstructor((Class[])null); + clazz.getDeclaredConstructor((Class[]) null); fail("Should have thrown NoSuchMethodException"); } catch (NoSuchMethodException expected) { assertTrue(true); @@ -115,34 +107,29 @@ public class UserTests extends TestCase { public void testNullValuesRejected() throws Exception { try { UserDetails user = new User(null, "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - UserDetails user = new User("marissa", null, true, true, true, - true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UserDetails user = new User("marissa", null, true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - UserDetails user = new User("marissa", "koala", true, true, true, - true, null); + UserDetails user = new User("marissa", "koala", true, true, true, true, null); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); } try { - UserDetails user = new User("marissa", "koala", true, true, true, - true, + UserDetails user = new User("marissa", "koala", true, true, true, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null}); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { @@ -154,9 +141,10 @@ public class UserTests extends TestCase { throws Exception { try { UserDetails user = new User(null, "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO"), null, new GrantedAuthorityImpl( - "ROLE_THREE")}); + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"), null, + new GrantedAuthorityImpl("ROLE_THREE") + }); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertTrue(true); @@ -165,23 +153,18 @@ public class UserTests extends TestCase { public void testUserGettersSetter() throws Exception { UserDetails user = new User("marissa", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertEquals("marissa", user.getUsername()); assertEquals("koala", user.getPassword()); assertTrue(user.isEnabled()); - assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), - user.getAuthorities()[0]); - assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), - user.getAuthorities()[1]); + assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), user.getAuthorities()[0]); + assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), user.getAuthorities()[1]); assertTrue(user.toString().indexOf("marissa") != -1); } public void testUserIsEnabled() throws Exception { - UserDetails user = new User("marissa", "koala", false, true, true, - true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UserDetails user = new User("marissa", "koala", false, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); assertTrue(!user.isEnabled()); } } diff --git a/core/src/test/java/org/acegisecurity/userdetails/jdbc/JdbcDaoTests.java b/core/src/test/java/org/acegisecurity/userdetails/jdbc/JdbcDaoTests.java index 6ee1c73392..e829f97b1f 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/jdbc/JdbcDaoTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/jdbc/JdbcDaoTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,20 @@ package org.acegisecurity.userdetails.jdbc; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashSet; - import junit.framework.TestCase; import org.acegisecurity.PopulatedDatabase; + import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; + import org.springframework.jdbc.object.MappingSqlQuery; +import java.sql.ResultSet; +import java.sql.SQLException; + +import java.util.HashSet; + /** * Tests {@link JdbcDaoImpl}. @@ -34,7 +37,7 @@ import org.springframework.jdbc.object.MappingSqlQuery; * @version $Id$ */ public class JdbcDaoTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public JdbcDaoTests() { super(); @@ -44,22 +47,41 @@ public class JdbcDaoTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(JdbcDaoTests.class); } + private JdbcDaoImpl makePopulatedJdbcDao() throws Exception { + JdbcDaoImpl dao = new JdbcDaoImpl(); + dao.setDataSource(PopulatedDatabase.getDataSource()); + dao.afterPropertiesSet(); + + return dao; + } + + private JdbcDaoImpl makePopulatedJdbcDaoWithRolePrefix() + throws Exception { + JdbcDaoImpl dao = new JdbcDaoImpl(); + dao.setDataSource(PopulatedDatabase.getDataSource()); + dao.setRolePrefix("ARBITRARY_PREFIX_"); + dao.afterPropertiesSet(); + + return dao; + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testCheckDaoAccessUserSuccess() throws Exception { JdbcDaoImpl dao = makePopulatedJdbcDao(); UserDetails user = dao.loadUserByUsername("marissa"); assertEquals("marissa", user.getUsername()); assertEquals("koala", user.getPassword()); assertTrue(user.isEnabled()); + HashSet authorities = new HashSet(2); authorities.add(user.getAuthorities()[0].getAuthority()); authorities.add(user.getAuthorities()[1].getAuthority()); @@ -127,6 +149,7 @@ public class JdbcDaoTests extends TestCase { UserDetails user = dao.loadUserByUsername("marissa"); assertEquals("marissa", user.getUsername()); assertEquals(2, user.getAuthorities().length); + HashSet authorities = new HashSet(2); authorities.add(user.getAuthorities()[0].getAuthority()); authorities.add(user.getAuthorities()[1].getAuthority()); @@ -157,25 +180,7 @@ public class JdbcDaoTests extends TestCase { } } - private JdbcDaoImpl makePopulatedJdbcDao() throws Exception { - JdbcDaoImpl dao = new JdbcDaoImpl(); - dao.setDataSource(PopulatedDatabase.getDataSource()); - dao.afterPropertiesSet(); - - return dao; - } - - private JdbcDaoImpl makePopulatedJdbcDaoWithRolePrefix() - throws Exception { - JdbcDaoImpl dao = new JdbcDaoImpl(); - dao.setDataSource(PopulatedDatabase.getDataSource()); - dao.setRolePrefix("ARBITRARY_PREFIX_"); - dao.afterPropertiesSet(); - - return dao; - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockMappingSqlQuery extends MappingSqlQuery { protected Object mapRow(ResultSet arg0, int arg1) diff --git a/core/src/test/java/org/acegisecurity/userdetails/memory/InMemoryDaoTests.java b/core/src/test/java/org/acegisecurity/userdetails/memory/InMemoryDaoTests.java index 760e3eb0df..8b7b5557c7 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/memory/InMemoryDaoTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/memory/InMemoryDaoTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import java.util.Properties; * @version $Id$ */ public class InMemoryDaoTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public InMemoryDaoTests() { super(); @@ -42,16 +42,23 @@ public class InMemoryDaoTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(InMemoryDaoTests.class); } + private UserMap makeUserMap() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText("marissa=koala,ROLE_ONE,ROLE_TWO,enabled\r\nscott=wombat,ROLE_ONE,ROLE_TWO,enabled"); + + return (UserMap) editor.getValue(); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testLookupFails() throws Exception { InMemoryDaoImpl dao = new InMemoryDaoImpl(); dao.setUserMap(makeUserMap()); @@ -120,12 +127,4 @@ public class InMemoryDaoTests extends TestCase { assertEquals("koala", dao.loadUserByUsername("marissa").getPassword()); assertEquals("wombat", dao.loadUserByUsername("scott").getPassword()); } - - private UserMap makeUserMap() { - UserMapEditor editor = new UserMapEditor(); - editor.setAsText( - "marissa=koala,ROLE_ONE,ROLE_TWO,enabled\r\nscott=wombat,ROLE_ONE,ROLE_TWO,enabled"); - - return (UserMap) editor.getValue(); - } } diff --git a/core/src/test/java/org/acegisecurity/userdetails/memory/UserAttributeEditorTests.java b/core/src/test/java/org/acegisecurity/userdetails/memory/UserAttributeEditorTests.java index d92e25e666..f392fb8403 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/memory/UserAttributeEditorTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/memory/UserAttributeEditorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,11 @@ package org.acegisecurity.userdetails.memory; +import junit.framework.TestCase; + import org.acegisecurity.userdetails.memory.UserAttribute; import org.acegisecurity.userdetails.memory.UserAttributeEditor; -import junit.framework.TestCase; - /** * Tests {@link UserAttributeEditor} and associated {@link UserAttribute}. @@ -28,7 +28,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class UserAttributeEditorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UserAttributeEditorTests() { super(); @@ -38,14 +38,25 @@ public class UserAttributeEditorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public static void main(String[] args) { + junit.textui.TestRunner.run(UserAttributeEditorTests.class); + } public final void setUp() throws Exception { super.setUp(); } - public static void main(String[] args) { - junit.textui.TestRunner.run(UserAttributeEditorTests.class); + public void testCorrectOperationWithTrailingSpaces() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("password ,ROLE_ONE,ROLE_TWO "); + + UserAttribute user = (UserAttribute) editor.getValue(); + assertEquals("password", user.getPassword()); + assertEquals(2, user.getAuthorities().length); + assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", user.getAuthorities()[1].getAuthority()); } public void testCorrectOperationWithoutEnabledDisabledKeyword() { @@ -126,15 +137,4 @@ public class UserAttributeEditorTests extends TestCase { UserAttribute user = (UserAttribute) editor.getValue(); assertTrue(user == null); } - - public void testCorrectOperationWithTrailingSpaces() { - UserAttributeEditor editor = new UserAttributeEditor(); - editor.setAsText("password ,ROLE_ONE,ROLE_TWO "); - - UserAttribute user = (UserAttribute) editor.getValue(); - assertEquals("password", user.getPassword()); - assertEquals(2, user.getAuthorities().length); - assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_TWO", user.getAuthorities()[1].getAuthority()); - } } diff --git a/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapEditorTests.java b/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapEditorTests.java index 5ff50965d9..68cdff5dd0 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapEditorTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapEditorTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,11 @@ package org.acegisecurity.userdetails.memory; +import junit.framework.TestCase; + import org.acegisecurity.userdetails.memory.UserMap; import org.acegisecurity.userdetails.memory.UserMapEditor; -import junit.framework.TestCase; - /** * Tests {@link UserMapEditor}. @@ -28,7 +28,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class UserMapEditorTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UserMapEditorTests() { super(); @@ -38,16 +38,16 @@ public class UserMapEditorTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(UserMapEditorTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testConvertedIntoUserSuccessfullyWhenDisabled() { UserMapEditor editor = new UserMapEditor(); editor.setAsText("marissa=koala,ROLE_ONE,ROLE_TWO,disabled"); @@ -63,10 +63,8 @@ public class UserMapEditorTests extends TestCase { UserMap map = (UserMap) editor.getValue(); assertEquals("marissa", map.getUser("marissa").getUsername()); assertEquals("koala", map.getUser("marissa").getPassword()); - assertEquals("ROLE_ONE", - map.getUser("marissa").getAuthorities()[0].getAuthority()); - assertEquals("ROLE_TWO", - map.getUser("marissa").getAuthorities()[1].getAuthority()); + assertEquals("ROLE_ONE", map.getUser("marissa").getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", map.getUser("marissa").getAuthorities()[1].getAuthority()); assertTrue(map.getUser("marissa").isEnabled()); } @@ -88,8 +86,7 @@ public class UserMapEditorTests extends TestCase { public void testMultiUserParsing() { UserMapEditor editor = new UserMapEditor(); - editor.setAsText( - "marissa=koala,ROLE_ONE,ROLE_TWO,enabled\r\nscott=wombat,ROLE_ONE,ROLE_TWO,enabled"); + editor.setAsText("marissa=koala,ROLE_ONE,ROLE_TWO,enabled\r\nscott=wombat,ROLE_ONE,ROLE_TWO,enabled"); UserMap map = (UserMap) editor.getValue(); assertEquals("marissa", map.getUser("marissa").getUsername()); diff --git a/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapTests.java b/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapTests.java index e985037f07..cd56b15f8f 100644 --- a/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapTests.java +++ b/core/src/test/java/org/acegisecurity/userdetails/memory/UserMapTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.userdetails.User; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; @@ -32,7 +33,7 @@ import org.acegisecurity.userdetails.memory.UserMap; * @version $Id$ */ public class UserMapTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UserMapTests() { super(); @@ -42,27 +43,23 @@ public class UserMapTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(UserMapTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAddAndRetrieveUser() { - UserDetails marissa = new User("marissa", "koala", true, true, true, - true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UserDetails marissa = new User("marissa", "koala", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); UserDetails scott = new User("scott", "wombat", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_THREE")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_THREE")}); UserDetails peter = new User("peter", "opal", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_FOUR")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_FOUR")}); UserMap map = new UserMap(); map.addUser(marissa); map.addUser(scott); @@ -87,10 +84,8 @@ public class UserMapTests extends TestCase { } public void testUnknownUserIsNotRetrieved() { - UserDetails marissa = new User("marissa", "koala", true, true, true, - true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); + UserDetails marissa = new User("marissa", "koala", true, true, true, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); UserMap map = new UserMap(); assertEquals(0, map.getUserCount()); map.addUser(marissa); diff --git a/core/src/test/java/org/acegisecurity/util/FilterChainProxyTests.java b/core/src/test/java/org/acegisecurity/util/FilterChainProxyTests.java index 738063e730..af1f5ee48b 100644 --- a/core/src/test/java/org/acegisecurity/util/FilterChainProxyTests.java +++ b/core/src/test/java/org/acegisecurity/util/FilterChainProxyTests.java @@ -41,7 +41,7 @@ import org.springframework.mock.web.MockHttpServletResponse; * @version $Id$ */ public class FilterChainProxyTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== // =========================================================== public FilterChainProxyTests() { @@ -52,7 +52,7 @@ public class FilterChainProxyTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== // ================================================================ public static void main(String[] args) { @@ -63,8 +63,7 @@ public class FilterChainProxyTests extends TestCase { throws Exception { FilterChainProxy filterChainProxy = new FilterChainProxy(); filterChainProxy.setApplicationContext(MockApplicationContext.getContext()); - filterChainProxy.setFilterInvocationDefinitionSource(new MockFilterInvocationDefinitionSource( - false, false)); + filterChainProxy.setFilterInvocationDefinitionSource(new MockFilterInvocationDefinitionSource(false, false)); try { filterChainProxy.afterPropertiesSet(); @@ -107,18 +106,14 @@ public class FilterChainProxyTests extends TestCase { filterChainProxy.afterPropertiesSet(); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("filterInvocationDefinitionSource must be specified", - expected.getMessage()); + assertEquals("filterInvocationDefinitionSource must be specified", expected.getMessage()); } } public void testDoNotFilter() throws Exception { - ApplicationContext appCtx = new ClassPathXmlApplicationContext( - "org/acegisecurity/util/filtertest-valid.xml"); - FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("filterChain", - FilterChainProxy.class); - MockFilter filter = (MockFilter) appCtx.getBean("mockFilter", - MockFilter.class); + ApplicationContext appCtx = new ClassPathXmlApplicationContext("org/acegisecurity/util/filtertest-valid.xml"); + FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("filterChain", FilterChainProxy.class); + MockFilter filter = (MockFilter) appCtx.getBean("mockFilter", MockFilter.class); MockHttpServletRequest request = new MockHttpServletRequest(); request.setServletPath("/do/not/filter/somefile.html"); @@ -134,20 +129,15 @@ public class FilterChainProxyTests extends TestCase { public void testGettersSetters() { FilterChainProxy filterChainProxy = new FilterChainProxy(); - FilterInvocationDefinitionSource fids = new MockFilterInvocationDefinitionSource(false, - false); + FilterInvocationDefinitionSource fids = new MockFilterInvocationDefinitionSource(false, false); filterChainProxy.setFilterInvocationDefinitionSource(fids); - assertEquals(fids, - filterChainProxy.getFilterInvocationDefinitionSource()); + assertEquals(fids, filterChainProxy.getFilterInvocationDefinitionSource()); } public void testNormalOperation() throws Exception { - ApplicationContext appCtx = new ClassPathXmlApplicationContext( - "org/acegisecurity/util/filtertest-valid.xml"); - FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("filterChain", - FilterChainProxy.class); - MockFilter filter = (MockFilter) appCtx.getBean("mockFilter", - MockFilter.class); + ApplicationContext appCtx = new ClassPathXmlApplicationContext("org/acegisecurity/util/filtertest-valid.xml"); + FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("filterChain", FilterChainProxy.class); + MockFilter filter = (MockFilter) appCtx.getBean("mockFilter", MockFilter.class); assertFalse(filter.isWasInitialized()); assertFalse(filter.isWasDoFiltered()); assertFalse(filter.isWasDestroyed()); @@ -177,7 +167,7 @@ public class FilterChainProxyTests extends TestCase { assertTrue(filter.isWasDestroyed()); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockConfigAttribute implements ConfigAttribute { public String getAttribute() { diff --git a/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java b/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java index 1e7e570129..29b2618f54 100644 --- a/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java +++ b/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,9 @@ import org.acegisecurity.MockFilterConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.mock.web.MockHttpServletResponse; + import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import java.io.IOException; @@ -41,7 +42,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class FilterToBeanProxyTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public FilterToBeanProxyTests() { super(); @@ -51,30 +52,36 @@ public class FilterToBeanProxyTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, + ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + filter.init(filterConfig); + filter.doFilter(request, response, filterChain); + filter.destroy(); } public static void main(String[] args) { junit.textui.TestRunner.run(FilterToBeanProxyTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsClassNotInClassLoader() throws Exception { // Setup our filter MockFilterConfig config = new MockFilterConfig(); config.setInitParmeter("targetClass", "net.sf.DOES.NOT.EXIST"); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); try { filter.init(config); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Class of type net.sf.DOES.NOT.EXIST not found in classloader", - expected.getMessage()); + assertEquals("Class of type net.sf.DOES.NOT.EXIST not found in classloader", expected.getMessage()); } } @@ -82,33 +89,28 @@ public class FilterToBeanProxyTests extends TestCase { // Setup our filter MockFilterConfig config = new MockFilterConfig(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); try { filter.init(config); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("targetClass or targetBean must be specified", - expected.getMessage()); + assertEquals("targetClass or targetBean must be specified", expected.getMessage()); } } public void testDetectsTargetBeanIsNotAFilter() throws Exception { // Setup our filter MockFilterConfig config = new MockFilterConfig(); - config.setInitParmeter("targetClass", - "org.acegisecurity.util.MockNotAFilter"); + config.setInitParmeter("targetClass", "org.acegisecurity.util.MockNotAFilter"); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); try { filter.init(config); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("Bean 'mockNotAFilter' does not implement javax.servlet.Filter", - expected.getMessage()); + assertEquals("Bean 'mockNotAFilter' does not implement javax.servlet.Filter", expected.getMessage()); } } @@ -118,15 +120,13 @@ public class FilterToBeanProxyTests extends TestCase { MockFilterConfig config = new MockFilterConfig(); config.setInitParmeter("targetBean", "WRONG_NAME"); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); try { filter.init(config); fail("Should have thrown ServletException"); } catch (ServletException expected) { - assertEquals("targetBean 'WRONG_NAME' not found in context", - expected.getMessage()); + assertEquals("targetBean 'WRONG_NAME' not found in context", expected.getMessage()); } } @@ -134,11 +134,9 @@ public class FilterToBeanProxyTests extends TestCase { throws Exception { // Setup our filter MockFilterConfig config = new MockFilterConfig(); - config.setInitParmeter("targetClass", - "org.acegisecurity.util.FilterToBeanProxyTests"); + config.setInitParmeter("targetClass", "org.acegisecurity.util.FilterToBeanProxyTests"); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); try { filter.init(config); @@ -152,8 +150,7 @@ public class FilterToBeanProxyTests extends TestCase { public void testIgnoresEmptyTargetBean() throws Exception { // Setup our filter MockFilterConfig config = new MockFilterConfig(); - config.setInitParmeter("targetClass", - "org.acegisecurity.util.MockFilter"); + config.setInitParmeter("targetClass", "org.acegisecurity.util.MockFilter"); config.setInitParmeter("targetBean", ""); // Setup our expectation that the filter chain will be invoked @@ -162,11 +159,9 @@ public class FilterToBeanProxyTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletRequest request = new MockHttpServletRequest(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); } public void testNormalOperationWithLazyTrue() throws Exception { @@ -181,11 +176,9 @@ public class FilterToBeanProxyTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletRequest request = new MockHttpServletRequest(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); } public void testNormalOperationWithSpecificBeanName() @@ -200,18 +193,15 @@ public class FilterToBeanProxyTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletRequest request = new MockHttpServletRequest(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); } public void testNormalOperationWithTargetClass() throws Exception { // Setup our filter MockFilterConfig config = new MockFilterConfig(); - config.setInitParmeter("targetClass", - "org.acegisecurity.util.MockFilter"); + config.setInitParmeter("targetClass", "org.acegisecurity.util.MockFilter"); // Setup our expectation that the filter chain will be invoked MockFilterChain chain = new MockFilterChain(true); @@ -219,11 +209,9 @@ public class FilterToBeanProxyTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletRequest request = new MockHttpServletRequest(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); - executeFilterInContainerSimulator(config, filter, request, response, - chain); + executeFilterInContainerSimulator(config, filter, request, response, chain); } public void testNullDelegateDoesNotCauseNullPointerException() @@ -239,22 +227,13 @@ public class FilterToBeanProxyTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletRequest request = new MockHttpServletRequest(); - FilterToBeanProxy filter = new MockFilterToBeanProxy( - "org/acegisecurity/util/filtertest-valid.xml"); + FilterToBeanProxy filter = new MockFilterToBeanProxy("org/acegisecurity/util/filtertest-valid.xml"); // do not init (which would hapen if called .doFilter) filter.destroy(); } - private void executeFilterInContainerSimulator(FilterConfig filterConfig, - Filter filter, ServletRequest request, ServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - filter.init(filterConfig); - filter.doFilter(request, response, filterChain); - filter.destroy(); - } - - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterToBeanProxy extends FilterToBeanProxy { private String appContextLocation; diff --git a/core/src/test/java/org/acegisecurity/util/MockFilter.java b/core/src/test/java/org/acegisecurity/util/MockFilter.java index f637e8247d..04d7022f15 100644 --- a/core/src/test/java/org/acegisecurity/util/MockFilter.java +++ b/core/src/test/java/org/acegisecurity/util/MockFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,13 +32,27 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class MockFilter implements Filter { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean wasDestroyed = false; private boolean wasDoFiltered = false; private boolean wasInitialized = false; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void destroy() { + wasDestroyed = true; + } + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + wasDoFiltered = true; + chain.doFilter(request, response); + } + + public void init(FilterConfig config) throws ServletException { + wasInitialized = true; + } public boolean isWasDestroyed() { return wasDestroyed; @@ -51,18 +65,4 @@ public class MockFilter implements Filter { public boolean isWasInitialized() { return wasInitialized; } - - public void destroy() { - wasDestroyed = true; - } - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - wasDoFiltered = true; - chain.doFilter(request, response); - } - - public void init(FilterConfig config) throws ServletException { - wasInitialized = true; - } } diff --git a/core/src/test/java/org/acegisecurity/util/MockFilterChain.java b/core/src/test/java/org/acegisecurity/util/MockFilterChain.java index a4b5642ea5..8206b4f7fe 100644 --- a/core/src/test/java/org/acegisecurity/util/MockFilterChain.java +++ b/core/src/test/java/org/acegisecurity/util/MockFilterChain.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,12 @@ package org.acegisecurity.util; import junit.framework.TestCase; +import java.io.IOException; + import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import java.io.IOException; /** @@ -31,20 +32,20 @@ import java.io.IOException; * @version $Id$ */ public class MockFilterChain implements FilterChain { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private boolean expectToProceed; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public MockFilterChain(boolean expectToProceed) { this.expectToProceed = expectToProceed; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void doFilter(ServletRequest request, ServletResponse response) - throws IOException, ServletException { + throws IOException, ServletException { if (expectToProceed) { TestCase.assertTrue(true); } else { diff --git a/core/src/test/java/org/acegisecurity/util/MockNotAFilter.java b/core/src/test/java/org/acegisecurity/util/MockNotAFilter.java index 5f14f56823..5a17676799 100644 --- a/core/src/test/java/org/acegisecurity/util/MockNotAFilter.java +++ b/core/src/test/java/org/acegisecurity/util/MockNotAFilter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/core/src/test/java/org/acegisecurity/util/PortMapperImplTests.java b/core/src/test/java/org/acegisecurity/util/PortMapperImplTests.java index f558c985b4..7fa0656b8b 100644 --- a/core/src/test/java/org/acegisecurity/util/PortMapperImplTests.java +++ b/core/src/test/java/org/acegisecurity/util/PortMapperImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import java.util.Map; * @version $Id$ */ public class PortMapperImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PortMapperImplTests() { super(); @@ -38,26 +38,22 @@ public class PortMapperImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(PortMapperImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDefaultMappingsAreKnown() throws Exception { PortMapperImpl portMapper = new PortMapperImpl(); - assertEquals(new Integer(80), - portMapper.lookupHttpPort(new Integer(443))); - assertEquals(new Integer(8080), - portMapper.lookupHttpPort(new Integer(8443))); - assertEquals(new Integer(443), - portMapper.lookupHttpsPort(new Integer(80))); - assertEquals(new Integer(8443), - portMapper.lookupHttpsPort(new Integer(8080))); + assertEquals(new Integer(80), portMapper.lookupHttpPort(new Integer(443))); + assertEquals(new Integer(8080), portMapper.lookupHttpPort(new Integer(8443))); + assertEquals(new Integer(443), portMapper.lookupHttpsPort(new Integer(80))); + assertEquals(new Integer(8443), portMapper.lookupHttpsPort(new Integer(8080))); } public void testDetectsEmptyMap() throws Exception { @@ -112,9 +108,7 @@ public class PortMapperImplTests extends TestCase { portMapper.setPortMappings(map); - assertEquals(new Integer(79), - portMapper.lookupHttpPort(new Integer(442))); - assertEquals(new Integer(442), - portMapper.lookupHttpsPort(new Integer(79))); + assertEquals(new Integer(79), portMapper.lookupHttpPort(new Integer(442))); + assertEquals(new Integer(442), portMapper.lookupHttpsPort(new Integer(79))); } } diff --git a/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java b/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java index 0cb1b7fafb..d672eb28bc 100644 --- a/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java +++ b/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package org.acegisecurity.util; import junit.framework.TestCase; -import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletRequest; /** @@ -27,7 +27,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class PortResolverImplTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PortResolverImplTests() { super(); @@ -37,16 +37,16 @@ public class PortResolverImplTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(PortResolverImplTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testDetectsBuggyIeHttpRequest() throws Exception { PortResolverImpl pr = new PortResolverImpl(); pr.afterPropertiesSet(); diff --git a/core/src/test/java/org/acegisecurity/util/StringSplitUtilsTests.java b/core/src/test/java/org/acegisecurity/util/StringSplitUtilsTests.java index 286caf028b..b4a7c53573 100644 --- a/core/src/test/java/org/acegisecurity/util/StringSplitUtilsTests.java +++ b/core/src/test/java/org/acegisecurity/util/StringSplitUtilsTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import java.util.Map; * @version $Id$ */ public class StringSplitUtilsTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== // =========================================================== public StringSplitUtilsTests() { @@ -40,7 +40,7 @@ public class StringSplitUtilsTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== // ================================================================ public static void main(String[] args) { @@ -51,17 +51,14 @@ public class StringSplitUtilsTests extends TestCase { // note it ignores malformed entries (ie those without an equals sign) String unsplit = "username=\"marissa\", invalidEntryThatHasNoEqualsSign, realm=\"Contacts Realm\", nonce=\"MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==\", uri=\"/acegi-security-sample-contacts-filter/secure/adminPermission.htm?contactId=4\", response=\"38644211cf9ac3da63ab639807e2baff\", qop=auth, nc=00000004, cnonce=\"2b8d329a8571b99a\""; String[] headerEntries = StringUtils.commaDelimitedListToStringArray(unsplit); - Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, - "=", "\""); + Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\""); assertEquals("marissa", headerMap.get("username")); assertEquals("Contacts Realm", headerMap.get("realm")); - assertEquals("MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==", - headerMap.get("nonce")); + assertEquals("MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==", headerMap.get("nonce")); assertEquals("/acegi-security-sample-contacts-filter/secure/adminPermission.htm?contactId=4", headerMap.get("uri")); - assertEquals("38644211cf9ac3da63ab639807e2baff", - headerMap.get("response")); + assertEquals("38644211cf9ac3da63ab639807e2baff", headerMap.get("response")); assertEquals("auth", headerMap.get("qop")); assertEquals("00000004", headerMap.get("nc")); assertEquals("2b8d329a8571b99a", headerMap.get("cnonce")); @@ -71,17 +68,14 @@ public class StringSplitUtilsTests extends TestCase { public void testSplitEachArrayElementAndCreateMapRespectsInstructionNotToRemoveCharacters() { String unsplit = "username=\"marissa\", realm=\"Contacts Realm\", nonce=\"MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==\", uri=\"/acegi-security-sample-contacts-filter/secure/adminPermission.htm?contactId=4\", response=\"38644211cf9ac3da63ab639807e2baff\", qop=auth, nc=00000004, cnonce=\"2b8d329a8571b99a\""; String[] headerEntries = StringUtils.commaDelimitedListToStringArray(unsplit); - Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, - "=", null); + Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", null); assertEquals("\"marissa\"", headerMap.get("username")); assertEquals("\"Contacts Realm\"", headerMap.get("realm")); - assertEquals("\"MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==\"", - headerMap.get("nonce")); + assertEquals("\"MTEwOTAyMzU1MTQ4NDo1YzY3OWViYWM5NDNmZWUwM2UwY2NmMDBiNDQzMTQ0OQ==\"", headerMap.get("nonce")); assertEquals("\"/acegi-security-sample-contacts-filter/secure/adminPermission.htm?contactId=4\"", headerMap.get("uri")); - assertEquals("\"38644211cf9ac3da63ab639807e2baff\"", - headerMap.get("response")); + assertEquals("\"38644211cf9ac3da63ab639807e2baff\"", headerMap.get("response")); assertEquals("auth", headerMap.get("qop")); assertEquals("00000004", headerMap.get("nc")); assertEquals("\"2b8d329a8571b99a\"", headerMap.get("cnonce")); @@ -89,10 +83,8 @@ public class StringSplitUtilsTests extends TestCase { } public void testSplitEachArrayElementAndCreateMapReturnsNullIfArrayEmptyOrNull() { - assertNull(StringSplitUtils.splitEachArrayElementAndCreateMap(null, - "=", "\"")); - assertNull(StringSplitUtils.splitEachArrayElementAndCreateMap( - new String[] {}, "=", "\"")); + assertNull(StringSplitUtils.splitEachArrayElementAndCreateMap(null, "=", "\"")); + assertNull(StringSplitUtils.splitEachArrayElementAndCreateMap(new String[] {}, "=", "\"")); } public void testSplitNormalOperation() { diff --git a/core/src/test/java/org/acegisecurity/vote/AbstractAccessDecisionManagerTests.java b/core/src/test/java/org/acegisecurity/vote/AbstractAccessDecisionManagerTests.java index ac4f60c7b8..887e019316 100644 --- a/core/src/test/java/org/acegisecurity/vote/AbstractAccessDecisionManagerTests.java +++ b/core/src/test/java/org/acegisecurity/vote/AbstractAccessDecisionManagerTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ import java.util.Vector; * @version $Id$ */ public class AbstractAccessDecisionManagerTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AbstractAccessDecisionManagerTests() { super(); @@ -44,16 +44,16 @@ public class AbstractAccessDecisionManagerTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AbstractAccessDecisionManagerTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAllowIfAccessDecisionManagerDefaults() throws Exception { MockDecisionManagerImpl mock = new MockDecisionManagerImpl(); @@ -159,11 +159,11 @@ public class AbstractAccessDecisionManagerTests extends TestCase { } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockDecisionManagerImpl extends AbstractAccessDecisionManager { - public void decide(Authentication authentication, Object object, - ConfigAttributeDefinition config) throws AccessDeniedException { + public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) + throws AccessDeniedException { return; } } @@ -178,14 +178,11 @@ public class AbstractAccessDecisionManagerTests extends TestCase { } public boolean supports(ConfigAttribute attribute) { - throw new UnsupportedOperationException( - "mock method not implemented"); + throw new UnsupportedOperationException("mock method not implemented"); } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { - throw new UnsupportedOperationException( - "mock method not implemented"); + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { + throw new UnsupportedOperationException("mock method not implemented"); } } } diff --git a/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java b/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java index df4f4d2e10..bcc66cc384 100644 --- a/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java +++ b/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.vote; -import java.util.List; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.AccessDeniedException; @@ -25,8 +22,12 @@ import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.providers.TestingAuthenticationToken; +import java.util.List; +import java.util.Vector; + /** * Tests {@link AffirmativeBased}. @@ -35,7 +36,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class AffirmativeBasedTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AffirmativeBasedTests() { super(); @@ -45,16 +46,35 @@ public class AffirmativeBasedTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(AffirmativeBasedTests.class); } + private AffirmativeBased makeDecisionManager() { + AffirmativeBased decisionManager = new AffirmativeBased(); + RoleVoter roleVoter = new RoleVoter(); + DenyVoter denyForSureVoter = new DenyVoter(); + DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); + List voters = new Vector(); + voters.add(roleVoter); + voters.add(denyForSureVoter); + voters.add(denyAgainForSureVoter); + decisionManager.setDecisionVoters(voters); + + return decisionManager; + } + + private TestingAuthenticationToken makeTestToken() { + return new TestingAuthenticationToken("somebody", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl("ROLE_2")}); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteGrantsAccess() throws Exception { TestingAuthenticationToken auth = makeTestToken(); @@ -140,24 +160,4 @@ public class AffirmativeBasedTests extends TestCase { mgr.decide(auth, new Object(), config); assertTrue(true); } - - private AffirmativeBased makeDecisionManager() { - AffirmativeBased decisionManager = new AffirmativeBased(); - RoleVoter roleVoter = new RoleVoter(); - DenyVoter denyForSureVoter = new DenyVoter(); - DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); - List voters = new Vector(); - voters.add(roleVoter); - voters.add(denyForSureVoter); - voters.add(denyAgainForSureVoter); - decisionManager.setDecisionVoters(voters); - - return decisionManager; - } - - private TestingAuthenticationToken makeTestToken() { - return new TestingAuthenticationToken("somebody", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl( - "ROLE_2")}); - } } diff --git a/core/src/test/java/org/acegisecurity/vote/AuthenticatedVoterTests.java b/core/src/test/java/org/acegisecurity/vote/AuthenticatedVoterTests.java index 79fb13d936..ebcd24d69e 100644 --- a/core/src/test/java/org/acegisecurity/vote/AuthenticatedVoterTests.java +++ b/core/src/test/java/org/acegisecurity/vote/AuthenticatedVoterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken; import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken; @@ -34,7 +35,7 @@ import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken; * @version $Id$ */ public class AuthenticatedVoterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public AuthenticatedVoterTests() { super(); @@ -44,53 +45,56 @@ public class AuthenticatedVoterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); + private Authentication createAnonymous() { + return new AnonymousAuthenticationToken("ignored", "ignored", + new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); + } + + private Authentication createFullyAuthenticated() { + return new UsernamePasswordAuthenticationToken("ignored", "ignored", + new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); + } + + private Authentication createRememberMe() { + return new RememberMeAuthenticationToken("ignored", "ignored", + new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); } public static void main(String[] args) { junit.textui.TestRunner.run(AuthenticatedVoterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testAnonymousWorks() { AuthenticatedVoter voter = new AuthenticatedVoter(); ConfigAttributeDefinition def = new ConfigAttributeDefinition(); - def.addConfigAttribute(new SecurityConfig( - AuthenticatedVoter.IS_AUTHENTICATED_ANONYMOUSLY)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createAnonymous(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createRememberMe(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createFullyAuthenticated(), null, def)); + def.addConfigAttribute(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_ANONYMOUSLY)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createAnonymous(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createRememberMe(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createFullyAuthenticated(), null, def)); } public void testFullyWorks() { AuthenticatedVoter voter = new AuthenticatedVoter(); ConfigAttributeDefinition def = new ConfigAttributeDefinition(); - def.addConfigAttribute(new SecurityConfig( - AuthenticatedVoter.IS_AUTHENTICATED_FULLY)); - assertEquals(AccessDecisionVoter.ACCESS_DENIED, - voter.vote(createAnonymous(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_DENIED, - voter.vote(createRememberMe(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createFullyAuthenticated(), null, def)); + def.addConfigAttribute(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_FULLY)); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, voter.vote(createAnonymous(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, voter.vote(createRememberMe(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createFullyAuthenticated(), null, def)); } public void testRememberMeWorks() { AuthenticatedVoter voter = new AuthenticatedVoter(); ConfigAttributeDefinition def = new ConfigAttributeDefinition(); - def.addConfigAttribute(new SecurityConfig( - AuthenticatedVoter.IS_AUTHENTICATED_REMEMBERED)); - assertEquals(AccessDecisionVoter.ACCESS_DENIED, - voter.vote(createAnonymous(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createRememberMe(), null, def)); - assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote(createFullyAuthenticated(), null, def)); + def.addConfigAttribute(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_REMEMBERED)); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, voter.vote(createAnonymous(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createRememberMe(), null, def)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, voter.vote(createFullyAuthenticated(), null, def)); } public void testSetterRejectsNull() { @@ -107,29 +111,9 @@ public class AuthenticatedVoterTests extends TestCase { public void testSupports() { AuthenticatedVoter voter = new AuthenticatedVoter(); assertTrue(voter.supports(String.class)); - assertTrue(voter.supports( - new SecurityConfig( - AuthenticatedVoter.IS_AUTHENTICATED_ANONYMOUSLY))); - assertTrue(voter.supports( - new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_FULLY))); - assertTrue(voter.supports( - new SecurityConfig( - AuthenticatedVoter.IS_AUTHENTICATED_REMEMBERED))); + assertTrue(voter.supports(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_ANONYMOUSLY))); + assertTrue(voter.supports(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_FULLY))); + assertTrue(voter.supports(new SecurityConfig(AuthenticatedVoter.IS_AUTHENTICATED_REMEMBERED))); assertFalse(voter.supports(new SecurityConfig("FOO"))); } - - private Authentication createAnonymous() { - return new AnonymousAuthenticationToken("ignored", "ignored", - new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); - } - - private Authentication createFullyAuthenticated() { - return new UsernamePasswordAuthenticationToken("ignored", "ignored", - new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); - } - - private Authentication createRememberMe() { - return new RememberMeAuthenticationToken("ignored", "ignored", - new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")}); - } } diff --git a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java index aa40a4449f..54b6a76601 100644 --- a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java +++ b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java @@ -45,7 +45,7 @@ import java.lang.reflect.Method; * @version $Id$ */ public class BasicAclEntryVoterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BasicAclEntryVoterTests() { super(); @@ -55,13 +55,12 @@ public class BasicAclEntryVoterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== private MethodInvocation getMethodInvocation(SomeDomainObject domainObject) throws Exception { Class clazz = SomeDomainObjectManager.class; - Method method = clazz.getMethod("someServiceMethod", - new Class[] {SomeDomainObject.class}); + Method method = clazz.getMethod("someServiceMethod", new Class[] {SomeDomainObject.class}); return new SimpleMethodInvocation(method, new Object[] {domainObject}); } @@ -80,20 +79,19 @@ public class BasicAclEntryVoterTests extends TestCase { // Setup an AclManager AclManager aclManager = new MockAclManager(domainObject, "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); voter.setAclManager(aclManager); assertEquals(aclManager, voter.getAclManager()); voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); - assertEquals("FOO_ADMIN_OR_WRITE_ACCESS", - voter.getProcessConfigAttribute()); + assertEquals("FOO_ADMIN_OR_WRITE_ACCESS", voter.getProcessConfigAttribute()); voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); assertEquals(2, voter.getRequirePermission().length); voter.setProcessDomainObjectClass(SomeDomainObject.class); @@ -108,9 +106,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote( - new UsernamePasswordAuthenticationToken("marissa", null), mi, - attr)); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr)); } public void testOnlySupportsMethodInvocationAndJoinPoint() { @@ -122,12 +118,12 @@ public class BasicAclEntryVoterTests extends TestCase { public void testStartupRejectsMissingAclManager() throws Exception { AclManager aclManager = new MockAclManager("domain1", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -146,12 +142,12 @@ public class BasicAclEntryVoterTests extends TestCase { public void testStartupRejectsMissingProcessConfigAttribute() throws Exception { AclManager aclManager = new MockAclManager("domain1", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -182,12 +178,12 @@ public class BasicAclEntryVoterTests extends TestCase { public void testStartupRejectsMissingRequirePermission() throws Exception { AclManager aclManager = new MockAclManager("domain1", "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -216,12 +212,12 @@ public class BasicAclEntryVoterTests extends TestCase { // Setup an AclManager AclManager aclManager = new MockAclManager(domainObject, "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -239,9 +235,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN, - voter.vote( - new UsernamePasswordAuthenticationToken("marissa", null), mi, - attr)); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr)); } public void testVoterAbstainsIfNotMatchingConfigAttribute() @@ -251,12 +245,12 @@ public class BasicAclEntryVoterTests extends TestCase { // Setup an AclManager AclManager aclManager = new MockAclManager(domainObject, "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -274,9 +268,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN, - voter.vote( - new UsernamePasswordAuthenticationToken("marissa", null), mi, - attr)); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr)); } public void testVoterCanDenyAccessBasedOnInternalMethodOfDomainObject() @@ -285,11 +277,11 @@ public class BasicAclEntryVoterTests extends TestCase { SomeDomainObject domainObject = new SomeDomainObject("foo"); // Setup an AclManager - AclManager aclManager = new MockAclManager(domainObject.getParent(), - "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.DELETE)}); + AclManager aclManager = new MockAclManager(domainObject.getParent(), "marissa", + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -308,9 +300,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); assertEquals(AccessDecisionVoter.ACCESS_DENIED, - voter.vote( - new UsernamePasswordAuthenticationToken("marissa", null), mi, - attr)); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr)); } public void testVoterCanDenyAccessIfPrincipalHasNoPermissionsAtAllToDomainObject() @@ -320,9 +310,10 @@ public class BasicAclEntryVoterTests extends TestCase { // Setup an AclManager AclManager aclManager = new MockAclManager(domainObject, "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.DELETE)}); + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -342,8 +333,7 @@ public class BasicAclEntryVoterTests extends TestCase { // NB: scott is the principal, not marissa assertEquals(AccessDecisionVoter.ACCESS_DENIED, - voter.vote(new UsernamePasswordAuthenticationToken("scott", null), - mi, attr)); + voter.vote(new UsernamePasswordAuthenticationToken("scott", null), mi, attr)); } public void testVoterCanGrantAccessBasedOnInternalMethodOfDomainObject() @@ -352,14 +342,13 @@ public class BasicAclEntryVoterTests extends TestCase { SomeDomainObject domainObject = new SomeDomainObject("foo"); // Setup an AclManager - AclManager aclManager = new MockAclManager(domainObject.getParent(), - "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + AclManager aclManager = new MockAclManager(domainObject.getParent(), "marissa", + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -380,9 +369,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); assertEquals(AccessDecisionVoter.ACCESS_GRANTED, - voter.vote( - new UsernamePasswordAuthenticationToken("marissa", null), mi, - attr)); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr)); } public void testVoterThrowsExceptionIfInvalidInternalMethodOfDomainObject() @@ -391,14 +378,13 @@ public class BasicAclEntryVoterTests extends TestCase { SomeDomainObject domainObject = new SomeDomainObject("foo"); // Setup an AclManager - AclManager aclManager = new MockAclManager(domainObject.getParent(), - "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + AclManager aclManager = new MockAclManager(domainObject.getParent(), "marissa", + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -418,8 +404,7 @@ public class BasicAclEntryVoterTests extends TestCase { MethodInvocation mi = getMethodInvocation(domainObject); try { - voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), - mi, attr); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr); fail("Should have thrown AuthorizationServiceException"); } catch (AuthorizationServiceException expected) { assertTrue(true); @@ -432,14 +417,13 @@ public class BasicAclEntryVoterTests extends TestCase { SomeDomainObject domainObject = new SomeDomainObject("foo"); // Setup an AclManager - AclManager aclManager = new MockAclManager(domainObject.getParent(), - "marissa", - new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( - "marissa", new MockAclObjectIdentity(), null, - SimpleAclEntry.READ), new SimpleAclEntry("marissa", - new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + AclManager aclManager = new MockAclManager(domainObject.getParent(), "marissa", + new AclEntry[] { + new MockAclEntry(), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ), + new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE) + }); // Wire up a voter BasicAclEntryVoter voter = new BasicAclEntryVoter(); @@ -457,19 +441,17 @@ public class BasicAclEntryVoterTests extends TestCase { Class clazz = String.class; Method method = clazz.getMethod("toString", new Class[] {}); - MethodInvocation mi = new SimpleMethodInvocation(method, - new Object[] {domainObject}); + MethodInvocation mi = new SimpleMethodInvocation(method, new Object[] {domainObject}); try { - voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), - mi, attr); + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), mi, attr); fail("Should have thrown AuthorizationServiceException"); } catch (AuthorizationServiceException expected) { assertTrue(true); } } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry { // just so AclTag iterates some different types of AclEntrys diff --git a/core/src/test/java/org/acegisecurity/vote/DenyAgainVoter.java b/core/src/test/java/org/acegisecurity/vote/DenyAgainVoter.java index 65d8ee38fa..ace32801ce 100644 --- a/core/src/test/java/org/acegisecurity/vote/DenyAgainVoter.java +++ b/core/src/test/java/org/acegisecurity/vote/DenyAgainVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,22 +23,16 @@ import java.util.Iterator; /** - * Implementation of an {@link AccessDecisionVoter} for unit testing. - * - *

- * If the {@link ConfigAttribute#getAttribute()} has a value of - * DENY_AGAIN_FOR_SURE, the voter will vote to deny access. - *

- * - *

- * All comparisons are case sensitive. - *

+ * Implementation of an {@link AccessDecisionVoter} for unit testing.

If the {@link + * ConfigAttribute#getAttribute()} has a value of DENY_AGAIN_FOR_SURE, the voter will vote to deny + * access.

+ *

All comparisons are case sensitive.

* * @author Ben Alex * @version $Id$ */ public class DenyAgainVoter implements AccessDecisionVoter { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean supports(ConfigAttribute attribute) { if ("DENY_AGAIN_FOR_SURE".equals(attribute.getAttribute())) { @@ -52,8 +46,7 @@ public class DenyAgainVoter implements AccessDecisionVoter { return true; } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { diff --git a/core/src/test/java/org/acegisecurity/vote/DenyVoter.java b/core/src/test/java/org/acegisecurity/vote/DenyVoter.java index 29b90063b1..69687cead6 100644 --- a/core/src/test/java/org/acegisecurity/vote/DenyVoter.java +++ b/core/src/test/java/org/acegisecurity/vote/DenyVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,22 +23,15 @@ import java.util.Iterator; /** - * Implementation of an {@link AccessDecisionVoter} for unit testing. - * - *

- * If the {@link ConfigAttribute#getAttribute()} has a value of - * DENY_FOR_SURE, the voter will vote to deny access. - *

- * - *

- * All comparisons are case sensitive. - *

+ * Implementation of an {@link AccessDecisionVoter} for unit testing.

If the {@link + * ConfigAttribute#getAttribute()} has a value of DENY_FOR_SURE, the voter will vote to deny access.

+ *

All comparisons are case sensitive.

* * @author Ben Alex * @version $Id$ */ public class DenyVoter implements AccessDecisionVoter { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean supports(ConfigAttribute attribute) { if ("DENY_FOR_SURE".equals(attribute.getAttribute())) { @@ -52,8 +45,7 @@ public class DenyVoter implements AccessDecisionVoter { return true; } - public int vote(Authentication authentication, Object object, - ConfigAttributeDefinition config) { + public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) { Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) { diff --git a/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java b/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java index 7f85760ac9..2daebd2577 100644 --- a/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java +++ b/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +22,11 @@ package org.acegisecurity.vote; * @version $Id$ */ public class SomeDomainObject { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String identity; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SomeDomainObject(String identity) { this.identity = identity; @@ -34,7 +34,7 @@ public class SomeDomainObject { private SomeDomainObject() {} - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public String getParent() { return "parentOf" + identity; diff --git a/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java b/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java index 741f3963cd..da6417eee7 100644 --- a/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java +++ b/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,14 @@ package org.acegisecurity.vote; /** - * Used by {@link BasicAclEntryVoterTests} so it can create a - * MethodInvocation contining SomeDomainObject. + * Used by {@link BasicAclEntryVoterTests} so it can create a MethodInvocation contining + * SomeDomainObject. * * @author Ben Alex * @version $Id$ */ public class SomeDomainObjectManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public void someServiceMethod(SomeDomainObject someDomainObject) {} } diff --git a/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java b/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java index c32e4a7452..c574a3f44e 100644 --- a/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java +++ b/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,6 @@ package org.acegisecurity.vote; -import java.util.List; -import java.util.Vector; - import junit.framework.TestCase; import org.acegisecurity.AccessDeniedException; @@ -25,8 +22,12 @@ import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.providers.TestingAuthenticationToken; +import java.util.List; +import java.util.Vector; + /** * Tests {@link UnanimousBased}. @@ -35,7 +36,7 @@ import org.acegisecurity.providers.TestingAuthenticationToken; * @version $Id$ */ public class UnanimousBasedTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public UnanimousBasedTests() { super(); @@ -45,16 +46,56 @@ public class UnanimousBasedTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(UnanimousBasedTests.class); } + private UnanimousBased makeDecisionManager() { + UnanimousBased decisionManager = new UnanimousBased(); + RoleVoter roleVoter = new RoleVoter(); + DenyVoter denyForSureVoter = new DenyVoter(); + DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); + List voters = new Vector(); + voters.add(roleVoter); + voters.add(denyForSureVoter); + voters.add(denyAgainForSureVoter); + decisionManager.setDecisionVoters(voters); + + return decisionManager; + } + + private UnanimousBased makeDecisionManagerWithFooBarPrefix() { + UnanimousBased decisionManager = new UnanimousBased(); + RoleVoter roleVoter = new RoleVoter(); + roleVoter.setRolePrefix("FOOBAR_"); + + DenyVoter denyForSureVoter = new DenyVoter(); + DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); + List voters = new Vector(); + voters.add(roleVoter); + voters.add(denyForSureVoter); + voters.add(denyAgainForSureVoter); + decisionManager.setDecisionVoters(voters); + + return decisionManager; + } + + private TestingAuthenticationToken makeTestToken() { + return new TestingAuthenticationToken("somebody", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl("ROLE_2")}); + } + + private TestingAuthenticationToken makeTestTokenWithFooBarPrefix() { + return new TestingAuthenticationToken("somebody", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("FOOBAR_1"), new GrantedAuthorityImpl("FOOBAR_2")}); + } + + public final void setUp() throws Exception { + super.setUp(); + } + public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteDeniesAccess() throws Exception { TestingAuthenticationToken auth = makeTestToken(); @@ -156,46 +197,4 @@ public class UnanimousBasedTests extends TestCase { mgr.decide(auth, new Object(), config); assertTrue(true); } - - private UnanimousBased makeDecisionManager() { - UnanimousBased decisionManager = new UnanimousBased(); - RoleVoter roleVoter = new RoleVoter(); - DenyVoter denyForSureVoter = new DenyVoter(); - DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); - List voters = new Vector(); - voters.add(roleVoter); - voters.add(denyForSureVoter); - voters.add(denyAgainForSureVoter); - decisionManager.setDecisionVoters(voters); - - return decisionManager; - } - - private UnanimousBased makeDecisionManagerWithFooBarPrefix() { - UnanimousBased decisionManager = new UnanimousBased(); - RoleVoter roleVoter = new RoleVoter(); - roleVoter.setRolePrefix("FOOBAR_"); - - DenyVoter denyForSureVoter = new DenyVoter(); - DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); - List voters = new Vector(); - voters.add(roleVoter); - voters.add(denyForSureVoter); - voters.add(denyAgainForSureVoter); - decisionManager.setDecisionVoters(voters); - - return decisionManager; - } - - private TestingAuthenticationToken makeTestToken() { - return new TestingAuthenticationToken("somebody", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl( - "ROLE_2")}); - } - - private TestingAuthenticationToken makeTestTokenWithFooBarPrefix() { - return new TestingAuthenticationToken("somebody", "password", - new GrantedAuthority[] {new GrantedAuthorityImpl("FOOBAR_1"), new GrantedAuthorityImpl( - "FOOBAR_2")}); - } } diff --git a/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilterTests.java b/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilterTests.java index 40c6f7a68a..5cb2c3d8c5 100644 --- a/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilterTests.java +++ b/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestFilterTests.java @@ -36,7 +36,7 @@ import javax.servlet.ServletResponse; * @version $Id$ */ public class SecurityContextHolderAwareRequestFilterTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityContextHolderAwareRequestFilterTests() { super(); @@ -46,7 +46,7 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SecurityContextHolderAwareRequestFilterTests.class); @@ -69,7 +69,7 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase { filter.destroy(); } - //~ Inner Classes ========================================================== + //~ Inner Classes ================================================================================================== private class MockFilterChain implements FilterChain { private Class expectedServletRequest; @@ -87,8 +87,7 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase { if (request.getClass().isAssignableFrom(expectedServletRequest)) { assertTrue(true); } else { - fail("Expected class to be of type " + expectedServletRequest - + " but was: " + request.getClass()); + fail("Expected class to be of type " + expectedServletRequest + " but was: " + request.getClass()); } } } diff --git a/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapperTests.java b/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapperTests.java index cfb815a586..85ba4b06f6 100644 --- a/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapperTests.java +++ b/core/src/test/java/org/acegisecurity/wrapper/SecurityContextHolderAwareRequestWrapperTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,13 @@ import junit.framework.TestCase; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.providers.TestingAuthenticationToken; + import org.acegisecurity.userdetails.User; + import org.acegisecurity.wrapper.SecurityContextHolderAwareRequestWrapper; import org.springframework.mock.web.MockHttpServletRequest; @@ -35,7 +39,7 @@ import org.springframework.mock.web.MockHttpServletRequest; * @version $Id$ */ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public SecurityContextHolderAwareRequestWrapperTests() { super(); @@ -45,20 +49,19 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase { super(arg0); } - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } + //~ Methods ======================================================================================================== public static void main(String[] args) { junit.textui.TestRunner.run(SecurityContextHolderAwareRequestWrapperTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testCorrectOperationWithStringBasedPrincipal() throws Exception { - Authentication auth = new TestingAuthenticationToken("marissa", - "koala", + Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO")}); SecurityContextHolder.getContext().setAuthentication(auth); @@ -77,11 +80,9 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase { public void testCorrectOperationWithUserDetailsBasedPrincipal() throws Exception { - Authentication auth = new TestingAuthenticationToken(new User( - "marissaAsUserDetails", "koala", true, true, true, true, - new GrantedAuthority[] {}), "koala", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl( - "ROLE_FOOBAR")}); + Authentication auth = new TestingAuthenticationToken(new User("marissaAsUserDetails", "koala", true, true, + true, true, new GrantedAuthority[] {}), "koala", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")}); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); @@ -115,8 +116,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase { public void testNullPrincipalHandling() throws Exception { Authentication auth = new TestingAuthenticationToken(null, "koala", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl( - "ROLE_FOOBAR")}); + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")}); SecurityContextHolder.getContext().setAuthentication(auth); MockHttpServletRequest request = new MockHttpServletRequest(); diff --git a/domain/src/main/java/org/acegisecurity/domain/DomainException.java b/domain/src/main/java/org/acegisecurity/domain/DomainException.java index 387c04c42c..9e1bbfceaa 100644 --- a/domain/src/main/java/org/acegisecurity/domain/DomainException.java +++ b/domain/src/main/java/org/acegisecurity/domain/DomainException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,15 @@ import org.acegisecurity.AcegiSecurityException; /** - * Abstract superclass for all exceptions related to domain object support - * subproject. + * Abstract superclass for all exceptions related to domain object support subproject. * * @author Ben Alex * @version $Id$ */ public abstract class DomainException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a DomainException with the specified message and * root cause. * @@ -39,7 +38,7 @@ public abstract class DomainException extends AcegiSecurityException { super(msg, t); } - /** +/** * Constructs a DomainException with the specified message and * no root cause. * diff --git a/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java b/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java index 65ec93ca50..b2d3f7b637 100644 --- a/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java +++ b/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,25 +30,16 @@ import java.io.Serializable; * @version $Id$ */ public interface PersistableEntity { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Provides a common getter for the persistence layer to obtain an - * identity, irrespective of the actual type of identity used. - * - *

- * Typically a subclass will delegate to a public - * SomePrimitiveWrapper getId() method. The necessity for the - * getInternalId() abstract method is solely because the - * persistence layer needs a way of obtaining the identity irrespective of - * the actual identity implementation choice. - *

- * - *

- * Returning null from this method will indicate the object - * has never been saved. This will likely be relied on by some - * Dao implementations. - *

+ * Provides a common getter for the persistence layer to obtain an identity, irrespective of the actual + * type of identity used.

Typically a subclass will delegate to a public SomePrimitiveWrapper + * getId() method. The necessity for the getInternalId() abstract method is solely because + * the persistence layer needs a way of obtaining the identity irrespective of the actual identity implementation + * choice.

+ *

Returning null from this method will indicate the object has never been saved. This + * will likely be relied on by some Dao implementations.

* * @return the persistence identity of this instance */ diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java b/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java index 58a8a27fe2..439caf8204 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,15 @@ package org.acegisecurity.domain.dao; +import org.acegisecurity.domain.PersistableEntity; + +import org.springframework.dao.DataAccessException; + import java.io.Serializable; + import java.util.Collection; import java.util.List; -import org.acegisecurity.domain.PersistableEntity; -import org.springframework.dao.DataAccessException; /** * Provides fundamental DAO capabilities for a single concrete {@link @@ -58,13 +61,14 @@ import org.springframework.dao.DataAccessException; * @version $Id$ */ public interface Dao { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Create a new object, with the current {@link - * PersistableEntity#getInternalId()} value being ignored. + * Create a new object, with the current {@link PersistableEntity#getInternalId()} value being ignored. * * @param value (without the identity property initialized) + * + * @throws DataAccessException DOCUMENT ME! */ public void create(E value) throws DataAccessException; @@ -72,106 +76,98 @@ public interface Dao { * Delete an object. * * @param value the value to delete + * + * @throws DataAccessException DOCUMENT ME! */ public void delete(E value) throws DataAccessException; /** * Return all persistent instances, including subclasses. * - * @return all persistence instances (an empty List will be - * returned if no matches are found) + * @return all persistence instances (an empty List will be returned if no matches are found) + * + * @throws DataAccessException DOCUMENT ME! */ public List findAll() throws DataAccessException; /** - * Find a List of PersistableEntitys, searched by - * their identifiers. + * Find a List of PersistableEntitys, searched by their identifiers. * * @param ids collection of identifiers to locate * - * @return the values with those identifiers (an empty List - * will be returned if no matches are found) + * @return the values with those identifiers (an empty List will be returned if no matches are found) + * + * @throws DataAccessException DOCUMENT ME! */ - public List findId(Collection ids) throws DataAccessException; + public List findId(Collection ids) + throws DataAccessException; /** - * Load a persistent instance by its identifier, although some properties - * may be lazy loaded depending on the underlying DAO implementation and/or - * persistence engine mapping document. + * Load a persistent instance by its identifier, although some properties may be lazy loaded depending on + * the underlying DAO implementation and/or persistence engine mapping document. * - * @param id the identifier of the persistent instance desired to be - * retrieved + * @param id the identifier of the persistent instance desired to be retrieved * * @return the request item, or null if not found + * + * @throws DataAccessException DOCUMENT ME! */ public E readId(Serializable id) throws DataAccessException; /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity. - * - *

- * Persistent instances are matched on the basis of query by example. - * Properties whose value is null, empty - * Strings, and any Collections are ignored in - * the query by example evaluation. - *

+ * Find persistent instances with properties matching those of the passed PersistableEntity.

Persistent + * instances are matched on the basis of query by example. Properties whose value is null, empty + * Strings, and any Collections are ignored in the query by example evaluation.

* - * @param value parameters to filter on (the class of this object will - * be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * @param orderByAsc the property name of the - * PersistableEntity that should be used to order the + * @param value parameters to filter on (the class of this object will be added to the filter) + * @param firstElement the first result (start at zero to obtain all results) + * @param maxElements the maximum number of results desired for this page of the result set + * @param orderByAsc the property name of the PersistableEntity that should be used to order the * results * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) + * @return the requested page of the result list (a properly formed PaginatedList is returned if no + * results match) + * + * @throws DataAccessException DOCUMENT ME! */ - public PaginatedList scroll(E value, int firstElement, - int maxElements, String orderByAsc) throws DataAccessException; + public PaginatedList scroll(E value, int firstElement, int maxElements, String orderByAsc) + throws DataAccessException; - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity, ignoring the class of the passed - * PersistableEntity (useful if you pass a superclass, as you - * want to find all subclass instances which match). - * - * @param value parameters to filter on (the class of this object will - * NOT be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set - * @param orderByAsc the property name of the - * PersistableEntity that should be used to order the + /** + * Find persistent instances with properties matching those of the passed PersistableEntity, + * ignoring the class of the passed PersistableEntity (useful if you pass a superclass, as you want + * to find all subclass instances which match). + * + * @param value parameters to filter on (the class of this object will NOT be added to the filter) + * @param firstElement the first result (start at zero to obtain all results) + * @param maxElements the maximum number of results desired for this page of the result set + * @param orderByAsc the property name of the PersistableEntity that should be used to order the * results * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements, String orderByAsc) throws DataAccessException; + * @return the requested page of the result list (a properly formed PaginatedList is returned if no + * results match) + * + * @throws DataAccessException DOCUMENT ME! + */ + public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements, String orderByAsc) + throws DataAccessException; - /** - * Indicates whether the DAO instance provides persistence services for the - * specified class. + /** + * Indicates whether the DAO instance provides persistence services for the specified class. * - * @param clazz to test, which should be an implementation of - * PersistableEntity + * @param clazz to test, which should be an implementation of PersistableEntity * - * @return true or false, indicating whether or - * not the passed class is supported by this DAO instance + * @return true or false, indicating whether or not the passed class is supported by this + * DAO instance */ public boolean supports(Class clazz); /** * Update an object. * - * @param value to update, with the PersistableEntity having a - * non-null identifier + * @param value to update, with the PersistableEntity having a non-null identifier + * + * @throws DataAccessException DOCUMENT ME! */ public void update(E value) throws DataAccessException; } diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/DetachmentContextHolder.java b/domain/src/main/java/org/acegisecurity/domain/dao/DetachmentContextHolder.java index aa0498cadb..c5df4a286a 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/DetachmentContextHolder.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/DetachmentContextHolder.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,11 @@ package org.acegisecurity.domain.dao; - /** - * InheritableThreadLocal which indicates whether a {@link Dao} - * implementation should be forced to return a detached instance. - * - *

A detached instance is one which is no longer associated with the ORM - * mapper and changes will therefore not be transparently persisted to the database. - * - *

Not all Dao implementations support the concept of detached - * instances. + * InheritableThreadLocal which indicates whether a {@link Dao} implementation should be forced to + * return a detached instance.

A detached instance is one which is no longer associated with the ORM mapper and + * changes will therefore not be transparently persisted to the database.

+ *

Not all Dao implementations support the concept of detached instances.

* * @author Ben Alex * @version $Id$ @@ -32,26 +27,17 @@ package org.acegisecurity.domain.dao; * @see java.lang.InheritableThreadLocal */ public class DetachmentContextHolder { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== private static InheritableThreadLocal contextHolder = new InheritableThreadLocal(); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Sets whether or not detached domain object instances should be returned - * within the current thread of execution. - * - * @param alwaysReturnDetached if true then detached instances should be returned. - */ - public static void setForceReturnOfDetachedInstances(boolean alwaysReturnDetached) { - contextHolder.set(new Boolean(alwaysReturnDetached)); - } - - /** - * Returns the boolean value detachment policy which has been set for the current - * thread (defaults to false). + * Returns the boolean value detachment policy which has been set for the current thread (defaults to + * false). * + * @return DOCUMENT ME! */ public static boolean isForceReturnOfDetachedInstances() { if (contextHolder.get() == null) { @@ -60,4 +46,14 @@ public class DetachmentContextHolder { return contextHolder.get().booleanValue(); } + + /** + * Sets whether or not detached domain object instances should be returned within the current thread of + * execution. + * + * @param alwaysReturnDetached if true then detached instances should be returned. + */ + public static void setForceReturnOfDetachedInstances(boolean alwaysReturnDetached) { + contextHolder.set(new Boolean(alwaysReturnDetached)); + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/EvictionCapable.java b/domain/src/main/java/org/acegisecurity/domain/dao/EvictionCapable.java index e498afe507..00de8ed32a 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/EvictionCapable.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/EvictionCapable.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,20 +31,12 @@ import org.acegisecurity.domain.PersistableEntity; * @version $Id$ */ public interface EvictionCapable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Removes the indicated persistent instance from the DAO's internal - * map/session. - * - *

- * If the passed object does not exist in the internal map/session, the - * invocation has no effect. - *

- * - *

- * May throw an exception if the implementation so desires. - *

+ * Removes the indicated persistent instance from the DAO's internal map/session.

If the passed object + * does not exist in the internal map/session, the invocation has no effect.

+ *

May throw an exception if the implementation so desires.

* * @param entity to remove from the internal map/session */ diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/EvictionUtils.java b/domain/src/main/java/org/acegisecurity/domain/dao/EvictionUtils.java index 48612de0b7..5791acc13b 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/EvictionUtils.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/EvictionUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,83 +20,45 @@ import org.acegisecurity.domain.PersistableEntity; import org.springframework.util.Assert; import java.lang.reflect.Method; + import java.util.Collection; import java.util.Iterator; /** - * Convenience methods that support eviction of PersistableEntitys - * from those objects that implement {@link EvictionCapable}. + * Convenience methods that support eviction of PersistableEntitys from those objects that implement + * {@link EvictionCapable}. * * @author Ben Alex * @version $Id$ */ public class EvictionUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Evicts the PersistableEntity using the passed - * Object (provided that the passed Object - * implements EvictionCapable). + * Evicts the PersistableEntity using the passed Object (provided that the passed + * Object implements EvictionCapable). * - * @param daoOrServices the potential source for - * EvictionCapable services (never null) + * @param daoOrServices the potential source for EvictionCapable services (never null) * @param entity to evict (can be null) */ - public static void evictIfRequired(Object daoOrServices, - PersistableEntity entity) { + public static void evictIfRequired(Object daoOrServices, PersistableEntity entity) { EvictionCapable evictor = getEvictionCapable(daoOrServices); - if (evictor != null && entity != null) { + if ((evictor != null) && (entity != null)) { evictor.evict(entity); } } /** - * Evicts the PersistableEntity using the passed - * Object (provided that the passed Object - * implements EvictionCapable), along with expressly - * evicting every PersistableEntity returned by the - * PersistableEntity's getters. - * - * @param daoOrServices the potential source for - * EvictionCapable services (never null) - * @param entity to evict includnig its getter results (can be null) - */ - public static void evictPopulatedIfRequired(Object daoOrServices, - PersistableEntity entity) { - EvictionCapable evictor = getEvictionCapable(daoOrServices); - - if (evictor != null && entity != null) { - evictor.evict(entity); - - Method[] methods = entity.getClass().getMethods(); - for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().startsWith("get") && methods[i].getParameterTypes().length == 0) { - try { - Object result = methods[i].invoke(entity, new Object[] {}); - if (result instanceof PersistableEntity) { - evictor.evict((PersistableEntity) result); - } - } catch (Exception ignored) {} - } - } - - } - } - - /** - * Evicts each PersistableEntity element of the passed - * Collection using the passed Object (provided - * that the passed Object implements + * Evicts each PersistableEntity element of the passed Collection using the + * passed Object (provided that the passed Object implements * EvictionCapable). * - * @param daoOrServices the potential source for - * EvictionCapable services (never null) + * @param daoOrServices the potential source for EvictionCapable services (never null) * @param collection whose members to evict (never null) */ - public static void evictIfRequired(Object daoOrServices, - Collection collection) { + public static void evictIfRequired(Object daoOrServices, Collection collection) { Assert.notNull(collection, "Cannot evict a null Collection"); if (getEvictionCapable(daoOrServices) == null) { @@ -104,7 +66,7 @@ public class EvictionUtils { return; } - Iterator iter = collection.iterator(); + Iterator iter = collection.iterator(); while (iter.hasNext()) { Object obj = iter.next(); @@ -116,17 +78,45 @@ public class EvictionUtils { } /** - * Obtain the EvictionCapable from the passed argument, or - * null. + * Evicts the PersistableEntity using the passed Object (provided that the passed + * Object implements EvictionCapable), along with expressly evicting every + * PersistableEntity returned by the PersistableEntity's getters. + * + * @param daoOrServices the potential source for EvictionCapable services (never null) + * @param entity to evict includnig its getter results (can be null) + */ + public static void evictPopulatedIfRequired(Object daoOrServices, PersistableEntity entity) { + EvictionCapable evictor = getEvictionCapable(daoOrServices); + + if ((evictor != null) && (entity != null)) { + evictor.evict(entity); + + Method[] methods = entity.getClass().getMethods(); + + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().startsWith("get") && (methods[i].getParameterTypes().length == 0)) { + try { + Object result = methods[i].invoke(entity, new Object[] {}); + + if (result instanceof PersistableEntity) { + evictor.evict((PersistableEntity) result); + } + } catch (Exception ignored) {} + } + } + } + } + + /** + * Obtain the EvictionCapable from the passed argument, or null. * * @param daoOrServices to check if provides eviction services * - * @return the EvictionCapable object or null if - * the object does not provide eviction services + * @return the EvictionCapable object or null if the object does not provide eviction + * services */ private static EvictionCapable getEvictionCapable(Object daoOrServices) { - Assert.notNull(daoOrServices, - "Cannot evict if the object that may provide EvictionCapable is null"); + Assert.notNull(daoOrServices, "Cannot evict if the object that may provide EvictionCapable is null"); if (daoOrServices instanceof EvictionCapable) { return (EvictionCapable) daoOrServices; diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java index acc1eac242..7e4536b55c 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,25 +60,22 @@ package org.acegisecurity.domain.dao; * @version $Id$ */ public interface InitializationCapable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Initializes the indicated object. - * - *

- * May throw an exception if the implementation so desires. - *

+ * Initializes the indicated object.

May throw an exception if the implementation so desires.

* * @param entity to initialize */ public void initialize(Object entity); - - /** - * Indicaets whether the passed object is initialized or not. - * - * @param entity to determine if initialized - * @return true if initialized, false is uninitialized or - * the initialization status is unknown - */ - public boolean isInitialized(Object entity); + + /** + * Indicaets whether the passed object is initialized or not. + * + * @param entity to determine if initialized + * + * @return true if initialized, false is uninitialized or the initialization status is + * unknown + */ + public boolean isInitialized(Object entity); } diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java index 5d24342025..1d2ca782f1 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,50 +18,49 @@ package org.acegisecurity.domain.dao; import org.springframework.util.Assert; - /** - * Convenience methods that support initialization of lazily loaded collections - * and associations using DAOs and other objects that implement - * {@link org.acegisecurity.domain.dao.InitializationCapable}. + * Convenience methods that support initialization of lazily loaded collections and associations using DAOs and + * other objects that implement {@link org.acegisecurity.domain.dao.InitializationCapable}. * * @author Ben Alex * @version $Id$ */ public class InitializationUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Initializes the passed entity using the passed - * DAO or services layer Object (provided that the passed - * Object implements InitializationCapable). + * Initializes the passed entity using the passed DAO or services layer Object (provided that + * the passed Object implements InitializationCapable). * - * @param daoOrServices the potential source for - * InitializationCapable services (never null) + * @param daoOrServices the potential source for InitializationCapable services (never + * null) * @param entity to evict (can be null) */ - public static void initializeIfRequired(Object daoOrServices, - Object entity) { - Assert.notNull(daoOrServices); - if (daoOrServices instanceof InitializationCapable) { - ((InitializationCapable) daoOrServices).initialize(entity); - } + public static void initializeIfRequired(Object daoOrServices, Object entity) { + Assert.notNull(daoOrServices); + + if (daoOrServices instanceof InitializationCapable) { + ((InitializationCapable) daoOrServices).initialize(entity); + } + } + + /** + * Indicates whether the passed entity has been initialized, by delegating to the passed daoOrServices + * (provided that the passed daoOrServices implements InitializationCapable. + * + * @param daoOrServices DOCUMENT ME! + * @param entity to determine whether initialized or not + * + * @return true if initialized, false if it is uninitialized or the passed daoOrServices + * does not provide initialization querying support + */ + public static boolean isInitialized(Object daoOrServices, Object entity) { + Assert.notNull(daoOrServices); + + if (daoOrServices instanceof InitializationCapable) { + return ((InitializationCapable) daoOrServices).isInitialized(entity); + } + + return false; } - - /** - * Indicates whether the passed entity has been initialized, by delegating - * to the passed daoOrServices (provided that the passed daoOrServices - * implements InitializationCapable. - * - * @param entity to determine whether initialized or not - * @return true if initialized, false if it is - * uninitialized or the passed daoOrServices does not provide - * initialization querying support - */ - public static boolean isInitialized(Object daoOrServices, Object entity) { - Assert.notNull(daoOrServices); - if (daoOrServices instanceof InitializationCapable) { - return ((InitializationCapable) daoOrServices).isInitialized(entity); - } - return false; - } } diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/PaginatedList.java b/domain/src/main/java/org/acegisecurity/domain/dao/PaginatedList.java index dee47b05fc..3fbe6c4755 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/PaginatedList.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/PaginatedList.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,44 +29,34 @@ import java.util.Vector; /** - *

- * JDK1.5 compatible paginated List. - *

- * - *

- * Elements in the internal List (see {@link #getList()} represent - * only part of a larger resultset. - *

- * - *

- * Note that firstElement starts at zero. Any attempt to access other than the - * current page will cause an error. - *

- * - *

- * This is a read only implementation and many of the List - * methods are not implemented. - *

+ *

JDK1.5 compatible paginated List.

+ *

Elements in the internal List (see {@link #getList()} represent only part of a larger + * resultset.

+ *

Note that firstElement starts at zero. Any attempt to access other than the current page will cause an + * error.

+ *

This is a read only implementation and many of the List methods are not implemented.

* * @author Carlos Sanchez * @author Ben Alex * @version $Id$ + * + * @param DOCUMENT ME! */ public class PaginatedList implements List { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - protected final transient Log logger = LogFactory.getLog(getClass()); private List list; + protected final transient Log logger = LogFactory.getLog(getClass()); private int firstElement; private int maxElements; private int size; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== // TODO: Consider removing this constructor public PaginatedList() {} - /** +/** * Used to construct a PaginatedList which contains only the * given entity. * @@ -96,95 +86,7 @@ public class PaginatedList implements List { this.size = size; } - //~ Methods ================================================================ - - /** - * Unsupported operation - * - * @return DOCUMENT ME! - * - * @throws UnsupportedOperationException - * - * @see java.util.Collection#isEmpty() - */ - public boolean isEmpty() { - throw new UnsupportedOperationException(); - } - - public void setFirstElement(int firstElement) { - this.firstElement = firstElement; - } - - /** - * First element of this page, starting at zero. - * - * @return - */ - public int getFirstElement() { - return firstElement; - } - - /** - * Calculate the last page number, starting at 0 - * - * @return - */ - public int getLastPageNumber() { - return (size() - 1) / getMaxElements(); - } - - public void setList(List list) { - this.list = list; - } - - /** - * Get list with the elements of this page. - * - * @return this page of the results - */ - public List getList() { - return list; - } - - public void setMaxElements(int maxElements) { - this.maxElements = maxElements; - } - - /** - * Max number of elements in the page - * - * @return - */ - public int getMaxElements() { - return maxElements; - } - - /** - * Calculate the page number, starting at 0 - * - * @return - */ - public int getPageNumber() { - return getFirstElement() / getMaxElements(); - } - - /** - * Number of elements in this page - * - * @return - */ - public int getPageSize() { - return list.size(); - } - - /** - * Set the number of elements in all the pages - * - * @param size DOCUMENT ME! - */ - public void setSize(int size) { - this.size = size; - } + //~ Methods ======================================================================================================== /** * Unsupported operation @@ -226,7 +128,7 @@ public class PaginatedList implements List { * * @see java.util.Collection#addAll(java.util.Collection) */ - public boolean addAll(Collection arg0) { + public boolean addAll(Collection arg0) { throw new UnsupportedOperationException(); } @@ -242,7 +144,7 @@ public class PaginatedList implements List { * * @see java.util.List#addAll(int, java.util.Collection) */ - public boolean addAll(int arg0, Collection arg1) { + public boolean addAll(int arg0, Collection arg1) { throw new UnsupportedOperationException(); } @@ -300,6 +202,60 @@ public class PaginatedList implements List { return list.get(arg0); } + /** + * First element of this page, starting at zero. + * + * @return + */ + public int getFirstElement() { + return firstElement; + } + + /** + * Calculate the last page number, starting at 0 + * + * @return + */ + public int getLastPageNumber() { + return (size() - 1) / getMaxElements(); + } + + /** + * Get list with the elements of this page. + * + * @return this page of the results + */ + public List getList() { + return list; + } + + /** + * Max number of elements in the page + * + * @return + */ + public int getMaxElements() { + return maxElements; + } + + /** + * Calculate the page number, starting at 0 + * + * @return + */ + public int getPageNumber() { + return getFirstElement() / getMaxElements(); + } + + /** + * Number of elements in this page + * + * @return + */ + public int getPageSize() { + return list.size(); + } + /** * Unsupported operation * @@ -315,6 +271,19 @@ public class PaginatedList implements List { throw new UnsupportedOperationException(); } + /** + * Unsupported operation + * + * @return DOCUMENT ME! + * + * @throws UnsupportedOperationException + * + * @see java.util.Collection#isEmpty() + */ + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + public Iterator iterator() { return new PaginatedListIterator(); } @@ -438,6 +407,27 @@ public class PaginatedList implements List { throw new UnsupportedOperationException(); } + public void setFirstElement(int firstElement) { + this.firstElement = firstElement; + } + + public void setList(List list) { + this.list = list; + } + + public void setMaxElements(int maxElements) { + this.maxElements = maxElements; + } + + /** + * Set the number of elements in all the pages + * + * @param size DOCUMENT ME! + */ + public void setSize(int size) { + this.size = size; + } + /** * Number of elements in all the pages * @@ -469,67 +459,61 @@ public class PaginatedList implements List { public T[] toArray(T[] arg0) { if (logger.isDebugEnabled()) { - logger.debug("List size when convert to array " - + list.toArray().length); + logger.debug("List size when convert to array " + list.toArray().length); } return list.toArray(arg0); } - - - private class PaginatedListIterator implements Iterator { - //~ Instance fields ======================================================== - private Iterator iterator; - private int i = 0; + //~ Inner Classes ================================================================================================== - /** - * @see java.util.Iterator#hasNext() - */ - public boolean hasNext() { - return i < size(); - } + private class PaginatedListIterator implements Iterator { + private Iterator iterator; + private int i = 0; - /** - * This method follows the rules of Iterator.next() except that it returns - * null when requesting an element that it's not in the current page. - * - * @see java.util.Iterator#next() - */ - public E next() { - if (i == getFirstElement()) { - iterator = getList().iterator(); - } + /** + * + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return i < size(); + } - if ((i >= getFirstElement()) - && (i < (getFirstElement() + getMaxElements()))) { - i++; + /** + * This method follows the rules of Iterator.next() except that it returns null when requesting an + * element that it's not in the current page. + * + * @see java.util.Iterator#next() + */ + public E next() { + if (i == getFirstElement()) { + iterator = getList().iterator(); + } - return iterator.next(); - } + if ((i >= getFirstElement()) && (i < (getFirstElement() + getMaxElements()))) { + i++; - if (hasNext()) { - i++; + return iterator.next(); + } - return null; - } else { - throw new NoSuchElementException(); - } - } + if (hasNext()) { + i++; - /** - * Unsupported operation - * - * @throws UnsupportedOperationException - * - * @see java.util.Iterator#remove() - */ - public void remove() { - throw new UnsupportedOperationException(); - } - } - - - - + return null; + } else { + throw new NoSuchElementException(); + } + } + + /** + * Unsupported operation + * + * @throws UnsupportedOperationException + * + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java b/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java index a98e785510..5f79d19def 100644 --- a/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java +++ b/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,28 +15,35 @@ package org.acegisecurity.domain.hibernate; -import java.io.Serializable; -import java.util.Collection; -import java.util.List; - import org.acegisecurity.domain.PersistableEntity; import org.acegisecurity.domain.dao.Dao; import org.acegisecurity.domain.dao.PaginatedList; import org.acegisecurity.domain.util.GenericsUtils; + import org.hibernate.Criteria; import org.hibernate.EntityMode; import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; + import org.hibernate.criterion.Expression; import org.hibernate.criterion.Order; + import org.hibernate.metadata.ClassMetadata; + import org.hibernate.type.Type; + import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + import org.springframework.util.Assert; +import java.io.Serializable; + +import java.util.Collection; +import java.util.List; + /** * Generics supporting {@link Dao} implementation that uses Hibernate 3 for persistence. @@ -44,23 +51,27 @@ import org.springframework.util.Assert; * @author Ben Alex * @author Matthew Porter * @version $Id$ + * + * @param DOCUMENT ME! */ public class DaoHibernate extends HibernateDaoSupport implements Dao { - //~ Instance fields ======================================================== - + //~ Instance fields ================================================================================================ + /** The class that this instance provides services for */ private Class supportsClass; - public DaoHibernate(SessionFactory sessionFactory) { - Assert.notNull(sessionFactory, "Non-null Hibernate SessionFactory must be expressed as a constructor argument"); - super.setSessionFactory(sessionFactory); - this.supportsClass = GenericsUtils.getGeneric(getClass()); - Assert.notNull(this.supportsClass, "Could not determine the generics type"); - } - - //~ Methods ================================================================ + //~ Constructors =================================================================================================== - public void create(E value) { + public DaoHibernate(SessionFactory sessionFactory) { + Assert.notNull(sessionFactory, "Non-null Hibernate SessionFactory must be expressed as a constructor argument"); + super.setSessionFactory(sessionFactory); + this.supportsClass = GenericsUtils.getGeneric(getClass()); + Assert.notNull(this.supportsClass, "Could not determine the generics type"); + } + + //~ Methods ======================================================================================================== + + public void create(E value) { Assert.notNull(value); super.getHibernateTemplate().save(value); } @@ -71,60 +82,21 @@ public class DaoHibernate extends HibernateDaoSuppo } @SuppressWarnings("unchecked") - public List findAll() { + public List findAll() { return super.getHibernateTemplate().loadAll(supportsClass); } @SuppressWarnings("unchecked") - public List findId(Collection ids) { + public List findId(Collection ids) { Assert.notNull(ids, "Collection of IDs cannot be null"); Assert.notEmpty(ids, "There must be some values in the Collection list"); return (List) super.getHibernateTemplate().execute(getFindByIdCallback(ids)); } - @SuppressWarnings("unchecked") - public E readId(Serializable id) { - Assert.notNull(id); - return (E) getHibernateTemplate().load(supportsClass, id); - } - - @SuppressWarnings("unchecked") - public PaginatedList scroll(E value, int firstElement, - int maxElements, String orderByAsc) { - validateScrollMethod(value, firstElement, maxElements, orderByAsc); - return (PaginatedList) super.getHibernateTemplate().execute(getFindByValueCallback( - value.getClass(), value, firstElement, maxElements, Order.asc(orderByAsc))); - } - - @SuppressWarnings("unchecked") - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements, String orderByAsc) { - validateScrollMethod(value, firstElement, maxElements, orderByAsc); - return (PaginatedList) super.getHibernateTemplate().execute(getFindByValueCallback( - this.supportsClass, value, firstElement, maxElements, Order.asc(orderByAsc))); - } - - private void validateScrollMethod(E value, int firstElement, int MaxElements, String orderByAsc) { - Assert.notNull(value); - Assert.hasText(orderByAsc, - "An orderByAsc is required (why not use your identity property?)"); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this DAO supports"); - } - - public boolean supports(Class clazz) { - Assert.notNull(clazz); - return this.supportsClass.equals(clazz); - } - - public void update(E value) { - Assert.notNull(value); - super.getHibernateTemplate().update(value); - } - - /** - * Provides a HibernateCallback that will load a list of - * objects by a Collection of identities. + /** + * Provides a HibernateCallback that will load a list of objects by a Collection + * of identities. * * @param ids collection of identities to be loaded * @@ -136,11 +108,9 @@ public class DaoHibernate extends HibernateDaoSuppo throws HibernateException { Criteria criteria = session.createCriteria(supportsClass); - ClassMetadata classMetadata = getSessionFactory() - .getClassMetadata(supportsClass); + ClassMetadata classMetadata = getSessionFactory().getClassMetadata(supportsClass); - String idPropertyName = classMetadata - .getIdentifierPropertyName(); + String idPropertyName = classMetadata.getIdentifierPropertyName(); criteria.add(Expression.in(idPropertyName, ids)); return criteria.list(); @@ -149,11 +119,9 @@ public class DaoHibernate extends HibernateDaoSuppo } /** - * Get a new HibernateCallback for finding objects by a bean - * property values, paginating the results. Properties with null values - * and collections and empty Strings are ignored, as is any property with - * the "version" name. If the property is mapped as String find a partial - * match, otherwise find by exact match. + * Get a new HibernateCallback for finding objects by a bean property values, paginating the + * results. Properties with null values and collections and empty Strings are ignored, as is any property with the + * "version" name. If the property is mapped as String find a partial match, otherwise find by exact match. * * @param whichClass the class (and subclasses) which results will be limited to including * @param bean bean with the values of the parameters @@ -163,22 +131,23 @@ public class DaoHibernate extends HibernateDaoSuppo * * @return a PaginatedList containing the requested objects */ - private HibernateCallback getFindByValueCallback(final Class whichClass, final Object bean, final int firstElement, final int count, final Order order) { + private HibernateCallback getFindByValueCallback(final Class whichClass, final Object bean, final int firstElement, + final int count, final Order order) { return new HibernateCallback() { @SuppressWarnings("unchecked") - public Object doInHibernate(Session session) + public Object doInHibernate(Session session) throws HibernateException { - int paramCount = 0; - - StringBuffer queryString = new StringBuffer("from ").append(bean.getClass().getName()).append(" as queryTarget"); - - - ClassMetadata classMetadata = getSessionFactory() - .getClassMetadata(bean - .getClass()); + int paramCount = 0; + + StringBuffer queryString = new StringBuffer("from ").append(bean.getClass().getName()) + .append(" as queryTarget"); + + ClassMetadata classMetadata = getSessionFactory().getClassMetadata(bean.getClass()); + + Assert.notNull(classMetadata, + "ClassMetadata for " + bean.getClass() + + " unavailable from Hibernate - have you mapped this class against the SessionFactory?"); - Assert.notNull(classMetadata, "ClassMetadata for " + bean.getClass() + " unavailable from Hibernate - have you mapped this class against the SessionFactory?"); - /* get persistent properties */ Type[] propertyTypes = classMetadata.getPropertyTypes(); String[] propertyNames = classMetadata.getPropertyNames(); @@ -186,6 +155,7 @@ public class DaoHibernate extends HibernateDaoSuppo /* for each persistent property of the bean */ for (int i = 0; i < propertyNames.length; i++) { String name = propertyNames[i]; + // TODO: Check if EntityMode.POJO appropriate Object value = classMetadata.getPropertyValue(bean, name, EntityMode.POJO); @@ -213,42 +183,87 @@ public class DaoHibernate extends HibernateDaoSuppo Type type = classMetadata.getPropertyType(name); - if (type.equals(Hibernate.STRING)) { + if (type.equals(Hibernate.STRING)) { // if the property is mapped as String, find partial match if (paramCount == 0) { - queryString.append(" where "); + queryString.append(" where "); } else { - queryString.append(" and "); + queryString.append(" and "); } + paramCount++; - queryString.append("lower(queryTarget.").append(name).append(") like '%" + value.toString().toLowerCase() + "%'"); + queryString.append("lower(queryTarget.").append(name) + .append(") like '%" + value.toString().toLowerCase() + "%'"); } else { // find exact match if (paramCount == 0) { - queryString.append(" where "); + queryString.append(" where "); } else { - queryString.append(" and "); + queryString.append(" and "); } + paramCount++; queryString.append("queryTarget.").append(name).append(" = " + value); } } - + if (logger.isDebugEnabled()) { - logger.debug(queryString.toString()); + logger.debug(queryString.toString()); } - - // Determine number of rows - org.hibernate.Query countQuery = session.createQuery("select count(*) " + queryString.toString()); - int size = ((Integer) countQuery.iterate().next()).intValue(); - - // Obtain requested page of query - org.hibernate.Query query = session.createQuery(queryString.toString()); - query.setMaxResults(count); - query.setFirstResult(firstElement); - + + // Determine number of rows + org.hibernate.Query countQuery = session.createQuery("select count(*) " + queryString.toString()); + int size = ((Integer) countQuery.iterate().next()).intValue(); + + // Obtain requested page of query + org.hibernate.Query query = session.createQuery(queryString.toString()); + query.setMaxResults(count); + query.setFirstResult(firstElement); + return new PaginatedList(query.list(), firstElement, count, size); } }; } + + @SuppressWarnings("unchecked") + public E readId(Serializable id) { + Assert.notNull(id); + + return (E) getHibernateTemplate().load(supportsClass, id); + } + + @SuppressWarnings("unchecked") + public PaginatedList scroll(E value, int firstElement, int maxElements, String orderByAsc) { + validateScrollMethod(value, firstElement, maxElements, orderByAsc); + + return (PaginatedList) super.getHibernateTemplate() + .execute(getFindByValueCallback(value.getClass(), value, firstElement, maxElements, + Order.asc(orderByAsc))); + } + + @SuppressWarnings("unchecked") + public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements, String orderByAsc) { + validateScrollMethod(value, firstElement, maxElements, orderByAsc); + + return (PaginatedList) super.getHibernateTemplate() + .execute(getFindByValueCallback(this.supportsClass, value, firstElement, + maxElements, Order.asc(orderByAsc))); + } + + public boolean supports(Class clazz) { + Assert.notNull(clazz); + + return this.supportsClass.equals(clazz); + } + + public void update(E value) { + Assert.notNull(value); + super.getHibernateTemplate().update(value); + } + + private void validateScrollMethod(E value, int firstElement, int MaxElements, String orderByAsc) { + Assert.notNull(value); + Assert.hasText(orderByAsc, "An orderByAsc is required (why not use your identity property?)"); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this DAO supports"); + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java b/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java index f616b90114..e48f09c17e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java +++ b/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java @@ -1,98 +1,124 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.acegisecurity.domain.hibernate; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - - import org.acegisecurity.domain.util.GenericsUtils; -import org.hibernate.HibernateException; -import org.hibernate.usertype.UserType; + +import org.hibernate.HibernateException; + +import org.hibernate.usertype.UserType; + +import java.io.Serializable; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + /** * Java 1.5 enumeration compatible Hibernate 3 UserType. - * + * * @author Ben Alex * @version $Id$ + * + * @param DOCUMENT ME! */ -public class EnumUserType> implements UserType { - private Class clazz = null; - - @SuppressWarnings("unchecked") - protected EnumUserType() { - this.clazz = GenericsUtils.getGeneric(getClass()); - } - - private static final int[] SQL_TYPES = {Types.VARCHAR}; - public int[] sqlTypes() { - return SQL_TYPES; - } - - public Class returnedClass() { - return clazz; - } - - public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException { - String name = resultSet.getString(names[0]); - E result = null; - if (!resultSet.wasNull()) { - result = Enum.valueOf(clazz, name); - } - return result; - } - - public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException { - if (null == value) { - preparedStatement.setNull(index, Types.VARCHAR); - } else { - preparedStatement.setString(index, ((Enum)value).name()); - } - } - - public Object deepCopy(Object value) throws HibernateException{ - return value; - } - - public boolean isMutable() { - return false; - } - - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; - } +public class EnumUserType> implements UserType { + //~ Static fields/initializers ===================================================================================== - public Serializable disassemble(Object value) throws HibernateException { - return (Serializable)value; - } - - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; - } - public int hashCode(Object x) throws HibernateException { - return x.hashCode(); - } - public boolean equals(Object x, Object y) throws HibernateException { - if (x == y) - return true; - if (null == x || null == y) - return false; - return x.equals(y); - } -} \ No newline at end of file + private static final int[] SQL_TYPES = {Types.VARCHAR}; + + //~ Instance fields ================================================================================================ + + private Class clazz = null; + + //~ Constructors =================================================================================================== + + @SuppressWarnings("unchecked") + protected EnumUserType() { + this.clazz = GenericsUtils.getGeneric(getClass()); + } + + //~ Methods ======================================================================================================== + + public Object assemble(Serializable cached, Object owner) + throws HibernateException { + return cached; + } + + public Object deepCopy(Object value) throws HibernateException { + return value; + } + + public Serializable disassemble(Object value) throws HibernateException { + return (Serializable) value; + } + + public boolean equals(Object x, Object y) throws HibernateException { + if (x == y) { + return true; + } + + if ((null == x) || (null == y)) { + return false; + } + + return x.equals(y); + } + + public int hashCode(Object x) throws HibernateException { + return x.hashCode(); + } + + public boolean isMutable() { + return false; + } + + public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) + throws HibernateException, SQLException { + String name = resultSet.getString(names[0]); + E result = null; + + if (!resultSet.wasNull()) { + result = Enum.valueOf(clazz, name); + } + + return result; + } + + public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) + throws HibernateException, SQLException { + if (null == value) { + preparedStatement.setNull(index, Types.VARCHAR); + } else { + preparedStatement.setString(index, ((Enum) value).name()); + } + } + + public Object replace(Object original, Object target, Object owner) + throws HibernateException { + return original; + } + + public Class returnedClass() { + return clazz; + } + + public int[] sqlTypes() { + return SQL_TYPES; + } +} diff --git a/domain/src/main/java/org/acegisecurity/domain/hibernate/IntrospectionManagerHibernate.java b/domain/src/main/java/org/acegisecurity/domain/hibernate/IntrospectionManagerHibernate.java index d0b2435b46..a29ce8bf30 100644 --- a/domain/src/main/java/org/acegisecurity/domain/hibernate/IntrospectionManagerHibernate.java +++ b/domain/src/main/java/org/acegisecurity/domain/hibernate/IntrospectionManagerHibernate.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,60 +40,33 @@ import java.util.Map; /** - * {@link IntrospectionManager} that uses Hibernate metadata to locate - * children. - * - *

- * Add children objects are added to the List of children objects - * to validate, irrespective of whether a save/update/delete operation will - * cascade to them. This is not a perfect solution, but addresses most - * real-world validation requirements (you can always implement your own - * IntrospectionManager if you prefer). - *

- * - *

- * This implementation only adds properties of a parent object that have a - * Hibernate {@link net.sf.hibernate.type.Type} that indicates it is an object - * type (ie {@link net.sf.hibernate.type.Type#isObjectType()}). - *

+ * {@link IntrospectionManager} that uses Hibernate metadata to locate children.

Add children objects are added + * to the List of children objects to validate, irrespective of whether a save/update/delete operation + * will cascade to them. This is not a perfect solution, but addresses most real-world validation requirements (you + * can always implement your own IntrospectionManager if you prefer).

+ *

This implementation only adds properties of a parent object that have a Hibernate {@link + * net.sf.hibernate.type.Type} that indicates it is an object type (ie {@link + * net.sf.hibernate.type.Type#isObjectType()}).

* * @author Matthew Porter * @author Ben Alex */ -public class IntrospectionManagerHibernate implements IntrospectionManager, - InitializingBean { - //~ Instance fields ======================================================== +public class IntrospectionManagerHibernate implements IntrospectionManager, InitializingBean { + //~ Instance fields ================================================================================================ - private SessionFactory[] sessionFactories; private ValidationRegistryManager validationRegistryManager; + private SessionFactory[] sessionFactories; - //~ Methods ================================================================ - - public void setSessionFactories(SessionFactory[] sessionFactorys) { - this.sessionFactories = sessionFactorys; - } - - public SessionFactory[] getSessionFactories() { - return this.sessionFactories; - } - - public void setValidationRegistryManager( - ValidationRegistryManager validationRegistryManager) { - this.validationRegistryManager = validationRegistryManager; - } - - public ValidationRegistryManager getValidationRegistryManager() { - return validationRegistryManager; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(validationRegistryManager, "ValidationRegistryManager is required"); Assert.notNull(sessionFactories, "SessionFactories are required"); Assert.notEmpty(sessionFactories, "SessionFactories are required"); - + // Eagerly pre-register Validators for all Hibernate metadata-defined classes for (int i = 0; i < sessionFactories.length; i++) { - Map metadataMap = this.sessionFactories[i].getAllClassMetadata(); + Map metadataMap = this.sessionFactories[i].getAllClassMetadata(); Collection mappedClasses = metadataMap.keySet(); for (Iterator iter = mappedClasses.iterator(); iter.hasNext();) { @@ -103,11 +76,29 @@ public class IntrospectionManagerHibernate implements IntrospectionManager, } } + private ClassMetadata findMetadata(Class clazz) throws HibernateSystemException { + for (int i = 0; i < sessionFactories.length; i++) { + ClassMetadata result = sessionFactories[i].getClassMetadata(clazz); + + if (result != null) { + return result; + } + } + + return null; + } + + public SessionFactory[] getSessionFactories() { + return this.sessionFactories; + } + + public ValidationRegistryManager getValidationRegistryManager() { + return validationRegistryManager; + } + public void obtainImmediateChildren(Object parentObject, List allObjects) { - Assert.notNull(parentObject, - "Violation of interface contract: parentObject null"); - Assert.notNull(allObjects, - "Violation of interface contract: allObjects null"); + Assert.notNull(parentObject, "Violation of interface contract: parentObject null"); + Assert.notNull(allObjects, "Violation of interface contract: allObjects null"); ClassMetadata classMetadata = null; @@ -122,13 +113,14 @@ public class IntrospectionManagerHibernate implements IntrospectionManager, // Add this property to the List of Objects to validate // only if a Validator is registered for that Object AND - // the object is initialized (ie not lazy loaded) - if (this.validationRegistryManager.findValidator( - propertyType.getReturnedClass()) != null) { - Object childObject = classMetadata.getPropertyValue(parentObject, propertyNames[i], EntityMode.POJO); - if (childObject != null && Hibernate.isInitialized(childObject)) { + // the object is initialized (ie not lazy loaded) + if (this.validationRegistryManager.findValidator(propertyType.getReturnedClass()) != null) { + Object childObject = classMetadata.getPropertyValue(parentObject, propertyNames[i], + EntityMode.POJO); + + if ((childObject != null) && Hibernate.isInitialized(childObject)) { if (childObject instanceof Collection) { - allObjects.addAll((Collection)childObject); + allObjects.addAll((Collection) childObject); } else { allObjects.add(childObject); } @@ -140,14 +132,12 @@ public class IntrospectionManagerHibernate implements IntrospectionManager, throw new HibernateSystemException(he); } } - - private ClassMetadata findMetadata(Class clazz) throws HibernateSystemException { - for (int i = 0; i < sessionFactories.length; i++) { - ClassMetadata result = sessionFactories[i].getClassMetadata(clazz); - if (result != null) { - return result; - } - } - return null; + + public void setSessionFactories(SessionFactory[] sessionFactorys) { + this.sessionFactories = sessionFactorys; + } + + public void setValidationRegistryManager(ValidationRegistryManager validationRegistryManager) { + this.validationRegistryManager = validationRegistryManager; } } diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java b/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java index 3d194f74ec..9446d4df93 100644 --- a/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java +++ b/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,51 +17,41 @@ package org.acegisecurity.domain.impl; import org.acegisecurity.domain.PersistableEntity; + /** - * An abstract implementation of {@link - * org.acegisecurity.domain.PersistableEntity}. + * An abstract implementation of {@link org.acegisecurity.domain.PersistableEntity}. * * @author Ben Alex * @version $Id$ - * - * */ -public abstract class AbstractPersistableEntity extends BusinessObject - implements PersistableEntity { - //~ Static fields/initializers ============================================= +public abstract class AbstractPersistableEntity extends BusinessObject implements PersistableEntity { + //~ Static fields/initializers ===================================================================================== public static final int STARTING_VERSION = 0; - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private int version = STARTING_VERSION; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Indicates whether this persistable entity has been persisted yet. - * Determine based on whether the {@link #getInternalId()} returns - * null or a non-null value. - * - * @return true if the instance has not been persisted, - * false otherwise - */ - public boolean isNew() { - return (getInternalId() == null); - } - - /** - * Returns the version number, which should be managed by the persistence - * layer. - * - *

- * Initially all PersistableEntitys will commence with the - * version number defined by {@link #STARTING_VERSION}. - *

+ * Returns the version number, which should be managed by the persistence layer.

Initially all + * PersistableEntitys will commence with the version number defined by {@link #STARTING_VERSION}.

* * @return the version */ public int getVersion() { return version; } + + /** + * Indicates whether this persistable entity has been persisted yet. Determine based on whether the {@link + * #getInternalId()} returns null or a non-null value. + * + * @return true if the instance has not been persisted, false otherwise + */ + public boolean isNew() { + return (getInternalId() == null); + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java b/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java index b564ef4fe2..d7cdcd8dd9 100644 --- a/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java +++ b/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,15 +25,9 @@ import java.io.Serializable; /** - * A business domain object. - * - *

- * Only minimal convenience methods are provided by - * BusinessObject. Whilst many other methods could easily be - * offered (and overridden on an as-required basis) it is felt the default - * behaviour of {@link java.lang.Object} is widely understood and an - * appropriate default. - *

+ * A business domain object.

Only minimal convenience methods are provided by BusinessObject. Whilst + * many other methods could easily be offered (and overridden on an as-required basis) it is felt the default + * behaviour of {@link java.lang.Object} is widely understood and an appropriate default.

* * @author Carlos Sanchez * @author Ben Alex @@ -41,27 +35,20 @@ import java.io.Serializable; * @version $Id$ */ public abstract class BusinessObject implements Serializable, Cloneable { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ protected final transient Log logger = LogFactory.getLog(getClass()); - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Swallow cloning. - * - *

- * This method delegates to BeanUtils.cloneBean(). Please note that - * this class uses serialization to achieve a clone, so this may - * represent a performance issue in certain applications. In - * such circumstances you should override this method and provide - * alternative cloning logic. - *

+ * Swallow cloning.

This method delegates to BeanUtils.cloneBean(). Please note that this class uses + * serialization to achieve a clone, so this may represent a performance issue in certain applications. In such + * circumstances you should override this method and provide alternative cloning logic.

* * @return a clone of the current instance * - * @throws IllegalStateException if there are any problems with swallow - * cloning + * @throws CloneNotSupportedException if there are any problems with swallow cloning * * @see java.lang.Object#clone() * @see BeanUtils#cloneBean(Object) diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java index df41ca62da..5c761328c6 100644 --- a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java +++ b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,24 +25,27 @@ import java.io.Serializable; * @version $Id$ */ public abstract class PersistableEntityInteger extends AbstractPersistableEntity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Integer id; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains the persistence identity of this instance. + * + * @return DOCUMENT ME! */ public Integer getId() { - return this.id; - } - - /** - * Required solely because Hibernate - */ - public Serializable getInternalId() { - return this.id; + return this.id; } + /** + * Required solely because Hibernate + * + * @return DOCUMENT ME! + */ + public Serializable getInternalId() { + return this.id; + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java index 780ecad3a2..a9adf495b3 100644 --- a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java +++ b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,25 +25,27 @@ import java.io.Serializable; * @version $Id$ */ public abstract class PersistableEntityLong extends AbstractPersistableEntity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Long id; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Obtains the persistence identity of this instance. + * + * @return DOCUMENT ME! */ public Long getId() { - return this.id; + return this.id; } - + /** * Required solely because Hibernate + * + * @return DOCUMENT ME! */ public Serializable getInternalId() { - return this.id; + return this.id; } - - } diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableValue.java b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableValue.java index dfe7656bb2..51e0a45a95 100644 --- a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableValue.java +++ b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableValue.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,12 @@ package org.acegisecurity.domain.impl; /** - * A value object, which means a persistable business object that does - * not have its own persistence identity. - * - *

- * Every value object belongs to a single {@link - * org.acegisecurity.domain.impl.AbstractPersistableEntity}. This is - * necessary so that the value object has some sort of persistence - * relationship/ownership. - *

- * - *

- * In addition, a value object cannot be referenced from more than one - * PersistableEntity. Use a PersistableEntity - * instead of a PersistableValue if this is a design constraint. - *

+ * A value object, which means a persistable business object that does not have its own persistence + * identity.

Every value object belongs to a single {@link + * org.acegisecurity.domain.impl.AbstractPersistableEntity}. This is necessary so that the value object has some sort + * of persistence relationship/ownership.

+ *

In addition, a value object cannot be referenced from more than one PersistableEntity. Use a + * PersistableEntity instead of a PersistableValue if this is a design constraint.

* * @author Ben Alex * @version $Id$ diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java index 734f3da4d5..08eb94f85e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.acegisecurity.domain.service; import org.acegisecurity.domain.PersistableEntity; import org.acegisecurity.domain.dao.PaginatedList; + import org.springframework.dao.DataAccessException; import java.io.Serializable; @@ -24,6 +25,7 @@ import java.io.Serializable; import java.util.Collection; import java.util.List; + /** * Provides fundamental services layer capabilities for a single concrete {@link * PersistableEntity}, using JDK 1.5 generics. @@ -68,92 +70,82 @@ import java.util.List; * @version $Id$ */ public interface ImmutableManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Return all persistent instances, including subclasses. * - * @return all persistence instances (an empty List will be - * returned if no matches are found) + * @return all persistence instances (an empty List will be returned if no matches are found) + * + * @throws DataAccessException DOCUMENT ME! */ public List findAll() throws DataAccessException; /** - * Find a List of PersistableEntitys, searched by - * their identifiers. + * Find a List of PersistableEntitys, searched by their identifiers. * * @param ids collection of identifiers to locate * - * @return the values with those identifiers (an empty List - * will be returned if no matches are found) + * @return the values with those identifiers (an empty List will be returned if no matches are found) + * + * @throws DataAccessException DOCUMENT ME! */ - public List findId(Collection ids) throws DataAccessException; + public List findId(Collection ids) + throws DataAccessException; /** - * Load a persistent instance by its identifier, although some properties - * may be lazy loaded depending on the underlying DAO implementation and/or - * persistence engine mapping document. + * Load a persistent instance by its identifier, although some properties may be lazy loaded depending on + * the underlying DAO implementation and/or persistence engine mapping document. * - * @param id the identifier of the persistent instance desired to be - * retrieved + * @param id the identifier of the persistent instance desired to be retrieved * * @return the request item, or null if not found + * + * @throws DataAccessException DOCUMENT ME! */ public E readId(Serializable id) throws DataAccessException; /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity. - * - *

- * Persistent instances are matched on the basis of query by example. - * Properties whose value is null, empty - * Strings, and any Collections are ignored in - * the query by example evaluation. - *

+ * Find persistent instances with properties matching those of the passed PersistableEntity.

Persistent + * instances are matched on the basis of query by example. Properties whose value is null, empty + * Strings, and any Collections are ignored in the query by example evaluation.

* - * @param value parameters to filter on (the class of this object will - * be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set + * @param value parameters to filter on (the class of this object will be added to the filter) + * @param firstElement the first result (start at zero to obtain all results) + * @param maxElements the maximum number of results desired for this page of the result set * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) + * @return the requested page of the result list (a properly formed PaginatedList is returned if no + * results match) + * + * @throws DataAccessException DOCUMENT ME! */ - public PaginatedList scroll(E value, int firstElement, - int maxElements) throws DataAccessException; + public PaginatedList scroll(E value, int firstElement, int maxElements) + throws DataAccessException; - /** - * Find persistent instances with properties matching those of the passed - * PersistableEntity, ignoring the class of the passed - * PersistableEntity (useful if you pass a superclass, as you - * want to find all subclass instances which match). - * - * @param value parameters to filter on (the class of this object will - * NOT be added to the filter) - * @param firstElement the first result (start at zero to obtain all - * results) - * @param maxElements the maximum number of results desired for this page - * of the result set + /** + * Find persistent instances with properties matching those of the passed PersistableEntity, + * ignoring the class of the passed PersistableEntity (useful if you pass a superclass, as you want + * to find all subclass instances which match). * - * @return the requested page of the result list (a properly formed - * PaginatedList is returned if no results match) - */ - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements) throws DataAccessException; + * @param value parameters to filter on (the class of this object will NOT be added to the filter) + * @param firstElement the first result (start at zero to obtain all results) + * @param maxElements the maximum number of results desired for this page of the result set + * + * @return the requested page of the result list (a properly formed PaginatedList is returned if no + * results match) + * + * @throws DataAccessException DOCUMENT ME! + */ + public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements) + throws DataAccessException; - /** - * Indicates whether the DAO instance provides persistence services for the - * specified class. + /** + * Indicates whether the DAO instance provides persistence services for the specified class. * - * @param clazz to test, which should be an implementation of - * PersistableEntity + * @param clazz to test, which should be an implementation of PersistableEntity * - * @return true or false, indicating whether or - * not the passed class is supported by this DAO instance + * @return true or false, indicating whether or not the passed class is supported by this + * DAO instance */ public boolean supports(Class clazz); - } diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerEditor.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerEditor.java index 15aa6c5377..0283f93d8f 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerEditor.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerEditor.java @@ -1,55 +1,82 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.domain.service; -import java.beans.PropertyEditorSupport; - import org.acegisecurity.domain.PersistableEntity; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import java.beans.PropertyEditorSupport; + + /** - * Converts between a PersistableEntity's internal ID (expressed as a String - * and the corresponding PersistableEntity sourced from an ImmutableManager). - * + * Converts between a PersistableEntity's internal ID (expressed as a String and the corresponding + * PersistableEntity sourced from an ImmutableManager). + * * @author Ben Alex * @version $Id$ */ public class ImmutableManagerEditor extends PropertyEditorSupport { - protected final transient Log log = LogFactory.getLog(getClass()); - private ImmutableManager immutableManager; - - private final boolean fallbackToNull; + //~ Instance fields ================================================================================================ - public ImmutableManagerEditor(ImmutableManager immutableManager, boolean fallbackToNull) { - Assert.notNull(immutableManager, "ImmutableManager required"); - this.immutableManager = immutableManager; - this.fallbackToNull = fallbackToNull; - } + private ImmutableManager immutableManager; + protected final transient Log log = LogFactory.getLog(getClass()); + private final boolean fallbackToNull; + + //~ Constructors =================================================================================================== + + public ImmutableManagerEditor(ImmutableManager immutableManager, boolean fallbackToNull) { + Assert.notNull(immutableManager, "ImmutableManager required"); + this.immutableManager = immutableManager; + this.fallbackToNull = fallbackToNull; + } + + //~ Methods ======================================================================================================== - public void setAsText(String text) throws IllegalArgumentException { - if (this.fallbackToNull && !StringUtils.hasText(text)) { - // treat empty String as null value - setValue(null); - } - else { - Long id = new Long(text); - PersistableEntity value = immutableManager.readId(id); - - if (log.isDebugEnabled()) { - log.debug("Property Editor converted '" + text + "' to object: " + value); - } - setValue(value); - } - } - public String getAsText() { - String result = null; - if (getValue() != null) { - result = ((PersistableEntity) getValue()).getInternalId().toString(); - } - if (log.isDebugEnabled()) - log.debug("Property Editor returning: " + result); - return result; + String result = null; + + if (getValue() != null) { + result = ((PersistableEntity) getValue()).getInternalId().toString(); + } + + if (log.isDebugEnabled()) { + log.debug("Property Editor returning: " + result); + } + + return result; + } + + public void setAsText(String text) throws IllegalArgumentException { + if (this.fallbackToNull && !StringUtils.hasText(text)) { + // treat empty String as null value + setValue(null); + } else { + Long id = new Long(text); + PersistableEntity value = immutableManager.readId(id); + + if (log.isDebugEnabled()) { + log.debug("Property Editor converted '" + text + "' to object: " + value); + } + + setValue(value); + } } } diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java index 90ec9000cf..db249ab490 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,51 +15,54 @@ package org.acegisecurity.domain.service; -import java.io.Serializable; -import java.util.Collection; -import java.util.List; - import org.acegisecurity.domain.PersistableEntity; import org.acegisecurity.domain.dao.Dao; import org.acegisecurity.domain.dao.PaginatedList; import org.acegisecurity.domain.util.GenericsUtils; + import org.springframework.context.support.ApplicationObjectSupport; + import org.springframework.util.Assert; +import java.io.Serializable; + +import java.util.Collection; +import java.util.List; + + /** * Base {@link ImmutableManager} implementation. * * @author Ben Alex * @version $Id$ + * + * @param DOCUMENT ME! */ -public class ImmutableManagerImpl extends ApplicationObjectSupport implements ImmutableManager { - //~ Instance fields ======================================================== +public class ImmutableManagerImpl extends ApplicationObjectSupport + implements ImmutableManager { + //~ Instance fields ================================================================================================ /** The class that this instance provides services for */ private Class supportsClass; - - protected Dao dao; + protected Dao dao; + + //~ Constructors =================================================================================================== + + public ImmutableManagerImpl(Dao dao) { + // work out what domain object we support + this.supportsClass = GenericsUtils.getGeneric(getClass()); + Assert.notNull(this.supportsClass, "Could not determine the generics type"); + Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), + "supportClass is not an implementation of PersistableEntity"); - //~ Methods ================================================================ - - public ImmutableManagerImpl(Dao dao) { - // work out what domain object we support - this.supportsClass = GenericsUtils.getGeneric(getClass()); - Assert.notNull(this.supportsClass, "Could not determine the generics type"); - Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), "supportClass is not an implementation of PersistableEntity"); - // store the DAO and check it also supports our domain object type - Assert.notNull(dao, "Non-null DAO (that supports the same domain object class as this services layer) is required as a constructor argument"); - Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'"); - this.dao = dao; - } + Assert.notNull(dao, + "Non-null DAO (that supports the same domain object class as this services layer) is required as a constructor argument"); + Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'"); + this.dao = dao; + } - /** - * @return the sort order column to be used by default by the scroll methods - */ - protected String getDefaultSortOrder() { - return "id"; - } + //~ Methods ======================================================================================================== public List findAll() { return dao.findAll(); @@ -68,32 +71,43 @@ public class ImmutableManagerImpl extends Applicati public List findId(Collection ids) { Assert.notNull(ids, "Collection of IDs cannot be null"); Assert.notEmpty(ids, "There must be some values in the Collection list"); + return dao.findId(ids); } + /** + * + DOCUMENT ME! + * + * @return the sort order column to be used by default by the scroll methods + */ + protected String getDefaultSortOrder() { + return "id"; + } + public E readId(Serializable id) { Assert.notNull(id); + return dao.readId(id); } - public PaginatedList scroll(E value, int firstElement, - int maxElements) { + public PaginatedList scroll(E value, int firstElement, int maxElements) { Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder()); } - public PaginatedList scrollWithSubclasses(E value, int firstElement, - int maxElements) { - Assert.notNull(value); - Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); + public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements) { + Assert.notNull(value); + Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports"); - return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); - } + return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); + } - public boolean supports(Class clazz) { + public boolean supports(Class clazz) { Assert.notNull(clazz); + return this.supportsClass.equals(clazz); } } diff --git a/domain/src/main/java/org/acegisecurity/domain/util/CollectionUtils.java b/domain/src/main/java/org/acegisecurity/domain/util/CollectionUtils.java index c6aa7736b1..f76dca6793 100644 --- a/domain/src/main/java/org/acegisecurity/domain/util/CollectionUtils.java +++ b/domain/src/main/java/org/acegisecurity/domain/util/CollectionUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,19 +35,12 @@ import java.util.TreeSet; * @version $Id$ */ public class CollectionUtils { - //~ Methods ================================================================ - - public static boolean isCollection(Class theClass) { - return Collection.class.isAssignableFrom(theClass); - } - - public static boolean isMap(Class theClass) { - return Map.class.isAssignableFrom(theClass); - } + //~ Methods ======================================================================================================== /** * Add an object to a Set and return the result. * + * @param DOCUMENT ME! * @param set * @param object * @@ -62,6 +55,7 @@ public class CollectionUtils { /** * Add an object to a List and return the result. * + * @param DOCUMENT ME! * @param list * @param object * @@ -74,9 +68,10 @@ public class CollectionUtils { } /** - * Clone a Collection copying all its elements to a new one. If map is - * null return null. + * Clone a Collection copying all its elements to a new one. If map is null return + * null. * + * @param DOCUMENT ME! * @param collection * * @return @@ -98,37 +93,36 @@ public class CollectionUtils { } else if (Set.class.isAssignableFrom(clazz)) { clone = new HashSet(collection); } else { - throw new IllegalArgumentException("Unknown collection class: " - + clazz); + throw new IllegalArgumentException("Unknown collection class: " + clazz); } return clone; } /** - * Clone a Map copying all its elements to a new one. If the - * passed argument is null, the method will return - * null. + * Clone a Map copying all its elements to a new one. If the passed argument is + * null, the method will return null. * + * @param DOCUMENT ME! + * @param DOCUMENT ME! * @param map to copy * * @return a copy of the Map passed as an argument * - * @throws IllegalArgumentException if the Map implementation - * is not supported by this method + * @throws IllegalArgumentException if the Map implementation is not supported by this method */ - public static Map clone(Map map) { + public static Map clone(Map map) { if (map == null) { return null; } Class clazz = map.getClass(); - Map clone = null; + Map clone = null; if (SortedMap.class.isAssignableFrom(clazz)) { - clone = new TreeMap(map); + clone = new TreeMap(map); } else if (Map.class.isAssignableFrom(clazz)) { - clone = new HashMap(map); + clone = new HashMap(map); } else { throw new IllegalArgumentException("Unknown map class: " + clazz); } @@ -136,10 +130,18 @@ public class CollectionUtils { return clone; } + public static boolean isCollection(Class theClass) { + return Collection.class.isAssignableFrom(theClass); + } + + public static boolean isMap(Class theClass) { + return Map.class.isAssignableFrom(theClass); + } + /** - * Return a List (actually an {@link ArrayList}) with only - * that object. + * Return a List (actually an {@link ArrayList}) with only that object. * + * @param DOCUMENT ME! * @param object * * @return @@ -149,9 +151,9 @@ public class CollectionUtils { } /** - * Return a Set (actually a {@link HashSet}) with only that - * object. + * Return a Set (actually a {@link HashSet}) with only that object. * + * @param DOCUMENT ME! * @param object * * @return diff --git a/domain/src/main/java/org/acegisecurity/domain/util/EnumEditor.java b/domain/src/main/java/org/acegisecurity/domain/util/EnumEditor.java index e5e0f2f5d8..2a02378125 100644 --- a/domain/src/main/java/org/acegisecurity/domain/util/EnumEditor.java +++ b/domain/src/main/java/org/acegisecurity/domain/util/EnumEditor.java @@ -1,58 +1,93 @@ -package org.acegisecurity.domain.util; +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import java.beans.PropertyEditorSupport; +package org.acegisecurity.domain.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.util.StringUtils; +import java.beans.PropertyEditorSupport; + + +/** + * DOCUMENT ME! + * + * @author Ben Alex + * @version $Id$ + */ public class EnumEditor extends PropertyEditorSupport { - protected final transient Log log = LogFactory.getLog(getClass()); + //~ Instance fields ================================================================================================ - private final Class enumClass; + private final Class enumClass; + protected final transient Log log = LogFactory.getLog(getClass()); + private final boolean fallbackToNull; - private final boolean fallbackToNull; + //~ Constructors =================================================================================================== - /** - * Create a new EnumEditor, which can create an Enum by retrieving - * the map of enum keys. - * - *

The fallbackToNull indicates whether null should be returned if - * a null String is provided to the property editor or if the provided - * String could not be used to locate an Enum. If set to true, null - * will be returned. If set to false, IllegalArgumentException will be thrown. - */ - public > EnumEditor(Class enumClass, boolean fallbackToNull) { - this.enumClass = enumClass; - this.fallbackToNull = fallbackToNull; - } +/** + * Create a new EnumEditor, which can create an Enum by retrieving + * the map of enum keys. + * + *

The fallbackToNull indicates whether null should be returned if + * a null String is provided to the property editor or if the provided + * String could not be used to locate an Enum. If set to true, null + * will be returned. If set to false, IllegalArgumentException will be thrown. + */ + public >EnumEditor(Class enumClass, boolean fallbackToNull) { + this.enumClass = enumClass; + this.fallbackToNull = fallbackToNull; + } + + //~ Methods ======================================================================================================== - /** - * Parse the Enum from the given text. - */ - @SuppressWarnings("unchecked") - public void setAsText(String text) throws IllegalArgumentException { - if (this.fallbackToNull && !StringUtils.hasText(text)) { - // treat empty String as null value - setValue(null); - } - else { - Enum value = Enum.valueOf(this.enumClass, text); - - if (log.isDebugEnabled()) { - log.debug("Property Editor converted '" + text + "' to object: " + value); - } - setValue(value); - } - } - public String getAsText() { - String result = null; - if (getValue() != null) { - result = ((Enum) getValue()).name(); - } - if (log.isDebugEnabled()) - log.debug("Property Editor returning: " + result); - return result; + String result = null; + + if (getValue() != null) { + result = ((Enum) getValue()).name(); + } + + if (log.isDebugEnabled()) { + log.debug("Property Editor returning: " + result); + } + + return result; + } + + /** + * Parse the Enum from the given text. + * + * @param text DOCUMENT ME! + * + * @throws IllegalArgumentException DOCUMENT ME! + */ + @SuppressWarnings("unchecked") + public void setAsText(String text) throws IllegalArgumentException { + if (this.fallbackToNull && !StringUtils.hasText(text)) { + // treat empty String as null value + setValue(null); + } else { + Enum value = Enum.valueOf(this.enumClass, text); + + if (log.isDebugEnabled()) { + log.debug("Property Editor converted '" + text + "' to object: " + value); + } + + setValue(value); + } } } diff --git a/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java b/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java index 0121df8e29..71c8fbc326 100644 --- a/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java +++ b/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java @@ -1,3 +1,18 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.domain.util; import java.lang.reflect.ParameterizedType; @@ -11,13 +26,16 @@ import java.lang.reflect.Type; * @version $Id$ */ public class GenericsUtils { + //~ Methods ======================================================================================================== + /** * Locates the first generic declaration on a class. * * @param clazz The class to introspect + * * @return the first generic declaration, or null if cannot be determined */ - public static Class getGeneric(Class clazz) { + public static Class getGeneric(Class clazz) { Type genType = clazz.getGenericSuperclass(); if (genType instanceof ParameterizedType) { diff --git a/domain/src/main/java/org/acegisecurity/domain/util/ReflectionToStringBuilder.java b/domain/src/main/java/org/acegisecurity/domain/util/ReflectionToStringBuilder.java index 7b711a2051..4196f62e0e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/util/ReflectionToStringBuilder.java +++ b/domain/src/main/java/org/acegisecurity/domain/util/ReflectionToStringBuilder.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,51 +15,94 @@ package org.acegisecurity.domain.util; -import java.io.Serializable; -import java.lang.reflect.Field; -import java.text.DateFormat; -import java.util.Calendar; -import java.util.Collection; - import org.acegisecurity.domain.PersistableEntity; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.io.Serializable; + +import java.lang.reflect.Field; + +import java.text.DateFormat; + +import java.util.Calendar; +import java.util.Collection; + /** - * Customized Commons Lang ReflectionToStringBuilder - * that ignores collections and inaccessible (ie lazy-loaded) fields. + * Customized Commons Lang ReflectionToStringBuilder that ignores collections and inaccessible (ie + * lazy-loaded) fields. * * @author Carlos Sanchez * @author Ben Alex * @version $Id$ */ -public class ReflectionToStringBuilder - extends org.apache.commons.lang.builder.ReflectionToStringBuilder { - //~ Static fields/initializers ============================================= +public class ReflectionToStringBuilder extends org.apache.commons.lang.builder.ReflectionToStringBuilder { + //~ Static fields/initializers ===================================================================================== + + private static DateFormat formatter = DateFormat.getDateTimeInstance(); + + //~ Instance fields ================================================================================================ protected final transient Log logger = LogFactory.getLog(getClass()); - private static DateFormat formatter = DateFormat.getDateTimeInstance(); - - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ReflectionToStringBuilder(Object object) { super(object, ToStringStyle.MULTI_LINE_STYLE); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + protected boolean accept(Field field) { + // Ignore if field inaccessible or collection + try { + Object o = getValue(field); + + if (o != null) { + if (o instanceof PersistableEntity) { + Serializable id = ((PersistableEntity) o).getInternalId(); + + if (logger.isDebugEnabled()) { + logger.debug(field + " id: " + id); + } + } + + if (o instanceof Collection) { + int size = ((Collection) o).size(); + this.append(field.getName(), ""); + + if (logger.isDebugEnabled()) { + logger.debug(field + " size: " + size); + } + } + } + } catch (Exception fieldInaccessible) { + this.append(field.getName(), ""); + + if (logger.isDebugEnabled()) { + logger.debug("Inaccessible: " + field); + } + + return false; + } + + if (logger.isDebugEnabled()) { + logger.debug("Accessible: " + field); + } + + return true; + } /** - * Calendar fields are formatted with DateFormat.getDateTimeInstance() - * instead of using Calendar.toString(). + * Calendar fields are formatted with DateFormat.getDateTimeInstance() instead of using + * Calendar.toString(). * * @see org.apache.commons.lang.builder.ReflectionToStringBuilder#getValue(java.lang.reflect.Field) */ - protected Object getValue(Field f) - throws IllegalArgumentException, IllegalAccessException { + protected Object getValue(Field f) throws IllegalArgumentException, IllegalAccessException { Object value = super.getValue(f); if (Calendar.class.isInstance(value)) { @@ -70,38 +113,4 @@ public class ReflectionToStringBuilder return value; } } - - protected boolean accept(Field field) { - // Ignore if field inaccessible or collection - try { - Object o = getValue(field); - if (o != null) { - if (o instanceof PersistableEntity) { - Serializable id = ((PersistableEntity)o).getInternalId(); - if (logger.isDebugEnabled()) { - logger.debug(field + " id: " + id); - } - } - if (o instanceof Collection) { - int size = ((Collection)o).size(); - this.append(field.getName(), ""); - if (logger.isDebugEnabled()) { - logger.debug(field + " size: " + size); - } - } - } - } catch (Exception fieldInaccessible) { - this.append(field.getName(), ""); - if (logger.isDebugEnabled()) { - logger.debug("Inaccessible: " + field); - } - return false; - } - - if (logger.isDebugEnabled()) { - logger.debug("Accessible: " + field); - } - - return true; - } } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidation.java b/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidation.java index 88a58fb6c3..e2a9b3377e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidation.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidation.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,24 +34,16 @@ import org.springframework.validation.BindException; * @version $Id$ */ public interface BindBeforeValidation { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * This method will be called by infrastructure code before attempting to - * validate the object. Given this method is called prior to validation, - * implementations of this method should not assume the object is - * in a valid state. - * - *

- * Implementations should modify the object as required so that the - * Validator will succeed if user-controllable properties are - * correct. - *

+ * This method will be called by infrastructure code before attempting to validate the object. Given this + * method is called prior to validation, implementations of this method should not assume the object is in + * a valid state.

Implementations should modify the object as required so that the Validator + * will succeed if user-controllable properties are correct.

* - * @throws BindException if there are problems that the method wish to - * advise (note that the Validator should be allowed - * to determine errors in most cases, rather than this method - * doing so) + * @throws BindException if there are problems that the method wish to advise (note that the Validator + * should be allowed to determine errors in most cases, rather than this method doing so) */ public void bindSupport() throws BindException; } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidationUtils.java b/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidationUtils.java index bcf97ea82c..984cc98bf4 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidationUtils.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/BindBeforeValidationUtils.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,18 +21,17 @@ import org.springframework.validation.BindException; /** - * Convenience class that invokes the {@link BindBeforeValidation} interface if - * the passed domain object has requested it. + * Convenience class that invokes the {@link BindBeforeValidation} interface if the passed domain object has + * requested it. * * @author Ben Alex * @version $Id$ */ public class BindBeforeValidationUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Call {@link BindBeforeValidation#bindSupport()} if the domain object - * requests it. + * Call {@link BindBeforeValidation#bindSupport()} if the domain object requests it. * * @param domainObject to attempt to bind (never null) * diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/IntrospectionManager.java b/domain/src/main/java/org/acegisecurity/domain/validation/IntrospectionManager.java index e78cb2c546..2f35675f8c 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/IntrospectionManager.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/IntrospectionManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,25 +31,18 @@ import java.util.List; * @version $Id$ */ public interface IntrospectionManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Locates any direct children of a domain object. - * - *

- * Typically used with a {@link ValidationManager} to validate each of the - * located children. - *

- * - *

- * Implementations should only add the immediate layer of children. - * Grandchildren, great-grandchildren etc should not be added. - *

+ * Locates any direct children of a domain object.

Typically used with a {@link ValidationManager} to + * validate each of the located children.

+ *

Implementations should only add the immediate layer of children. Grandchildren, + * great-grandchildren etc should not be added.

* - * @param parentObject the immediate parent which all children should share - * (guaranteed to never be null) - * @param allObjects the list to which this method should append each - * immediate child (guaranteed to never be null) + * @param parentObject the immediate parent which all children should share (guaranteed to never be + * null) + * @param allObjects the list to which this method should append each immediate child (guaranteed to never be + * null) */ public void obtainImmediateChildren(Object parentObject, List allObjects); } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationAdvisor.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationAdvisor.java index eb8a13fdf5..c884d80430 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationAdvisor.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationAdvisor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,66 +26,48 @@ import java.lang.reflect.Method; /** - * Advisor for the {@link ValidationInterceptor}. - * - *

- * Intended to be used with Spring's - * DefaultAdvisorAutoProxyCreator. - *

- * - *

- * Registers {@link ValidationInterceptor} for every Method - * against a class that directly or through its superclasses implements {@link - * #supportsClass} and has a signature match those defined by {@link - * #methods}. - *

+ * Advisor for the {@link ValidationInterceptor}.

Intended to be used with Spring's + * DefaultAdvisorAutoProxyCreator.

+ *

Registers {@link ValidationInterceptor} for every Method against a class that directly or + * through its superclasses implements {@link #supportsClass} and has a signature match those defined by {@link + * #methods}.

* * @author Ben Alex * @version $Id$ */ -public class ValidationAdvisor extends StaticMethodMatcherPointcutAdvisor - implements InitializingBean { - //~ Instance fields ======================================================== +public class ValidationAdvisor extends StaticMethodMatcherPointcutAdvisor implements InitializingBean { + //~ Instance fields ================================================================================================ - private Class supportsClass; + private Class supportsClass; private String[] methods = {"create", "update", "createOrUpdate"}; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ValidationAdvisor(ValidationInterceptor advice) { super(advice); if (advice == null) { - throw new AopConfigException( - "Cannot construct a BindAndValidateAdvisor using a " + throw new AopConfigException("Cannot construct a BindAndValidateAdvisor using a " + "null BindAndValidateInterceptor"); } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setMethods(String[] methods) { - this.methods = methods; + public void afterPropertiesSet() throws Exception { + Assert.notNull(supportsClass, "A supportsClass is required"); + Assert.notNull(methods, "A list of valid methods is required"); + Assert.notEmpty(methods, "A list of valid methods is required"); } public String[] getMethods() { return methods; } - public void setSupportsClass(Class clazz) { - this.supportsClass = clazz; - } - public Class getSupportsClass() { return supportsClass; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(supportsClass, "A supportsClass is required"); - Assert.notNull(methods, "A list of valid methods is required"); - Assert.notEmpty(methods, "A list of valid methods is required"); - } - public boolean matches(Method m, Class targetClass) { // Check there are actual arguments if (m.getParameterTypes().length == 0) { @@ -112,4 +94,12 @@ public class ValidationAdvisor extends StaticMethodMatcherPointcutAdvisor return false; } + + public void setMethods(String[] methods) { + this.methods = methods; + } + + public void setSupportsClass(Class clazz) { + this.supportsClass = clazz; + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationInterceptor.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationInterceptor.java index 9f67e73ef0..1709cfc165 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationInterceptor.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationInterceptor.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,58 +30,42 @@ import org.springframework.util.Assert; /** - * Calls {@link ValidationManager} for method invocations. - * - *

- * For each method invocation, any argument that is assignable from {@link - * #argumentClasses} and is non-null will be passed to the - * {@link org.acegisecurity.domain.validation.ValidationManager} for - * processing. - *

+ * Calls {@link ValidationManager} for method invocations.

For each method invocation, any argument that is + * assignable from {@link #argumentClasses}and is non-null will be passed to the {@link + * org.acegisecurity.domain.validation.ValidationManager} for processing.

* * @author Ben Alex * @version $Id$ */ -public class ValidationInterceptor implements MethodInterceptor, - InitializingBean { - //~ Instance fields ======================================================== +public class ValidationInterceptor implements MethodInterceptor, InitializingBean { + //~ Instance fields ================================================================================================ protected final Log logger = LogFactory.getLog(getClass()); private ValidationManager validationManager; private Class[] argumentClasses = {BusinessObject.class, PersistableEntity.class}; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setArgumentClasses(Class[] argumentClasses) { - this.argumentClasses = argumentClasses; + public void afterPropertiesSet() throws Exception { + Assert.notNull(validationManager, "A ValidationManager is required"); + Assert.notEmpty(argumentClasses, "A list of business object classes to validate is required"); } public Class[] getArgumentClasses() { return argumentClasses; } - public void setValidationManager(ValidationManager validationManager) { - this.validationManager = validationManager; - } - public ValidationManager getValidationManager() { return validationManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(validationManager, "A ValidationManager is required"); - Assert.notEmpty(argumentClasses, - "A list of business object classes to validate is required"); - } - public Object invoke(MethodInvocation mi) throws Throwable { Object[] args = mi.getArguments(); for (int i = 0; i < args.length; i++) { if (shouldValidate(args[i])) { if (logger.isDebugEnabled()) { - logger.debug("ValidationInterceptor calling for: '" - + args[i] + "'"); + logger.debug("ValidationInterceptor calling for: '" + args[i] + "'"); } validationManager.validate(args[i]); @@ -91,6 +75,14 @@ public class ValidationInterceptor implements MethodInterceptor, return mi.proceed(); } + public void setArgumentClasses(Class[] argumentClasses) { + this.argumentClasses = argumentClasses; + } + + public void setValidationManager(ValidationManager validationManager) { + this.validationManager = validationManager; + } + private boolean shouldValidate(Object argument) { if (argument == null) { return false; diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManager.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManager.java index e6dcad1384..a3e9beffc3 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManager.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,25 +25,18 @@ import org.springframework.validation.BindException; * @version $Id$ */ public interface ValidationManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Validates the passed domain object, along with any children, - * grandchildren, great-grandchildren etc. - * - *

- * Before performing validation, implementations must execute {@link - * BindBeforeValidation} for any domain objects requesting it. - *

+ * Validates the passed domain object, along with any children, grandchildren, great-grandchildren etc.

Before + * performing validation, implementations must execute {@link BindBeforeValidation} for any domain objects + * requesting it.

* * @param domainObject to validate (cannot be null) * * @throws BindException if a validation problem occurs - * @throws ValidatorNotFoundException if no matching Validator - * could be found (and the implementation wishes to treat this as - * an exception condition as opposed to logging it and - * continuing). + * @throws ValidatorNotFoundException if no matching Validator could be found (and the implementation + * wishes to treat this as an exception condition as opposed to logging it and continuing). */ - public void validate(Object domainObject) - throws BindException, ValidatorNotFoundException; + public void validate(Object domainObject) throws BindException, ValidatorNotFoundException; } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManagerImpl.java index 8f21244a51..a358853ace 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,82 +40,124 @@ import java.util.Vector; * @author Matthew E. Porter * @version $Id$ */ -public class ValidationManagerImpl implements InitializingBean, - ValidationManager { - //~ Instance fields ======================================================== +public class ValidationManagerImpl implements InitializingBean, ValidationManager { + //~ Instance fields ================================================================================================ - protected final Log logger = LogFactory.getLog(getClass()); private IntrospectionManager introspectionManager; + protected final Log logger = LogFactory.getLog(getClass()); private ValidationRegistryManager validationRegistryManager = new ValidationRegistryManagerImpl(); private boolean strictValidation = true; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setIntrospectionManager( - IntrospectionManager introspectionManager) { - this.introspectionManager = introspectionManager; + public void afterPropertiesSet() throws Exception { + Assert.notNull(validationRegistryManager, "A ValidationRegistryManager is required"); + Assert.notNull(introspectionManager, "An IntrospectionManager is required"); + } + + private Validator findValidator(Class clazz) throws ValidatorNotFoundException { + Assert.notNull(clazz, "Class cannot be null"); + + Validator validator = this.validationRegistryManager.findValidator(clazz); + + if (validator == null) { + throw new ValidatorNotFoundException("No Validator found for class '" + clazz + "'"); + } + + return validator; } public IntrospectionManager getIntrospectionManager() { return introspectionManager; } - /** - * Indicates whether a {@link ValidatorNotFoundException} should be thrown - * if any domain object does not have a corresponding - * Validator. - * - *

- * Defaults to true. This is a reasonable default, as callers - * of ValidationManager should expect the object to support - * validation. - *

- * - * @param strictValidation set to false if you wish to - * silently ignore any domain object that is missing a - * Validator - */ - public void setStrictValidation(boolean strictValidation) { - this.strictValidation = strictValidation; + public ValidationRegistryManager getValidationRegistryManager() { + return validationRegistryManager; } public boolean isStrictValidation() { return strictValidation; } - public void setValidationRegistryManager( - ValidationRegistryManager validationRegistryManager) { - this.validationRegistryManager = validationRegistryManager; + /** + * Locates all immediate children of the passed parentObject, adding each of those immediate + * children to the allObjects list and then calling this same method for each of those immediate + * children.

Does not add the passed parentObject to the allObjects + * list. The caller of this method should ensure the parentObject is added to the list instead.

+ * + * @param parentObject the object we wish to locate all children for + * @param allObjects the list to add the located children to + */ + private void obtainAllChildren(Object parentObject, List allObjects) { + Assert.notNull(parentObject, "Violation of parentObject method contract"); + Assert.notNull(allObjects, "Violation of allObjects method contract"); + Assert.isTrue(allObjects.contains(parentObject), "List of objects missing the requested parentObject"); + + if (logger.isDebugEnabled()) { + logger.debug("Searching for children of " + parentObject); + } + + // Add immediate children of this domain object + List currentChildren = new Vector(); + introspectionManager.obtainImmediateChildren(parentObject, currentChildren); + + // Now iterate the children, adding their children to the object list + Iterator childrenIter = currentChildren.iterator(); + + while (childrenIter.hasNext()) { + Object childObject = childrenIter.next(); + + if (childObject != null) { + if (allObjects.contains(childObject)) { + if (logger.isDebugEnabled()) { + logger.debug("Already processed this object (will not re-add): " + childObject); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug( + "New child object found; adding child object to list of objects, and searching for its children: " + + childObject); + } + + allObjects.add(childObject); + obtainAllChildren(childObject, allObjects); + } + } + } } - public ValidationRegistryManager getValidationRegistryManager() { - return validationRegistryManager; - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(validationRegistryManager, - "A ValidationRegistryManager is required"); - Assert.notNull(introspectionManager, - "An IntrospectionManager is required"); + public void setIntrospectionManager(IntrospectionManager introspectionManager) { + this.introspectionManager = introspectionManager; } /** - * Validates the passed domain object, along with any children, - * grandchildren, great-grandchildren etc. + * Indicates whether a {@link ValidatorNotFoundException} should be thrown if any domain object does not + * have a corresponding Validator.

Defaults to true. This is a reasonable + * default, as callers of ValidationManager should expect the object to support validation.

+ * + * @param strictValidation set to false if you wish to silently ignore any domain object that is + * missing a Validator + */ + public void setStrictValidation(boolean strictValidation) { + this.strictValidation = strictValidation; + } + + public void setValidationRegistryManager(ValidationRegistryManager validationRegistryManager) { + this.validationRegistryManager = validationRegistryManager; + } + + /** + * Validates the passed domain object, along with any children, grandchildren, great-grandchildren etc. * * @param domainObject to validate (cannot be null) * * @throws BindException if a validation problem occurs - * @throws ValidatorNotFoundException if no matching Validator - * could be found for the object or its children (only ever thrown - * if the {@link #strictValidation}) was set to - * true). + * @throws ValidatorNotFoundException if no matching Validator could be found for the object or its + * children (only ever thrown if the {@link #strictValidation}) was set to true). */ - public void validate(Object domainObject) - throws BindException, ValidatorNotFoundException { + public void validate(Object domainObject) throws BindException, ValidatorNotFoundException { // Abort if null - Assert.notNull(domainObject, - "Cannot validate a null domain object, as unable to getClass()"); + Assert.notNull(domainObject, "Cannot validate a null domain object, as unable to getClass()"); // Construct a list of objects to be validated and adds self List allObjects = new Vector(); @@ -126,8 +168,7 @@ public class ValidationManagerImpl implements InitializingBean, // (list never contains null) obtainAllChildren(domainObject, allObjects); - Assert.notEmpty(allObjects, - "The list of objects to be validated was empty"); + Assert.notEmpty(allObjects, "The list of objects to be validated was empty"); // Process list of objects to be validated by validating each Iterator iter = allObjects.iterator(); @@ -137,12 +178,12 @@ public class ValidationManagerImpl implements InitializingBean, Class clazz = currentDomainObject.getClass(); DetachmentContextHolder.setForceReturnOfDetachedInstances(true); + try { // Call bindSupport() if this class wishes BindBeforeValidationUtils.bindIfRequired(currentDomainObject); - Errors errors = new BindException(currentDomainObject, - clazz.getName()); + Errors errors = new BindException(currentDomainObject, clazz.getName()); Validator v = findValidator(clazz); // Perform validation @@ -151,13 +192,11 @@ public class ValidationManagerImpl implements InitializingBean, // Handle validation outcome if (errors.getErrorCount() == 0) { if (logger.isDebugEnabled()) { - logger.debug("Validated '" + clazz + "' successfully using '" - + v.getClass() + "'"); + logger.debug("Validated '" + clazz + "' successfully using '" + v.getClass() + "'"); } } else { if (logger.isDebugEnabled()) { - logger.debug("Validated '" + clazz + "' using '" + v.getClass() - + "' but errors detected"); + logger.debug("Validated '" + clazz + "' using '" + v.getClass() + "' but errors detected"); } throw (BindException) errors; @@ -172,77 +211,10 @@ public class ValidationManagerImpl implements InitializingBean, } if (logger.isDebugEnabled()) { - logger.debug("Could not locate validator for class '" - + clazz + "'; skipping without error"); + logger.debug("Could not locate validator for class '" + clazz + "'; skipping without error"); } } finally { - DetachmentContextHolder.setForceReturnOfDetachedInstances(false); - } - } - } - - private Validator findValidator(Class clazz) - throws ValidatorNotFoundException { - Assert.notNull(clazz, "Class cannot be null"); - - Validator validator = this.validationRegistryManager.findValidator(clazz); - - if (validator == null) { - throw new ValidatorNotFoundException( - "No Validator found for class '" + clazz + "'"); - } - - return validator; - } - - /** - * Locates all immediate children of the passed parentObject, - * adding each of those immediate children to the allObjects - * list and then calling this same method for each of those immediate - * children. - * - *

- * Does not add the passed parentObject to the - * allObjects list. The caller of this method should ensure - * the parentObject is added to the list instead. - *

- * - * @param parentObject the object we wish to locate all children for - * @param allObjects the list to add the located children to - */ - private void obtainAllChildren(Object parentObject, List allObjects) { - Assert.notNull(parentObject, "Violation of parentObject method contract"); - Assert.notNull(allObjects, "Violation of allObjects method contract"); - Assert.isTrue(allObjects.contains(parentObject), - "List of objects missing the requested parentObject"); - - if (logger.isDebugEnabled()) { - logger.debug("Searching for children of " + parentObject); - } - - // Add immediate children of this domain object - List currentChildren = new Vector(); - introspectionManager.obtainImmediateChildren(parentObject, - currentChildren); - - // Now iterate the children, adding their children to the object list - Iterator childrenIter = currentChildren.iterator(); - - while (childrenIter.hasNext()) { - Object childObject = childrenIter.next(); - - if (childObject != null) { - if (allObjects.contains(childObject)) { - if (logger.isDebugEnabled()) { - logger.debug("Already processed this object (will not re-add): " + childObject); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("New child object found; adding child object to list of objects, and searching for its children: " + childObject); - } - allObjects.add(childObject); - obtainAllChildren(childObject, allObjects); - } + DetachmentContextHolder.setForceReturnOfDetachedInstances(false); } } } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManager.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManager.java index 882ff945ee..8237b8730e 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManager.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,16 +34,14 @@ import org.springframework.validation.Validator; * @version $Id$ */ public interface ValidationRegistryManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains the Validator that applies for a given domain - * object class. + * Obtains the Validator that applies for a given domain object class. * * @param domainClass that a Validator is required for * - * @return the Validator, or null if no - * Validator is known for the indicated + * @return the Validator, or null if no Validator is known for the indicated * domainClass */ public Validator findValidator(Class domainClass); diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java index f93db2d7e7..0ca4e57e3b 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,137 +15,140 @@ package org.acegisecurity.domain.validation; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; + +import org.springframework.util.Assert; + +import org.springframework.validation.Validator; + import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.util.Assert; -import org.springframework.validation.Validator; - /** - * A basic implementation of {@link ValidationRegistryManager}. - * - *

- * Locates Validators registered in bean factory. - *

- * - *

If more than one Validator can support a given object, the - * supporting Validators will be iterated and their bean factory - * defined bean names will be used to attempt to select the "best matching" - * Validator. The lowercase version of a given object's simplified - * class name will be searched within the bean names. If more than one - * Validator contains this search criteria, an exception will be - * thrown as the actual intended Validator is unidentifiable. - * - *

For example, say you had a PartyValidator which could validate - * com.foo.Party, and also its subclass, com.foo.Person. There is also a - * PersonValidator which can only validate Person. PartyValidator and - * PersonValidator are registered in the bean container as "partyValidator" - * and "personValidator". When ValidationRegistryManagerImpl - * is asked to return the Validator for Person, it will locate - * the two matching Validators in the bean container. As there - * are two matching, it will look at the lowercase representation of the - * bean names and see if either contain the lower simplified class name of - * the object being search for (com.foo.Person thus becomes simply "person"). - * ValidationRegistryManagerImpl will then correctly return the - * PersonValidator for Person. If the PartyValidator had been registered with - * an ambiguous bean name of say "personAndPartyValidator", both bean names - * would have matched and an exception would have been thrown. + * A basic implementation of {@link ValidationRegistryManager}.

Locates Validators registered in + * bean factory.

+ *

If more than one Validator can support a given object, the supporting Validators + * will be iterated and their bean factory defined bean names will be used to attempt to select the "best matching" + * Validator. The lowercase version of a given object's simplified class name will be searched within the + * bean names. If more than one Validator contains this search criteria, an exception will be thrown as + * the actual intended Validator is unidentifiable.

+ *

For example, say you had a PartyValidator which could validate com.foo.Party, and also its subclass, + * com.foo.Person. There is also a PersonValidator which can only validate Person. PartyValidator and PersonValidator + * are registered in the bean container as "partyValidator" and "personValidator". When + * ValidationRegistryManagerImpl is asked to return the Validator for Person, it will locate + * the two matching Validators in the bean container. As there are two matching, it will look at the + * lowercase representation of the bean names and see if either contain the lower simplified class name of the object + * being search for (com.foo.Person thus becomes simply "person"). ValidationRegistryManagerImpl will + * then correctly return the PersonValidator for Person. If the PartyValidator had been registered with an ambiguous + * bean name of say "personAndPartyValidator", both bean names would have matched and an exception would have been + * thrown.

* * @author Matthew E. Porter * @author Ben Alex * @version $Id$ */ -public class ValidationRegistryManagerImpl implements ValidationRegistryManager, - BeanFactoryAware { - //~ Static fields/initializers ============================================= - - //~ Instance fields ======================================================== +public class ValidationRegistryManagerImpl implements ValidationRegistryManager, BeanFactoryAware { + //~ Instance fields ================================================================================================ private ListableBeanFactory bf; - private Map validatorMap = new HashMap(); + private Map validatorMap = new HashMap(); - //~ Methods ================================================================ - - public void setBeanFactory(BeanFactory beanFactory) - throws BeansException { - Assert.isInstanceOf(ListableBeanFactory.class, beanFactory, - "BeanFactory must be ListableBeanFactory"); - this.bf = (ListableBeanFactory) beanFactory; - } + //~ Methods ======================================================================================================== public Validator findValidator(Class domainClass) { Assert.notNull(domainClass, "domainClass cannot be null"); - if (validatorMap.containsKey(domainClass)) { - if (validatorMap.get(domainClass) == null) { - return null; - } - return (Validator) this.bf.getBean((String)validatorMap.get(domainClass), Validator.class); - } - - // Attempt to find Validator via introspection - Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, Validator.class, true, true); - - // Search all Validators for those that support the class - Set candidateValidatorNames = new HashSet(); - Iterator iter = beans.keySet().iterator(); - while (iter.hasNext()) { - String beanName = iter.next(); - Validator validator = beans.get(beanName); - if (validator.supports(domainClass)) { - candidateValidatorNames.add(beanName); - } - } - - if (candidateValidatorNames.size() == 0) { - // No Validator found - this.validatorMap.put(domainClass, null); - return null; - } else if (candidateValidatorNames.size() == 1) { - // Only one Validator found, so return it - String validator = candidateValidatorNames.iterator().next(); - this.validatorMap.put(domainClass, validator); - return beans.get(validator); - } else { - // Try to locate an entry with simple class name in it - StringBuffer sb = new StringBuffer(); - Iterator iterCandidates = candidateValidatorNames.iterator(); - String lastFound = null; - int numberFound = 0; - while (iterCandidates.hasNext()) { - String candidate = iterCandidates.next(); - sb.append(candidate); - if (iterCandidates.hasNext()) { - sb.append(","); - } - if (candidate.toLowerCase().contains(domainClass.getSimpleName().toLowerCase())) { - numberFound++; - lastFound = candidate; - } - } - if (numberFound != 1) { - throw new IllegalArgumentException("More than one Validator found (" + sb.toString() + ") that supports '" + domainClass + "', but cannot determine the most specific Validator to use; give a hint by making bean name include the simple name of the target class ('" + domainClass.getSimpleName().toString() + "')"); - } - this.validatorMap.put(domainClass, lastFound); - return beans.get(lastFound); - } + if (validatorMap.containsKey(domainClass)) { + if (validatorMap.get(domainClass) == null) { + return null; + } + + return (Validator) this.bf.getBean((String) validatorMap.get(domainClass), Validator.class); + } + + // Attempt to find Validator via introspection + Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, Validator.class, true, true); + + // Search all Validators for those that support the class + Set candidateValidatorNames = new HashSet(); + Iterator iter = beans.keySet().iterator(); + + while (iter.hasNext()) { + String beanName = iter.next(); + Validator validator = beans.get(beanName); + + if (validator.supports(domainClass)) { + candidateValidatorNames.add(beanName); + } + } + + if (candidateValidatorNames.size() == 0) { + // No Validator found + this.validatorMap.put(domainClass, null); + + return null; + } else if (candidateValidatorNames.size() == 1) { + // Only one Validator found, so return it + String validator = candidateValidatorNames.iterator().next(); + this.validatorMap.put(domainClass, validator); + + return beans.get(validator); + } else { + // Try to locate an entry with simple class name in it + StringBuffer sb = new StringBuffer(); + Iterator iterCandidates = candidateValidatorNames.iterator(); + String lastFound = null; + int numberFound = 0; + + while (iterCandidates.hasNext()) { + String candidate = iterCandidates.next(); + sb.append(candidate); + + if (iterCandidates.hasNext()) { + sb.append(","); + } + + if (candidate.toLowerCase().contains(domainClass.getSimpleName().toLowerCase())) { + numberFound++; + lastFound = candidate; + } + } + + if (numberFound != 1) { + throw new IllegalArgumentException("More than one Validator found (" + sb.toString() + + ") that supports '" + domainClass + + "', but cannot determine the most specific Validator to use; give a hint by making bean name include the simple name of the target class ('" + + domainClass.getSimpleName().toString() + "')"); + } + + this.validatorMap.put(domainClass, lastFound); + + return beans.get(lastFound); + } } public void registerValidator(Class domainClass, String beanName) { Assert.notNull(domainClass, "domainClass cannot be null"); Assert.notNull(beanName, "beanName cannot be null"); - Assert.isTrue(this.bf.containsBean(beanName), "beanName not found in context"); - Assert.isInstanceOf(Validator.class, this.bf.getBean(beanName), "beanName '" + beanName + "' must be a Validator"); - Assert.isTrue(((Validator)this.bf.getBean(beanName)).supports(domainClass), "Validator does not support " + domainClass); - this.validatorMap.put(domainClass, beanName); + Assert.isTrue(this.bf.containsBean(beanName), "beanName not found in context"); + Assert.isInstanceOf(Validator.class, this.bf.getBean(beanName), + "beanName '" + beanName + "' must be a Validator"); + Assert.isTrue(((Validator) this.bf.getBean(beanName)).supports(domainClass), + "Validator does not support " + domainClass); + this.validatorMap.put(domainClass, beanName); + } + + public void setBeanFactory(BeanFactory beanFactory) + throws BeansException { + Assert.isInstanceOf(ListableBeanFactory.class, beanFactory, "BeanFactory must be ListableBeanFactory"); + this.bf = (ListableBeanFactory) beanFactory; } } diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidatorNotFoundException.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidatorNotFoundException.java index 9b5b73d51d..b9073a6a97 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidatorNotFoundException.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidatorNotFoundException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,15 @@ import org.acegisecurity.domain.DomainException; /** - * Thrown if no Validator could be found that supports a domain - * object presented for validation. + * Thrown if no Validator could be found that supports a domain object presented for validation. * * @author Ben Alex * @version $Id$ */ public class ValidatorNotFoundException extends DomainException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs a ValidatorNotFoundException with the specified * message and root cause. * @@ -39,7 +38,7 @@ public class ValidatorNotFoundException extends DomainException { super(msg, t); } - /** +/** * Constructs a DomainException with the specified message and * no root cause. * diff --git a/jalopy.xml b/jalopy.xml index e49add138a..a64f486f7a 100644 --- a/jalopy.xml +++ b/jalopy.xml @@ -327,7 +327,7 @@ -2147483647 +0 false false false @@ -351,10 +351,34 @@ false + + +2147483647 + + +true + + + + +2147483647 + + +true + + + + +2147483647 + + +true + + true true -80 +120 @@ -370,7 +394,13 @@ false + +false + false + +false + diff --git a/samples/acegifier/src/main/java/acegifier/WebXmlConverter.java b/samples/acegifier/src/main/java/acegifier/WebXmlConverter.java index e984d925b1..747605d68d 100644 --- a/samples/acegifier/src/main/java/acegifier/WebXmlConverter.java +++ b/samples/acegifier/src/main/java/acegifier/WebXmlConverter.java @@ -24,6 +24,7 @@ import org.springframework.util.Assert; /** * A utility to translate a web.xml file into a set of acegi security spring beans. * + *

* Also produces a new "acegified" web.xml file with the necessary filters installed * and the security elements defined by the servlet DTD removed. * diff --git a/samples/acegifier/src/main/java/acegifier/web/AcegifierController.java b/samples/acegifier/src/main/java/acegifier/web/AcegifierController.java index 2f460d5bcf..c5e64accc6 100644 --- a/samples/acegifier/src/main/java/acegifier/web/AcegifierController.java +++ b/samples/acegifier/src/main/java/acegifier/web/AcegifierController.java @@ -1,50 +1,89 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package acegifier.web; +import acegifier.WebXmlConverter; + +import org.acegisecurity.util.FilterChainProxy; +import org.acegisecurity.util.InMemoryResource; + +import org.dom4j.Document; +import org.dom4j.DocumentException; + +import org.dom4j.io.OutputFormat; +import org.dom4j.io.XMLWriter; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; + +import org.springframework.validation.BindException; +import org.springframework.validation.Errors; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.SimpleFormController; + import java.io.ByteArrayOutputStream; import java.io.IOException; + import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + import javax.xml.transform.TransformerException; -import org.acegisecurity.util.FilterChainProxy; -import org.acegisecurity.util.InMemoryResource; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.XMLWriter; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.validation.BindException; -import org.springframework.validation.Errors; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.SimpleFormController; - -import acegifier.WebXmlConverter; /** - * Takes a submitted web.xml, applies the transformer to it and returns the resulting - * modified web.xml and acegi-app-context.xml file contents. + * Takes a submitted web.xml, applies the transformer to it and returns the resulting modified web.xml and + * acegi-app-context.xml file contents. * * @author Luke Taylor * @version $Id$ */ public class AcegifierController extends SimpleFormController { + //~ Constructors =================================================================================================== - public AcegifierController() { + public AcegifierController() {} + + //~ Methods ======================================================================================================== + + /** + * Creates a BeanFactory from the spring beans XML document + * + * @param beans DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private DefaultListableBeanFactory createBeanFactory(Document beans) { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + XmlBeanDefinitionReader beanReader = new XmlBeanDefinitionReader(bf); + beanReader.loadBeanDefinitions(new InMemoryResource(beans.asXML().getBytes())); + + return bf; } - public ModelAndView onSubmit( - HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) - throws Exception { - - AcegifierForm conversion = (AcegifierForm)command; + public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, + BindException errors) throws Exception { + AcegifierForm conversion = (AcegifierForm) command; WebXmlConverter converter = new WebXmlConverter(); int nBeans = 0; - Document newWebXml = null, acegiBeans = null; + Document newWebXml = null; + Document acegiBeans = null; try { converter.setInput(conversion.getWebXml()); @@ -53,12 +92,13 @@ public class AcegifierController extends SimpleFormController { acegiBeans = converter.getAcegiBeans(); nBeans = validateAcegiBeans(conversion, acegiBeans, errors); } catch (DocumentException de) { - errors.rejectValue("webXml","webXmlDocError","There was a problem with your web.xml: " + de.getMessage()); + errors.rejectValue("webXml", "webXmlDocError", "There was a problem with your web.xml: " + de.getMessage()); } catch (TransformerException te) { - errors.rejectValue("webXml","transFailure","There was an error during the XSL transformation: " + te.getMessage()); + errors.rejectValue("webXml", "transFailure", + "There was an error during the XSL transformation: " + te.getMessage()); } - if(errors.hasErrors()) { + if (errors.hasErrors()) { return showForm(request, response, errors); } @@ -70,42 +110,49 @@ public class AcegifierController extends SimpleFormController { return new ModelAndView("acegificationResults", model); } - /** Creates a formatted XML string from the supplied document */ + /** + * Creates a formatted XML string from the supplied document + * + * @param document DOCUMENT ME! + * + * @return DOCUMENT ME! + * + * @throws IOException DOCUMENT ME! + */ private String prettyPrint(Document document) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); OutputFormat format = OutputFormat.createPrettyPrint(); format.setTrimText(false); + XMLWriter writer = new XMLWriter(output, format); writer.write(document); writer.flush(); writer.close(); + return output.toString(); } /** - * Validates the acegi beans, based on the input form data, and returns the number - * of spring beans defined in the document. + * Validates the acegi beans, based on the input form data, and returns the number of spring beans defined + * in the document. + * + * @param conversion DOCUMENT ME! + * @param beans DOCUMENT ME! + * @param errors DOCUMENT ME! + * + * @return DOCUMENT ME! */ private int validateAcegiBeans(AcegifierForm conversion, Document beans, Errors errors) { DefaultListableBeanFactory bf = createBeanFactory(beans); //TODO: actually do some proper validation! - try { bf.getBean("filterChainProxy", FilterChainProxy.class); } catch (BeansException be) { - errors.rejectValue("webXml","beansInvalid","There was an error creating or accessing the bean factory " + be.getMessage()); + errors.rejectValue("webXml", "beansInvalid", + "There was an error creating or accessing the bean factory " + be.getMessage()); } + return bf.getBeanDefinitionCount(); } - - /** Creates a BeanFactory from the spring beans XML document */ - private DefaultListableBeanFactory createBeanFactory(Document beans) { - DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); - XmlBeanDefinitionReader beanReader = new XmlBeanDefinitionReader(bf); - beanReader.loadBeanDefinitions(new InMemoryResource(beans.asXML().getBytes())); - - return bf; - } - } diff --git a/samples/acegifier/src/main/java/acegifier/web/AcegifierForm.java b/samples/acegifier/src/main/java/acegifier/web/AcegifierForm.java index dfb6730242..986360bf94 100644 --- a/samples/acegifier/src/main/java/acegifier/web/AcegifierForm.java +++ b/samples/acegifier/src/main/java/acegifier/web/AcegifierForm.java @@ -1,3 +1,18 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package acegifier.web; /** @@ -7,8 +22,12 @@ package acegifier.web; * @version $Id$ */ public class AcegifierForm { + //~ Instance fields ================================================================================================ + private String webXml; + //~ Methods ======================================================================================================== + public String getWebXml() { return webXml; } diff --git a/samples/acegifier/src/test/java/acegifier/WebXmlConverterTests.java b/samples/acegifier/src/test/java/acegifier/WebXmlConverterTests.java index 41d51c8edd..80a037f7ff 100644 --- a/samples/acegifier/src/test/java/acegifier/WebXmlConverterTests.java +++ b/samples/acegifier/src/test/java/acegifier/WebXmlConverterTests.java @@ -1,25 +1,28 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package acegifier; import java.io.ByteArrayOutputStream; import java.io.IOException; -import javax.xml.transform.TransformerFactoryConfigurationError; - import junit.framework.TestCase; -import org.acegisecurity.providers.ProviderManager; -import org.acegisecurity.providers.dao.DaoAuthenticationProvider; -import org.acegisecurity.ui.ExceptionTranslationFilter; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.memory.InMemoryDaoImpl; -import org.acegisecurity.util.InMemoryResource; import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; /** * Tests the WebXmlConverter by applying it to a sample web.xml file. diff --git a/samples/annotations/src/main/java/sample/annotations/BankService.java b/samples/annotations/src/main/java/sample/annotations/BankService.java index a734322b63..4f37a70abe 100644 --- a/samples/annotations/src/main/java/sample/annotations/BankService.java +++ b/samples/annotations/src/main/java/sample/annotations/BankService.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package sample.annotations; import org.acegisecurity.annotation.Secured; + /** * BankService sample using Java 5 Annotations. * @@ -25,10 +26,9 @@ import org.acegisecurity.annotation.Secured; * * @see org.acegisecurity.annotation.Secured */ - -@Secured({"ROLE_TELLER" }) +@Secured({"ROLE_TELLER"}) public interface BankService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Get the account balance. @@ -37,8 +37,7 @@ public interface BankService { * * @return The balance */ - - @Secured({"ROLE_PERMISSION_BALANCE" }) + @Secured({"ROLE_PERMISSION_BALANCE"}) public float balance(String accountNumber); /** @@ -46,7 +45,6 @@ public interface BankService { * * @return The list of accounts */ - - @Secured({"ROLE_PERMISSION_LIST" }) + @Secured({"ROLE_PERMISSION_LIST"}) public String[] listAccounts(); } diff --git a/samples/annotations/src/main/java/sample/annotations/BankServiceImpl.java b/samples/annotations/src/main/java/sample/annotations/BankServiceImpl.java index 2582bc5528..a2b3a10907 100644 --- a/samples/annotations/src/main/java/sample/annotations/BankServiceImpl.java +++ b/samples/annotations/src/main/java/sample/annotations/BankServiceImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,12 @@ package sample.annotations; /** * BankService sample implementation. - * + * * @author Mark St.Godard * @version $Id$ */ public class BankServiceImpl implements BankService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public float balance(String accountNumber) { return 42000000; diff --git a/samples/annotations/src/main/java/sample/annotations/Main.java b/samples/annotations/src/main/java/sample/annotations/Main.java index 9e870caea2..56199097b4 100644 --- a/samples/annotations/src/main/java/sample/annotations/Main.java +++ b/samples/annotations/src/main/java/sample/annotations/Main.java @@ -1,11 +1,27 @@ -package sample.annotations; +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.annotations; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -13,11 +29,29 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; /** * +DOCUMENT ME! + * * @author Mark St.Godard * @version $Id$ */ public class Main { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + /** + * This can be done in a web app by using a filter or SpringMvcIntegrationInterceptor. + */ + private static void createSecureContext() { + TestingAuthenticationToken auth = new TestingAuthenticationToken("test", "test", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST") + }); + + SecurityContextHolder.getContext().setAuthentication(auth); + } + + private static void destroySecureContext() { + SecurityContextHolder.setContext(new SecurityContextImpl()); + } public static void main(String[] args) throws Exception { createSecureContext(); @@ -40,21 +74,4 @@ public class Main { destroySecureContext(); } - - /** - * This can be done in a web app by using a filter or - * SpringMvcIntegrationInterceptor. - */ - private static void createSecureContext() { - TestingAuthenticationToken auth = new TestingAuthenticationToken("test", - "test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl( - "ROLE_PERMISSION_LIST")}); - - SecurityContextHolder.getContext().setAuthentication(auth); - } - - private static void destroySecureContext() { - SecurityContextHolder.setContext(new SecurityContextImpl()); - } } diff --git a/samples/annotations/src/test/java/samples/annotations/BankTests.java b/samples/annotations/src/test/java/samples/annotations/BankTests.java index 1c5f737b32..d968d0bf9a 100644 --- a/samples/annotations/src/test/java/samples/annotations/BankTests.java +++ b/samples/annotations/src/test/java/samples/annotations/BankTests.java @@ -1,11 +1,29 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package samples.annotations; import junit.framework.TestCase; + import org.acegisecurity.AccessDeniedException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -14,69 +32,68 @@ import sample.annotations.BankService; /** -* Tests security objects. -* -* @author Ben Alex -* @version $Id$ -*/ + * Tests security objects. + * + * @author Ben Alex + * @version $Id$ + */ public class BankTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - private BankService service; - private ClassPathXmlApplicationContext ctx; + private BankService service; + private ClassPathXmlApplicationContext ctx; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public BankTests() { - super(); - } + public BankTests() { + super(); + } - public BankTests(String arg0) { - super(arg0); - } + public BankTests(String arg0) { + super(arg0); + } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public final void setUp() throws Exception { - super.setUp(); - ctx = new ClassPathXmlApplicationContext("applicationContext-annotations.xml"); - service = (BankService) ctx.getBean("bankService"); - } + private static void createSecureContext() { + TestingAuthenticationToken auth = new TestingAuthenticationToken("test", "test", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST") + }); - public static void main(String[] args) { - junit.textui.TestRunner.run(BankTests.class); - } + SecurityContextHolder.getContext().setAuthentication(auth); + } - public void testDeniedAccess() throws Exception { - createSecureContext(); + private static void destroySecureContext() { + SecurityContextHolder.setContext(new SecurityContextImpl()); + } - try { - service.balance("1"); - fail("Should have thrown AccessDeniedException"); - } catch (AccessDeniedException expected) { - assertTrue(true); - } + public static void main(String[] args) { + junit.textui.TestRunner.run(BankTests.class); + } - destroySecureContext(); - } + public final void setUp() throws Exception { + super.setUp(); + ctx = new ClassPathXmlApplicationContext("applicationContext-annotations.xml"); + service = (BankService) ctx.getBean("bankService"); + } - public void testListAccounts() throws Exception { - createSecureContext(); - service.listAccounts(); - destroySecureContext(); - } + public void testDeniedAccess() throws Exception { + createSecureContext(); - private static void createSecureContext() { - TestingAuthenticationToken auth = new TestingAuthenticationToken("test", - "test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl( - "ROLE_PERMISSION_LIST")}); + try { + service.balance("1"); + fail("Should have thrown AccessDeniedException"); + } catch (AccessDeniedException expected) { + assertTrue(true); + } - SecurityContextHolder.getContext().setAuthentication(auth); - } + destroySecureContext(); + } - private static void destroySecureContext() { - SecurityContextHolder.setContext(new SecurityContextImpl()); - } + public void testListAccounts() throws Exception { + createSecureContext(); + service.listAccounts(); + destroySecureContext(); + } } - diff --git a/samples/attributes/src/main/java/sample/attributes/BankService.java b/samples/attributes/src/main/java/sample/attributes/BankService.java index ea79505716..45ef0a9803 100644 --- a/samples/attributes/src/main/java/sample/attributes/BankService.java +++ b/samples/attributes/src/main/java/sample/attributes/BankService.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ package sample.attributes; * @author Ben Alex * @version $Id$ * - * @@net.sf.acegisecurity.SecurityConfig("ROLE_TELLER") */ public interface BankService { //~ Methods ================================================================ diff --git a/samples/attributes/src/main/java/sample/attributes/BankServiceImpl.java b/samples/attributes/src/main/java/sample/attributes/BankServiceImpl.java index 8cfbb8164c..b16d4e0b70 100644 --- a/samples/attributes/src/main/java/sample/attributes/BankServiceImpl.java +++ b/samples/attributes/src/main/java/sample/attributes/BankServiceImpl.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ package sample.attributes; * @version $Id$ */ public class BankServiceImpl implements BankService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public float balance(String accountNumber) { return 42000000; diff --git a/samples/attributes/src/main/java/sample/attributes/Main.java b/samples/attributes/src/main/java/sample/attributes/Main.java index 2e68891eb4..3f4098f0ec 100644 --- a/samples/attributes/src/main/java/sample/attributes/Main.java +++ b/samples/attributes/src/main/java/sample/attributes/Main.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,10 @@ package sample.attributes; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -33,13 +35,28 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * @version $Id$ */ public class Main { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + /** + * This can be done in a web app by using a filter or SpringMvcIntegrationInterceptor. + */ + private static void createSecureContext() { + TestingAuthenticationToken auth = new TestingAuthenticationToken("test", "test", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST") + }); + + SecurityContextHolder.getContext().setAuthentication(auth); + } + + private static void destroySecureContext() { + SecurityContextHolder.setContext(new SecurityContextImpl()); + } public static void main(String[] args) throws Exception { createSecureContext(); - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( - "applicationContext.xml"); + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BankService service = (BankService) context.getBean("bankService"); // will succeed @@ -56,21 +73,4 @@ public class Main { destroySecureContext(); } - - /** - * This can be done in a web app by using a filter or - * SpringMvcIntegrationInterceptor. - */ - private static void createSecureContext() { - TestingAuthenticationToken auth = new TestingAuthenticationToken("test", - "test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl( - "ROLE_PERMISSION_LIST")}); - - SecurityContextHolder.getContext().setAuthentication(auth); - } - - private static void destroySecureContext() { - SecurityContextHolder.setContext(new SecurityContextImpl()); - } } diff --git a/samples/attributes/src/test/java/sample/attributes/BankTests.java b/samples/attributes/src/test/java/sample/attributes/BankTests.java index 713de2daa2..6ad9550aa0 100644 --- a/samples/attributes/src/test/java/sample/attributes/BankTests.java +++ b/samples/attributes/src/test/java/sample/attributes/BankTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,10 @@ import junit.framework.TestCase; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; + import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextImpl; + import org.acegisecurity.providers.TestingAuthenticationToken; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -34,12 +36,12 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * @version $Id$ */ public class BankTests extends TestCase { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private BankService service; private ClassPathXmlApplicationContext ctx; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public BankTests() { super(); @@ -49,7 +51,24 @@ public class BankTests extends TestCase { super(arg0); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + private static void createSecureContext() { + TestingAuthenticationToken auth = new TestingAuthenticationToken("test", "test", + new GrantedAuthority[] { + new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl("ROLE_PERMISSION_LIST") + }); + + SecurityContextHolder.getContext().setAuthentication(auth); + } + + private static void destroySecureContext() { + SecurityContextHolder.setContext(new SecurityContextImpl()); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(BankTests.class); + } public final void setUp() throws Exception { super.setUp(); @@ -57,10 +76,6 @@ public class BankTests extends TestCase { service = (BankService) ctx.getBean("bankService"); } - public static void main(String[] args) { - junit.textui.TestRunner.run(BankTests.class); - } - public void testDeniedAccess() throws Exception { createSecureContext(); @@ -79,17 +94,4 @@ public class BankTests extends TestCase { service.listAccounts(); destroySecureContext(); } - - private static void createSecureContext() { - TestingAuthenticationToken auth = new TestingAuthenticationToken("test", - "test", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"), new GrantedAuthorityImpl( - "ROLE_PERMISSION_LIST")}); - - SecurityContextHolder.getContext().setAuthentication(auth); - } - - private static void destroySecureContext() { - SecurityContextHolder.setContext(new SecurityContextImpl()); - } } diff --git a/samples/contacts-tiger/src/main/java/sample/contact/annotation/ContactManagerBackend.java b/samples/contacts-tiger/src/main/java/sample/contact/annotation/ContactManagerBackend.java index 336c7ff49e..ecbb31b07c 100644 --- a/samples/contacts-tiger/src/main/java/sample/contact/annotation/ContactManagerBackend.java +++ b/samples/contacts-tiger/src/main/java/sample/contact/annotation/ContactManagerBackend.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,27 +15,34 @@ package sample.contact.annotation; -import java.util.List; -import java.util.Random; - import org.acegisecurity.Authentication; + import org.acegisecurity.acl.basic.AclObjectIdentity; import org.acegisecurity.acl.basic.BasicAclExtendedDao; import org.acegisecurity.acl.basic.NamedEntityObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.annotation.Secured; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.userdetails.UserDetails; import org.springframework.beans.factory.InitializingBean; + import org.springframework.context.support.ApplicationObjectSupport; + import org.springframework.transaction.annotation.Transactional; + import org.springframework.util.Assert; import sample.contact.Contact; import sample.contact.ContactDao; import sample.contact.ContactManager; +import java.util.List; +import java.util.Random; + /** * Concrete implementation of Java 5 Annotated {@link ContactManager}. @@ -44,18 +51,70 @@ import sample.contact.ContactManager; * @version $Id$ */ @Transactional -public class ContactManagerBackend extends ApplicationObjectSupport - implements ContactManager, InitializingBean { - //~ Instance fields ======================================================== +public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean { + //~ Instance fields ================================================================================================ private BasicAclExtendedDao basicAclExtendedDao; private ContactDao contactDao; private int counter = 100; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - @Secured ({"ROLE_USER","AFTER_ACL_COLLECTION_READ"}) - @Transactional(readOnly=true) + @Secured({"ACL_CONTACT_ADMIN"}) + public void addPermission(Contact contact, String recipient, Integer permission) { + SimpleAclEntry simpleAclEntry = new SimpleAclEntry(); + simpleAclEntry.setAclObjectIdentity(makeObjectIdentity(contact)); + simpleAclEntry.setMask(permission.intValue()); + simpleAclEntry.setRecipient(recipient); + basicAclExtendedDao.create(simpleAclEntry); + + if (logger.isDebugEnabled()) { + logger.debug("Added permission " + permission + " for recipient " + recipient + " contact " + contact); + } + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactDao, "contactDao required"); + Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required"); + } + + @Secured({"ROLE_USER"}) + public void create(Contact contact) { + // Create the Contact itself + contact.setId(new Long(counter++)); + contactDao.create(contact); + + // Grant the current principal access to the contact + addPermission(contact, getUsername(), new Integer(SimpleAclEntry.ADMINISTRATION)); + + if (logger.isDebugEnabled()) { + logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername()); + } + } + + @Secured({"ACL_CONTACT_DELETE"}) + public void delete(Contact contact) { + contactDao.delete(contact.getId()); + + // Delete the ACL information as well + basicAclExtendedDao.delete(makeObjectIdentity(contact)); + + if (logger.isDebugEnabled()) { + logger.debug("Deleted contact " + contact + " including ACL permissions"); + } + } + + @Secured({"ACL_CONTACT_ADMIN"}) + public void deletePermission(Contact contact, String recipient) { + basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient); + + if (logger.isDebugEnabled()) { + logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient); + } + } + + @Secured({"ROLE_USER", "AFTER_ACL_COLLECTION_READ"}) + @Transactional(readOnly = true) public List getAll() { if (logger.isDebugEnabled()) { logger.debug("Returning all contacts"); @@ -64,8 +123,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport return contactDao.findAll(); } - @Secured ({"ROLE_USER"}) - @Transactional(readOnly=true) + @Secured({"ROLE_USER"}) + @Transactional(readOnly = true) public List getAllRecipients() { if (logger.isDebugEnabled()) { logger.debug("Returning all recipients"); @@ -77,16 +136,12 @@ public class ContactManagerBackend extends ApplicationObjectSupport return list; } - public void setBasicAclExtendedDao(BasicAclExtendedDao basicAclExtendedDao) { - this.basicAclExtendedDao = basicAclExtendedDao; - } - public BasicAclExtendedDao getBasicAclExtendedDao() { return basicAclExtendedDao; } - @Secured ({"ROLE_USER","AFTER_ACL_READ"}) - @Transactional(readOnly=true) + @Secured({"ROLE_USER", "AFTER_ACL_READ"}) + @Transactional(readOnly = true) public Contact getById(Long id) { if (logger.isDebugEnabled()) { logger.debug("Returning contact with id: " + id); @@ -95,10 +150,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport return contactDao.getById(id); } - public void setContactDao(ContactDao contactDao) { - this.contactDao = contactDao; - } - public ContactDao getContactDao() { return contactDao; } @@ -120,76 +171,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport return (Contact) contacts.get(getNumber); } - @Secured ({"ACL_CONTACT_ADMIN"}) - public void addPermission(Contact contact, String recipient, - Integer permission) { - SimpleAclEntry simpleAclEntry = new SimpleAclEntry(); - simpleAclEntry.setAclObjectIdentity(makeObjectIdentity(contact)); - simpleAclEntry.setMask(permission.intValue()); - simpleAclEntry.setRecipient(recipient); - basicAclExtendedDao.create(simpleAclEntry); - - if (logger.isDebugEnabled()) { - logger.debug("Added permission " + permission + " for recipient " - + recipient + " contact " + contact); - } - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactDao, "contactDao required"); - Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required"); - } - - @Secured ({"ROLE_USER"}) - public void create(Contact contact) { - // Create the Contact itself - contact.setId(new Long(counter++)); - contactDao.create(contact); - - // Grant the current principal access to the contact - addPermission(contact, getUsername(), - new Integer(SimpleAclEntry.ADMINISTRATION)); - - if (logger.isDebugEnabled()) { - logger.debug("Created contact " + contact - + " and granted admin permission to recipient " + getUsername()); - } - } - - @Secured ({"ACL_CONTACT_DELETE"}) - public void delete(Contact contact) { - contactDao.delete(contact.getId()); - - // Delete the ACL information as well - basicAclExtendedDao.delete(makeObjectIdentity(contact)); - - if (logger.isDebugEnabled()) { - logger.debug("Deleted contact " + contact - + " including ACL permissions"); - } - } - - @Secured ({"ACL_CONTACT_ADMIN"}) - public void deletePermission(Contact contact, String recipient) { - basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient); - - if (logger.isDebugEnabled()) { - logger.debug("Deleted contact " + contact - + " ACL permissions for recipient " + recipient); - } - } - - public void update(Contact contact) { - contactDao.update(contact); - - if (logger.isDebugEnabled()) { - logger.debug("Updated contact " + contact); - } - } - protected String getUsername() { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth.getPrincipal() instanceof UserDetails) { return ((UserDetails) auth.getPrincipal()).getUsername(); @@ -199,7 +182,22 @@ public class ContactManagerBackend extends ApplicationObjectSupport } private AclObjectIdentity makeObjectIdentity(Contact contact) { - return new NamedEntityObjectIdentity(contact.getClass().getName(), - contact.getId().toString()); + return new NamedEntityObjectIdentity(contact.getClass().getName(), contact.getId().toString()); + } + + public void setBasicAclExtendedDao(BasicAclExtendedDao basicAclExtendedDao) { + this.basicAclExtendedDao = basicAclExtendedDao; + } + + public void setContactDao(ContactDao contactDao) { + this.contactDao = contactDao; + } + + public void update(Contact contact) { + contactDao.update(contact); + + if (logger.isDebugEnabled()) { + logger.debug("Updated contact " + contact); + } } } diff --git a/samples/contacts/src/main/java/sample/contact/AddPermission.java b/samples/contacts/src/main/java/sample/contact/AddPermission.java index f8c5d794f1..8891aa25a4 100644 --- a/samples/contacts/src/main/java/sample/contact/AddPermission.java +++ b/samples/contacts/src/main/java/sample/contact/AddPermission.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,35 +25,35 @@ import org.acegisecurity.acl.basic.SimpleAclEntry; * @version $Id$ */ public class AddPermission { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ public Contact contact; public Integer permission = new Integer(SimpleAclEntry.NOTHING); public String recipient; - //~ Methods ================================================================ - - public void setContact(Contact contact) { - this.contact = contact; - } + //~ Methods ======================================================================================================== public Contact getContact() { return contact; } - public void setPermission(Integer permission) { - this.permission = permission; - } - public Integer getPermission() { return permission; } - public void setRecipient(String recipient) { - this.recipient = recipient; - } - public String getRecipient() { return recipient; } + + public void setContact(Contact contact) { + this.contact = contact; + } + + public void setPermission(Integer permission) { + this.permission = permission; + } + + public void setRecipient(String recipient) { + this.recipient = recipient; + } } diff --git a/samples/contacts/src/main/java/sample/contact/AddPermissionController.java b/samples/contacts/src/main/java/sample/contact/AddPermissionController.java index 8b71ff48aa..bd4190b737 100644 --- a/samples/contacts/src/main/java/sample/contact/AddPermissionController.java +++ b/samples/contacts/src/main/java/sample/contact/AddPermissionController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,42 +45,28 @@ import javax.servlet.http.HttpServletResponse; * @author Ben Alex * @version $Id$ */ -public class AddPermissionController extends SimpleFormController - implements InitializingBean { - //~ Instance fields ======================================================== +public class AddPermissionController extends SimpleFormController implements InitializingBean { + //~ Instance fields ================================================================================================ private ContactManager contactManager; - //~ Methods ================================================================ - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } - - public ContactManager getContactManager() { - return contactManager; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, - "A ContactManager implementation is required"); + Assert.notNull(contactManager, "A ContactManager implementation is required"); } - protected ModelAndView disallowDuplicateFormSubmission( - HttpServletRequest request, HttpServletResponse response) + protected ModelAndView disallowDuplicateFormSubmission(HttpServletRequest request, HttpServletResponse response) throws Exception { - BindException errors = new BindException(formBackingObject(request), - getCommandName()); - errors.reject("err.duplicateFormSubmission", - "Duplicate form submission."); + BindException errors = new BindException(formBackingObject(request), getCommandName()); + errors.reject("err.duplicateFormSubmission", "Duplicate form submission."); return showForm(request, response, errors); } protected Object formBackingObject(HttpServletRequest request) throws Exception { - int contactId = RequestUtils.getRequiredIntParameter(request, - "contactId"); + int contactId = RequestUtils.getRequiredIntParameter(request, "contactId"); Contact contact = contactManager.getById(new Long(contactId)); @@ -90,19 +76,53 @@ public class AddPermissionController extends SimpleFormController return addPermission; } - protected ModelAndView handleInvalidSubmit(HttpServletRequest request, - HttpServletResponse response) throws Exception { + public ContactManager getContactManager() { + return contactManager; + } + + protected ModelAndView handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response) + throws Exception { return disallowDuplicateFormSubmission(request, response); } - protected ModelAndView onSubmit(HttpServletRequest request, - HttpServletResponse response, Object command, BindException errors) - throws Exception { + private Map listPermissions(HttpServletRequest request) { + Map map = new LinkedHashMap(); + map.put(new Integer(SimpleAclEntry.NOTHING), + getApplicationContext().getMessage("select.none", null, "None", request.getLocale())); + map.put(new Integer(SimpleAclEntry.ADMINISTRATION), + getApplicationContext().getMessage("select.administer", null, "Administer", request.getLocale())); + map.put(new Integer(SimpleAclEntry.READ), + getApplicationContext().getMessage("select.read", null, "Read", request.getLocale())); + map.put(new Integer(SimpleAclEntry.DELETE), + getApplicationContext().getMessage("select.delete", null, "Delete", request.getLocale())); + map.put(new Integer(SimpleAclEntry.READ_WRITE_DELETE), + getApplicationContext().getMessage("select.readWriteDelete", null, "Read+Write+Delete", request.getLocale())); + + return map; + } + + private Map listRecipients(HttpServletRequest request) { + Map map = new LinkedHashMap(); + map.put("", + getApplicationContext().getMessage("select.pleaseSelect", null, "-- please select --", request.getLocale())); + + Iterator recipientsIter = contactManager.getAllRecipients().iterator(); + + while (recipientsIter.hasNext()) { + String recipient = (String) recipientsIter.next(); + map.put(recipient, recipient); + } + + return map; + } + + protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, + BindException errors) throws Exception { AddPermission addPermission = (AddPermission) command; try { - contactManager.addPermission(addPermission.getContact(), - addPermission.getRecipient(), addPermission.getPermission()); + contactManager.addPermission(addPermission.getContact(), addPermission.getRecipient(), + addPermission.getPermission()); } catch (DataAccessException existingPermission) { existingPermission.printStackTrace(); errors.rejectValue("recipient", "err.recipientExistsForContact", @@ -123,40 +143,7 @@ public class AddPermissionController extends SimpleFormController return model; } - private Map listPermissions(HttpServletRequest request) { - Map map = new LinkedHashMap(); - map.put(new Integer(SimpleAclEntry.NOTHING), - getApplicationContext().getMessage("select.none", null, "None", - request.getLocale())); - map.put(new Integer(SimpleAclEntry.ADMINISTRATION), - getApplicationContext().getMessage("select.administer", null, - "Administer", request.getLocale())); - map.put(new Integer(SimpleAclEntry.READ), - getApplicationContext().getMessage("select.read", null, "Read", - request.getLocale())); - map.put(new Integer(SimpleAclEntry.DELETE), - getApplicationContext().getMessage("select.delete", null, "Delete", - request.getLocale())); - map.put(new Integer(SimpleAclEntry.READ_WRITE_DELETE), - getApplicationContext().getMessage("select.readWriteDelete", null, - "Read+Write+Delete", request.getLocale())); - - return map; - } - - private Map listRecipients(HttpServletRequest request) { - Map map = new LinkedHashMap(); - map.put("", - getApplicationContext().getMessage("select.pleaseSelect", null, - "-- please select --", request.getLocale())); - - Iterator recipientsIter = contactManager.getAllRecipients().iterator(); - - while (recipientsIter.hasNext()) { - String recipient = (String) recipientsIter.next(); - map.put(recipient, recipient); - } - - return map; + public void setContactManager(ContactManager contact) { + this.contactManager = contact; } } diff --git a/samples/contacts/src/main/java/sample/contact/AddPermissionValidator.java b/samples/contacts/src/main/java/sample/contact/AddPermissionValidator.java index e2da7a90c1..664aaf6fdf 100644 --- a/samples/contacts/src/main/java/sample/contact/AddPermissionValidator.java +++ b/samples/contacts/src/main/java/sample/contact/AddPermissionValidator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.springframework.validation.Validator; * @version $Id$ */ public class AddPermissionValidator implements Validator { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean supports(Class clazz) { return clazz.equals(AddPermission.class); @@ -38,21 +38,16 @@ public class AddPermissionValidator implements Validator { public void validate(Object obj, Errors errors) { AddPermission addPermission = (AddPermission) obj; - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "permission", - "err.permission", "Permission is required"); - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipient", - "err.recipient", "Recipient is required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "permission", "err.permission", "Permission is required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipient", "err.recipient", "Recipient is required"); if (addPermission.getPermission() != null) { int permission = addPermission.getPermission().intValue(); - if ((permission != SimpleAclEntry.NOTHING) - && (permission != SimpleAclEntry.ADMINISTRATION) - && (permission != SimpleAclEntry.READ) - && (permission != SimpleAclEntry.DELETE) + if ((permission != SimpleAclEntry.NOTHING) && (permission != SimpleAclEntry.ADMINISTRATION) + && (permission != SimpleAclEntry.READ) && (permission != SimpleAclEntry.DELETE) && (permission != SimpleAclEntry.READ_WRITE_DELETE)) { - errors.rejectValue("permission", "err.permission.invalid", - "The indicated permission is invalid."); + errors.rejectValue("permission", "err.permission.invalid", "The indicated permission is invalid."); } } diff --git a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java index 75ace75be6..2a47f3ad65 100644 --- a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java +++ b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,37 +43,28 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class AdminPermissionController implements Controller, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclManager aclManager; private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setAclManager(AclManager aclManager) { - this.aclManager = aclManager; + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactManager, "A ContactManager implementation is required"); + Assert.notNull(aclManager, "An aclManager implementation is required"); } public AclManager getAclManager() { return aclManager; } - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } - public ContactManager getContactManager() { return contactManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, - "A ContactManager implementation is required"); - Assert.notNull(aclManager, "An aclManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { int id = RequestUtils.getRequiredIntParameter(request, "contactId"); Contact contact = contactManager.getById(new Long(id)); @@ -85,4 +76,12 @@ public class AdminPermissionController implements Controller, InitializingBean { return new ModelAndView("adminPermission", "model", model); } + + public void setAclManager(AclManager aclManager) { + this.aclManager = aclManager; + } + + public void setContactManager(ContactManager contact) { + this.contactManager = contact; + } } diff --git a/samples/contacts/src/main/java/sample/contact/ClientApplication.java b/samples/contacts/src/main/java/sample/contact/ClientApplication.java index a5cb85b167..029790d880 100644 --- a/samples/contacts/src/main/java/sample/contact/ClientApplication.java +++ b/samples/contacts/src/main/java/sample/contact/ClientApplication.java @@ -36,33 +36,27 @@ import java.util.Map; /** - * Demonstrates accessing the {@link ContactManager} via remoting protocols. - * - *

- * Based on Spring's JPetStore sample, written by Juergen Hoeller. - *

+ * Demonstrates accessing the {@link ContactManager} via remoting protocols.

Based on Spring's JPetStore sample, + * written by Juergen Hoeller.

* * @author Ben Alex */ public class ClientApplication { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private final ListableBeanFactory beanFactory; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ClientApplication(ListableBeanFactory beanFactory) { this.beanFactory = beanFactory; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void invokeContactManager(Authentication authentication, - int nrOfCalls) { - StopWatch stopWatch = new StopWatch(nrOfCalls - + " ContactManager call(s)"); - Map contactServices = this.beanFactory.getBeansOfType(ContactManager.class, - true, true); + public void invokeContactManager(Authentication authentication, int nrOfCalls) { + StopWatch stopWatch = new StopWatch(nrOfCalls + " ContactManager call(s)"); + Map contactServices = this.beanFactory.getBeansOfType(ContactManager.class, true, true); SecurityContextHolder.getContext().setAuthentication(authentication); @@ -72,20 +66,13 @@ public class ClientApplication { Object object = this.beanFactory.getBean("&" + beanName); try { - System.out.println( - "Trying to find setUsername(String) method on: " - + object.getClass().getName()); + System.out.println("Trying to find setUsername(String) method on: " + object.getClass().getName()); - Method method = object.getClass() - .getMethod("setUsername", - new Class[] {String.class}); - System.out.println("Found; Trying to setUsername(String) to " - + authentication.getPrincipal()); - method.invoke(object, - new Object[] {authentication.getPrincipal()}); + Method method = object.getClass().getMethod("setUsername", new Class[] {String.class}); + System.out.println("Found; Trying to setUsername(String) to " + authentication.getPrincipal()); + method.invoke(object, new Object[] {authentication.getPrincipal()}); } catch (NoSuchMethodException ignored) { - System.out.println( - "This client proxy factory does not have a setUsername(String) method"); + System.out.println("This client proxy factory does not have a setUsername(String) method"); } catch (IllegalAccessException ignored) { ignored.printStackTrace(); } catch (InvocationTargetException ignored) { @@ -93,25 +80,17 @@ public class ClientApplication { } try { - System.out.println( - "Trying to find setPassword(String) method on: " - + object.getClass().getName()); + System.out.println("Trying to find setPassword(String) method on: " + object.getClass().getName()); - Method method = object.getClass() - .getMethod("setPassword", - new Class[] {String.class}); - method.invoke(object, - new Object[] {authentication.getCredentials()}); - System.out.println("Found; Trying to setPassword(String) to " - + authentication.getCredentials()); + Method method = object.getClass().getMethod("setPassword", new Class[] {String.class}); + method.invoke(object, new Object[] {authentication.getCredentials()}); + System.out.println("Found; Trying to setPassword(String) to " + authentication.getCredentials()); } catch (NoSuchMethodException ignored) { - System.out.println( - "This client proxy factory does not have a setPassword(String) method"); + System.out.println("This client proxy factory does not have a setPassword(String) method"); } catch (IllegalAccessException ignored) {} catch (InvocationTargetException ignored) {} - ContactManager remoteContactManager = (ContactManager) contactServices - .get(beanName); + ContactManager remoteContactManager = (ContactManager) contactServices.get(beanName); System.out.println("Calling ContactManager '" + beanName + "'"); stopWatch.start(beanName); @@ -132,8 +111,7 @@ public class ClientApplication { System.out.println("Contact: " + contact.toString()); } } else { - System.out.println( - "No contacts found which this user has permission to"); + System.out.println("No contacts found which this user has permission to"); } System.out.println(); @@ -162,12 +140,10 @@ public class ClientApplication { nrOfCalls = Integer.parseInt(nrOfCallsString); } - ListableBeanFactory beanFactory = new FileSystemXmlApplicationContext( - "clientContext.xml"); + ListableBeanFactory beanFactory = new FileSystemXmlApplicationContext("clientContext.xml"); ClientApplication client = new ClientApplication(beanFactory); - client.invokeContactManager(new UsernamePasswordAuthenticationToken( - username, password), nrOfCalls); + client.invokeContactManager(new UsernamePasswordAuthenticationToken(username, password), nrOfCalls); System.exit(0); } } diff --git a/samples/contacts/src/main/java/sample/contact/Contact.java b/samples/contacts/src/main/java/sample/contact/Contact.java index 908f831723..74c5fb4d50 100644 --- a/samples/contacts/src/main/java/sample/contact/Contact.java +++ b/samples/contacts/src/main/java/sample/contact/Contact.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,13 +25,13 @@ import java.io.Serializable; * @version $Id$ */ public class Contact implements Serializable { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Long id; private String email; private String name; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public Contact(String name, String email) { this.name = name; @@ -40,16 +40,7 @@ public class Contact implements Serializable { public Contact() {} - //~ Methods ================================================================ - - /** - * DOCUMENT ME! - * - * @param email The email to set. - */ - public void setEmail(String email) { - this.email = email; - } + //~ Methods ======================================================================================================== /** * DOCUMENT ME! @@ -60,10 +51,6 @@ public class Contact implements Serializable { return email; } - public void setId(Long id) { - this.id = id; - } - /** * DOCUMENT ME! * @@ -76,19 +63,32 @@ public class Contact implements Serializable { /** * DOCUMENT ME! * - * @param name The name to set. + * @return Returns the name. */ - public void setName(String name) { - this.name = name; + public String getName() { + return name; } /** * DOCUMENT ME! * - * @return Returns the name. + * @param email The email to set. */ - public String getName() { - return name; + public void setEmail(String email) { + this.email = email; + } + + public void setId(Long id) { + this.id = id; + } + + /** + * DOCUMENT ME! + * + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; } public String toString() { diff --git a/samples/contacts/src/main/java/sample/contact/ContactDao.java b/samples/contacts/src/main/java/sample/contact/ContactDao.java index b72b33b9e7..9c05056bd7 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactDao.java +++ b/samples/contacts/src/main/java/sample/contact/ContactDao.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,7 @@ import java.util.List; * @version $Id$ */ public interface ContactDao { - //~ Methods ================================================================ - - public Contact getById(Long id); + //~ Methods ======================================================================================================== public void create(Contact contact); @@ -39,5 +37,7 @@ public interface ContactDao { public List findAllRoles(); + public Contact getById(Long id); + public void update(Contact contact); } diff --git a/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java b/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java index 1f178743f0..a97a963963 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java +++ b/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ import javax.sql.DataSource; * @version $Id$ */ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ContactDelete contactDelete; private ContactInsert contactInsert; @@ -46,21 +46,10 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { private PrincipalsAllQuery principalsAllQuery; private RolesAllQuery rolesAllQuery; - //~ Methods ================================================================ - - public Contact getById(Long id) { - List list = contactsByIdQuery.execute(id.longValue()); - - if (list.size() == 0) { - return null; - } else { - return (Contact) list.get(0); - } - } + //~ Methods ======================================================================================================== public void create(Contact contact) { - System.out.println("creating contact w/ id " + contact.getId() + " " - + contact.getEmail()); + System.out.println("creating contact w/ id " + contact.getId() + " " + contact.getEmail()); contactInsert.insert(contact); } @@ -80,8 +69,14 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { return rolesAllQuery.execute(); } - public void update(Contact contact) { - contactUpdate.update(contact); + public Contact getById(Long id) { + List list = contactsByIdQuery.execute(id.longValue()); + + if (list.size() == 0) { + return null; + } else { + return (Contact) list.get(0); + } } protected void initDao() throws Exception { @@ -98,13 +93,15 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { return contact.getClass().getName() + ":" + contact.getId(); } - //~ Inner Classes ========================================================== + public void update(Contact contact) { + contactUpdate.update(contact); + } - protected class AclObjectIdentityByObjectIdentityQuery - extends MappingSqlQuery { + //~ Inner Classes ================================================================================================== + + protected class AclObjectIdentityByObjectIdentityQuery extends MappingSqlQuery { protected AclObjectIdentityByObjectIdentityQuery(DataSource ds) { - super(ds, - "SELECT id FROM acl_object_identity WHERE object_identity = ?"); + super(ds, "SELECT id FROM acl_object_identity WHERE object_identity = ?"); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } @@ -125,8 +122,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { compile(); } - protected int insert(String objectIdentity, - Long parentAclObjectIdentity, String aclClass) { + protected int insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass) { Object[] objs = new Object[] {null, objectIdentity, parentAclObjectIdentity, aclClass}; super.update(objs); @@ -156,16 +152,14 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { } protected void insert(Contact contact) { - Object[] objs = new Object[] {contact.getId(), contact.getName(), contact - .getEmail()}; + Object[] objs = new Object[] {contact.getId(), contact.getName(), contact.getEmail()}; super.update(objs); } } protected class ContactUpdate extends SqlUpdate { protected ContactUpdate(DataSource ds) { - super(ds, - "UPDATE contacts SET contact_name = ?, address = ? WHERE id = ?"); + super(ds, "UPDATE contacts SET contact_name = ?, address = ? WHERE id = ?"); declareParameter(new SqlParameter(Types.VARCHAR)); declareParameter(new SqlParameter(Types.VARCHAR)); declareParameter(new SqlParameter(Types.BIGINT)); @@ -173,8 +167,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { } protected void update(Contact contact) { - Object[] objs = new Object[] {contact.getName(), contact.getEmail(), contact - .getId()}; + Object[] objs = new Object[] {contact.getName(), contact.getEmail(), contact.getId()}; super.update(objs); } } @@ -198,8 +191,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { protected class ContactsByIdQuery extends MappingSqlQuery { protected ContactsByIdQuery(DataSource ds) { - super(ds, - "SELECT id, contact_name, email FROM contacts WHERE id = ? ORDER BY id"); + super(ds, "SELECT id, contact_name, email FROM contacts WHERE id = ? ORDER BY id"); declareParameter(new SqlParameter(Types.BIGINT)); compile(); } @@ -217,8 +209,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { protected class PermissionDelete extends SqlUpdate { protected PermissionDelete(DataSource ds) { - super(ds, - "DELETE FROM acl_permission WHERE ACL_OBJECT_IDENTITY = ? AND RECIPIENT = ?"); + super(ds, "DELETE FROM acl_permission WHERE ACL_OBJECT_IDENTITY = ? AND RECIPIENT = ?"); declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); @@ -239,8 +230,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { compile(); } - protected int insert(Long aclObjectIdentity, String recipient, - Integer mask) { + protected int insert(Long aclObjectIdentity, String recipient, Integer mask) { Object[] objs = new Object[] {null, aclObjectIdentity, recipient, mask}; super.update(objs); @@ -262,8 +252,7 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { protected class RolesAllQuery extends MappingSqlQuery { protected RolesAllQuery(DataSource ds) { - super(ds, - "SELECT DISTINCT authority FROM authorities ORDER BY authority"); + super(ds, "SELECT DISTINCT authority FROM authorities ORDER BY authority"); compile(); } diff --git a/samples/contacts/src/main/java/sample/contact/ContactManager.java b/samples/contacts/src/main/java/sample/contact/ContactManager.java index 1092add997..7cdbb56a0d 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactManager.java +++ b/samples/contacts/src/main/java/sample/contact/ContactManager.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,15 @@ import java.util.List; * @version $Id$ */ public interface ContactManager { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void addPermission(Contact contact, String recipient, Integer permission); + + public void create(Contact contact); + + public void delete(Contact contact); + + public void deletePermission(Contact contact, String recipient); public List getAll(); @@ -34,13 +42,4 @@ public interface ContactManager { public Contact getById(Long id); public Contact getRandomContact(); - - public void addPermission(Contact contact, String recipient, - Integer permission); - - public void create(Contact contact); - - public void delete(Contact contact); - - public void deletePermission(Contact contact, String recipient); } diff --git a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java index 1ebe1d0901..1960ff2cc0 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java +++ b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,14 @@ package sample.contact; import org.acegisecurity.Authentication; + import org.acegisecurity.acl.basic.AclObjectIdentity; import org.acegisecurity.acl.basic.BasicAclExtendedDao; import org.acegisecurity.acl.basic.NamedEntityObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.context.SecurityContextHolder; + import org.acegisecurity.userdetails.UserDetails; import org.springframework.beans.factory.InitializingBean; @@ -39,15 +42,63 @@ import java.util.Random; * @author Ben Alex * @version $Id$ */ -public class ContactManagerBackend extends ApplicationObjectSupport - implements ContactManager, InitializingBean { - //~ Instance fields ======================================================== +public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean { + //~ Instance fields ================================================================================================ private BasicAclExtendedDao basicAclExtendedDao; private ContactDao contactDao; private int counter = 1000; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + public void addPermission(Contact contact, String recipient, Integer permission) { + SimpleAclEntry simpleAclEntry = new SimpleAclEntry(); + simpleAclEntry.setAclObjectIdentity(makeObjectIdentity(contact)); + simpleAclEntry.setMask(permission.intValue()); + simpleAclEntry.setRecipient(recipient); + basicAclExtendedDao.create(simpleAclEntry); + + if (logger.isDebugEnabled()) { + logger.debug("Added permission " + permission + " for recipient " + recipient + " contact " + contact); + } + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactDao, "contactDao required"); + Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required"); + } + + public void create(Contact contact) { + // Create the Contact itself + contact.setId(new Long(counter++)); + contactDao.create(contact); + + // Grant the current principal access to the contact + addPermission(contact, getUsername(), new Integer(SimpleAclEntry.ADMINISTRATION)); + + if (logger.isDebugEnabled()) { + logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername()); + } + } + + public void delete(Contact contact) { + contactDao.delete(contact.getId()); + + // Delete the ACL information as well + basicAclExtendedDao.delete(makeObjectIdentity(contact)); + + if (logger.isDebugEnabled()) { + logger.debug("Deleted contact " + contact + " including ACL permissions"); + } + } + + public void deletePermission(Contact contact, String recipient) { + basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient); + + if (logger.isDebugEnabled()) { + logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient); + } + } public List getAll() { if (logger.isDebugEnabled()) { @@ -68,10 +119,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport return list; } - public void setBasicAclExtendedDao(BasicAclExtendedDao basicAclExtendedDao) { - this.basicAclExtendedDao = basicAclExtendedDao; - } - public BasicAclExtendedDao getBasicAclExtendedDao() { return basicAclExtendedDao; } @@ -84,10 +131,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport return contactDao.getById(id); } - public void setContactDao(ContactDao contactDao) { - this.contactDao = contactDao; - } - public ContactDao getContactDao() { return contactDao; } @@ -109,72 +152,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport return (Contact) contacts.get(getNumber); } - public void addPermission(Contact contact, String recipient, - Integer permission) { - SimpleAclEntry simpleAclEntry = new SimpleAclEntry(); - simpleAclEntry.setAclObjectIdentity(makeObjectIdentity(contact)); - simpleAclEntry.setMask(permission.intValue()); - simpleAclEntry.setRecipient(recipient); - basicAclExtendedDao.create(simpleAclEntry); - - if (logger.isDebugEnabled()) { - logger.debug("Added permission " + permission + " for recipient " - + recipient + " contact " + contact); - } - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactDao, "contactDao required"); - Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required"); - } - - public void create(Contact contact) { - // Create the Contact itself - contact.setId(new Long(counter++)); - contactDao.create(contact); - - // Grant the current principal access to the contact - addPermission(contact, getUsername(), - new Integer(SimpleAclEntry.ADMINISTRATION)); - - if (logger.isDebugEnabled()) { - logger.debug("Created contact " + contact - + " and granted admin permission to recipient " + getUsername()); - } - } - - public void delete(Contact contact) { - contactDao.delete(contact.getId()); - - // Delete the ACL information as well - basicAclExtendedDao.delete(makeObjectIdentity(contact)); - - if (logger.isDebugEnabled()) { - logger.debug("Deleted contact " + contact - + " including ACL permissions"); - } - } - - public void deletePermission(Contact contact, String recipient) { - basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient); - - if (logger.isDebugEnabled()) { - logger.debug("Deleted contact " + contact - + " ACL permissions for recipient " + recipient); - } - } - - public void update(Contact contact) { - contactDao.update(contact); - - if (logger.isDebugEnabled()) { - logger.debug("Updated contact " + contact); - } - } - protected String getUsername() { - Authentication auth = SecurityContextHolder.getContext() - .getAuthentication(); + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth.getPrincipal() instanceof UserDetails) { return ((UserDetails) auth.getPrincipal()).getUsername(); @@ -184,7 +163,22 @@ public class ContactManagerBackend extends ApplicationObjectSupport } private AclObjectIdentity makeObjectIdentity(Contact contact) { - return new NamedEntityObjectIdentity(contact.getClass().getName(), - contact.getId().toString()); + return new NamedEntityObjectIdentity(contact.getClass().getName(), contact.getId().toString()); + } + + public void setBasicAclExtendedDao(BasicAclExtendedDao basicAclExtendedDao) { + this.basicAclExtendedDao = basicAclExtendedDao; + } + + public void setContactDao(ContactDao contactDao) { + this.contactDao = contactDao; + } + + public void update(Contact contact) { + contactDao.update(contact); + + if (logger.isDebugEnabled()) { + logger.debug("Updated contact " + contact); + } } } diff --git a/samples/contacts/src/main/java/sample/contact/DataSourcePopulator.java b/samples/contacts/src/main/java/sample/contact/DataSourcePopulator.java index 79f1038ed8..77ad1dab00 100644 --- a/samples/contacts/src/main/java/sample/contact/DataSourcePopulator.java +++ b/samples/contacts/src/main/java/sample/contact/DataSourcePopulator.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,31 +33,23 @@ import javax.sql.DataSource; * @version $Id$ */ public class DataSourcePopulator implements InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ - Random rnd = new Random(); - String[] firstNames = {"Bob", "Mary", "James", "Jane", "Kristy", "Kirsty", "Kate", "Jeni", "Angela", "Melanie", "Kent", "William", "Geoff", "Jeff", "Adrian", "Amanda", "Lisa", "Elizabeth", "Prue", "Richard", "Darin", "Phillip", "Michael", "Belinda", "Samantha", "Brian", "Greg", "Matthew"}; - String[] lastNames = {"Smith", "Williams", "Jackson", "Rictor", "Nelson", "Fitzgerald", "McAlpine", "Sutherland", "Abbott", "Hall", "Edwards", "Gates", "Black", "Brown", "Gray", "Marwell", "Booch", "Johnson", "McTaggart", "Parklin", "Findlay", "Robinson", "Giugni", "Lang", "Chi", "Carmichael"}; private DataSource dataSource; + Random rnd = new Random(); + String[] firstNames = { + "Bob", "Mary", "James", "Jane", "Kristy", "Kirsty", "Kate", "Jeni", "Angela", "Melanie", "Kent", "William", + "Geoff", "Jeff", "Adrian", "Amanda", "Lisa", "Elizabeth", "Prue", "Richard", "Darin", "Phillip", "Michael", + "Belinda", "Samantha", "Brian", "Greg", "Matthew" + }; + String[] lastNames = { + "Smith", "Williams", "Jackson", "Rictor", "Nelson", "Fitzgerald", "McAlpine", "Sutherland", "Abbott", "Hall", + "Edwards", "Gates", "Black", "Brown", "Gray", "Marwell", "Booch", "Johnson", "McTaggart", "Parklin", + "Findlay", "Robinson", "Giugni", "Lang", "Chi", "Carmichael" + }; private int createEntities = 1000; - //~ Methods ================================================================ - - public void setCreateEntities(int createEntities) { - this.createEntities = createEntities; - } - - public int getCreateEntities() { - return createEntities; - } - - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - public DataSource getDataSource() { - return dataSource; - } + //~ Methods ======================================================================================================== public void afterPropertiesSet() throws Exception { Assert.notNull(dataSource, "dataSource required"); @@ -66,30 +58,20 @@ public class DataSourcePopulator implements InitializingBean { template.execute( "CREATE TABLE CONTACTS(ID BIGINT NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)"); - template.execute( - "INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');"); // marissa - template.execute( - "INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');"); // marissa - template.execute( - "INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');"); // marissa - template.execute( - "INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');"); // marissa + dianne + scott - template.execute( - "INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');"); // dianne - template.execute( - "INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');"); // dianne + scott - template.execute( - "INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');"); // scott - template.execute( - "INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');"); // dianne + scott - template.execute( - "INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');"); // scott + template.execute("INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');"); // marissa + template.execute("INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');"); // marissa + template.execute("INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');"); // marissa + template.execute("INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');"); // marissa + dianne + scott + template.execute("INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');"); // dianne + template.execute("INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');"); // dianne + scott + template.execute("INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');"); // scott + template.execute("INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');"); // dianne + scott + template.execute("INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');"); // scott for (int i = 10; i < createEntities; i++) { String[] person = selectPerson(); - template.execute("INSERT INTO contacts VALUES (" + i + ", '" - + person[2] + "', '" + person[0].toLowerCase() + "@" - + person[1].toLowerCase() + ".com');"); + template.execute("INSERT INTO contacts VALUES (" + i + ", '" + person[2] + "', '" + person[0].toLowerCase() + + "@" + person[1].toLowerCase() + ".com');"); } template.execute( @@ -114,39 +96,25 @@ public class DataSourcePopulator implements InitializingBean { "INSERT INTO acl_object_identity VALUES (9, 'sample.contact.Contact:9', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');"); for (int i = 10; i < createEntities; i++) { - template.execute("INSERT INTO acl_object_identity VALUES (" + i - + ", 'sample.contact.Contact:" + i + template.execute("INSERT INTO acl_object_identity VALUES (" + i + ", 'sample.contact.Contact:" + i + "', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');"); } template.execute( "CREATE TABLE ACL_PERMISSION(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,ACL_OBJECT_IDENTITY BIGINT NOT NULL,RECIPIENT VARCHAR_IGNORECASE(100) NOT NULL,MASK INTEGER NOT NULL,CONSTRAINT UNIQUE_RECIPIENT UNIQUE(ACL_OBJECT_IDENTITY,RECIPIENT),CONSTRAINT SYS_FK_7 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID))"); - template.execute( - "INSERT INTO acl_permission VALUES (null, 1, 'marissa', 1);"); // administer - template.execute( - "INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 3, 'marissa', 22);"); // read+write+delete - template.execute( - "INSERT INTO acl_permission VALUES (null, 4, 'marissa', 1);"); // administer - template.execute( - "INSERT INTO acl_permission VALUES (null, 4, 'dianne', 1);"); // administer - template.execute( - "INSERT INTO acl_permission VALUES (null, 4, 'scott', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 5, 'dianne', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 6, 'dianne', 22);"); // read+write+delete - template.execute( - "INSERT INTO acl_permission VALUES (null, 6, 'scott', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 7, 'scott', 1);"); // administer - template.execute( - "INSERT INTO acl_permission VALUES (null, 8, 'dianne', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 8, 'scott', 2);"); // read - template.execute( - "INSERT INTO acl_permission VALUES (null, 9, 'scott', 22);"); // read+write+delete + template.execute("INSERT INTO acl_permission VALUES (null, 1, 'marissa', 1);"); // administer + template.execute("INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 3, 'marissa', 22);"); // read+write+delete + template.execute("INSERT INTO acl_permission VALUES (null, 4, 'marissa', 1);"); // administer + template.execute("INSERT INTO acl_permission VALUES (null, 4, 'dianne', 1);"); // administer + template.execute("INSERT INTO acl_permission VALUES (null, 4, 'scott', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 5, 'dianne', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 6, 'dianne', 22);"); // read+write+delete + template.execute("INSERT INTO acl_permission VALUES (null, 6, 'scott', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 7, 'scott', 1);"); // administer + template.execute("INSERT INTO acl_permission VALUES (null, 8, 'dianne', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 8, 'scott', 2);"); // read + template.execute("INSERT INTO acl_permission VALUES (null, 9, 'scott', 22);"); // read+write+delete String[] users = {"bill", "bob", "jane"}; // don't want to mess around with consistent sample data int[] permissions = {1, 2, 22}; @@ -154,15 +122,14 @@ public class DataSourcePopulator implements InitializingBean { for (int i = 10; i < createEntities; i++) { String user = users[rnd.nextInt(users.length)]; int permission = permissions[rnd.nextInt(permissions.length)]; - template.execute("INSERT INTO acl_permission VALUES (null, " + i - + ", '" + user + "', " + permission + ");"); + template.execute("INSERT INTO acl_permission VALUES (null, " + i + ", '" + user + "', " + permission + ");"); String user2 = users[rnd.nextInt(users.length)]; int permission2 = permissions[rnd.nextInt(permissions.length)]; if (!user2.equals(user)) { - template.execute("INSERT INTO acl_permission VALUES (null, " - + i + ", '" + user2 + "', " + permission2 + ");"); + template.execute("INSERT INTO acl_permission VALUES (null, " + i + ", '" + user2 + "', " + permission2 + + ");"); } } @@ -170,8 +137,7 @@ public class DataSourcePopulator implements InitializingBean { "CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);"); template.execute( "CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));"); - template.execute( - "CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);"); + template.execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);"); /* Passwords encoded using MD5, NOT in Base64 format, with null as salt @@ -184,26 +150,16 @@ public class DataSourcePopulator implements InitializingBean { Encoded password for jane is "wombat" */ - template.execute( - "INSERT INTO USERS VALUES('marissa','a564de63c2d0da68cf47586ee05984d7',TRUE);"); - template.execute( - "INSERT INTO USERS VALUES('dianne','65d15fe9156f9c4bbffd98085992a44e',TRUE);"); - template.execute( - "INSERT INTO USERS VALUES('scott','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); - template.execute( - "INSERT INTO USERS VALUES('peter','22b5c9accc6e1ba628cedc63a72d57f8',FALSE);"); - template.execute( - "INSERT INTO USERS VALUES('bill','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); - template.execute( - "INSERT INTO USERS VALUES('bob','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); - template.execute( - "INSERT INTO USERS VALUES('jane','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('marissa','ROLE_USER');"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR');"); - template.execute( - "INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');"); + template.execute("INSERT INTO USERS VALUES('marissa','a564de63c2d0da68cf47586ee05984d7',TRUE);"); + template.execute("INSERT INTO USERS VALUES('dianne','65d15fe9156f9c4bbffd98085992a44e',TRUE);"); + template.execute("INSERT INTO USERS VALUES('scott','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); + template.execute("INSERT INTO USERS VALUES('peter','22b5c9accc6e1ba628cedc63a72d57f8',FALSE);"); + template.execute("INSERT INTO USERS VALUES('bill','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); + template.execute("INSERT INTO USERS VALUES('bob','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); + template.execute("INSERT INTO USERS VALUES('jane','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);"); + template.execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_USER');"); + template.execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR');"); + template.execute("INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');"); template.execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_USER');"); template.execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_USER');"); template.execute("INSERT INTO AUTHORITIES VALUES('bill','ROLE_USER');"); @@ -211,10 +167,26 @@ public class DataSourcePopulator implements InitializingBean { template.execute("INSERT INTO AUTHORITIES VALUES('jane','ROLE_USER');"); } + public int getCreateEntities() { + return createEntities; + } + + public DataSource getDataSource() { + return dataSource; + } + private String[] selectPerson() { String firstName = firstNames[rnd.nextInt(firstNames.length)]; String lastName = lastNames[rnd.nextInt(lastNames.length)]; return new String[] {firstName, lastName, firstName + " " + lastName}; } + + public void setCreateEntities(int createEntities) { + this.createEntities = createEntities; + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } } diff --git a/samples/contacts/src/main/java/sample/contact/DeleteController.java b/samples/contacts/src/main/java/sample/contact/DeleteController.java index 0959bdc65a..fa83cab117 100644 --- a/samples/contacts/src/main/java/sample/contact/DeleteController.java +++ b/samples/contacts/src/main/java/sample/contact/DeleteController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,31 +37,30 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class DeleteController implements Controller, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setContactManager(ContactManager contact) { - this.contactManager = contact; + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactManager, "A ContactManager implementation is required"); } public ContactManager getContactManager() { return contactManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, - "A ContactManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { int id = RequestUtils.getRequiredIntParameter(request, "contactId"); Contact contact = contactManager.getById(new Long(id)); contactManager.delete(contact); return new ModelAndView("deleted", "contact", contact); } + + public void setContactManager(ContactManager contact) { + this.contactManager = contact; + } } diff --git a/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java b/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java index cd4b07c920..56e04d7bb0 100644 --- a/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java +++ b/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,41 +42,30 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class DeletePermissionController implements Controller, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private AclManager aclManager; private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setAclManager(AclManager aclManager) { - this.aclManager = aclManager; + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactManager, "A ContactManager implementation is required"); + Assert.notNull(aclManager, "An aclManager implementation is required"); } public AclManager getAclManager() { return aclManager; } - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } - public ContactManager getContactManager() { return contactManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, - "A ContactManager implementation is required"); - Assert.notNull(aclManager, "An aclManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - int contactId = RequestUtils.getRequiredIntParameter(request, - "contactId"); - String recipient = RequestUtils.getRequiredStringParameter(request, - "recipient"); + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + int contactId = RequestUtils.getRequiredIntParameter(request, "contactId"); + String recipient = RequestUtils.getRequiredStringParameter(request, "recipient"); Contact contact = contactManager.getById(new Long(contactId)); @@ -88,4 +77,12 @@ public class DeletePermissionController implements Controller, InitializingBean return new ModelAndView("deletePermission", "model", model); } + + public void setAclManager(AclManager aclManager) { + this.aclManager = aclManager; + } + + public void setContactManager(ContactManager contact) { + this.contactManager = contact; + } } diff --git a/samples/contacts/src/main/java/sample/contact/PublicIndexController.java b/samples/contacts/src/main/java/sample/contact/PublicIndexController.java index 0325129590..2b89b4e35c 100644 --- a/samples/contacts/src/main/java/sample/contact/PublicIndexController.java +++ b/samples/contacts/src/main/java/sample/contact/PublicIndexController.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,10 @@ package sample.contact; import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; + import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; -import org.springframework.util.Assert; import java.io.IOException; @@ -35,28 +36,28 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class PublicIndexController implements Controller, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setContactManager(ContactManager contact) { - this.contactManager = contact; + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactManager, "A ContactManager implementation is required"); } public ContactManager getContactManager() { return contactManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { Contact rnd = contactManager.getRandomContact(); return new ModelAndView("hello", "contact", rnd); } + + public void setContactManager(ContactManager contact) { + this.contactManager = contact; + } } diff --git a/samples/contacts/src/main/java/sample/contact/SecureIndexController.java b/samples/contacts/src/main/java/sample/contact/SecureIndexController.java index 84c9e45813..dad05ba918 100644 --- a/samples/contacts/src/main/java/sample/contact/SecureIndexController.java +++ b/samples/contacts/src/main/java/sample/contact/SecureIndexController.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,10 @@ package sample.contact; import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; + import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; -import org.springframework.util.Assert; import java.io.IOException; @@ -39,26 +40,22 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class SecureIndexController implements Controller, InitializingBean { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setContactManager(ContactManager contact) { - this.contactManager = contact; + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactManager, "A ContactManager implementation is required"); } public ContactManager getContactManager() { return contactManager; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { + public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { List myContactsList = contactManager.getAll(); Contact[] myContacts; @@ -73,4 +70,8 @@ public class SecureIndexController implements Controller, InitializingBean { return new ModelAndView("index", "model", model); } + + public void setContactManager(ContactManager contact) { + this.contactManager = contact; + } } diff --git a/samples/contacts/src/main/java/sample/contact/WebContact.java b/samples/contacts/src/main/java/sample/contact/WebContact.java index f0c16ac21c..90594bd8f2 100644 --- a/samples/contacts/src/main/java/sample/contact/WebContact.java +++ b/samples/contacts/src/main/java/sample/contact/WebContact.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,26 +22,26 @@ package sample.contact; * @version $Id$ */ public class WebContact { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String email; private String name; - //~ Methods ================================================================ - - public void setEmail(String email) { - this.email = email; - } + //~ Methods ======================================================================================================== public String getEmail() { return email; } - public void setName(String name) { - this.name = name; - } - public String getName() { return name; } + + public void setEmail(String email) { + this.email = email; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/samples/contacts/src/main/java/sample/contact/WebContactAddController.java b/samples/contacts/src/main/java/sample/contact/WebContactAddController.java index 1403c5ff07..f8281f5427 100644 --- a/samples/contacts/src/main/java/sample/contact/WebContactAddController.java +++ b/samples/contacts/src/main/java/sample/contact/WebContactAddController.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,14 +30,17 @@ import javax.servlet.http.HttpServletRequest; * @version $Id$ */ public class WebContactAddController extends SimpleFormController { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private ContactManager contactManager; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setContactManager(ContactManager contactManager) { - this.contactManager = contactManager; + protected Object formBackingObject(HttpServletRequest request) + throws ServletException { + WebContact wc = new WebContact(); + + return wc; } public ContactManager getContactManager() { @@ -54,10 +57,7 @@ public class WebContactAddController extends SimpleFormController { return new ModelAndView(new RedirectView(getSuccessView())); } - protected Object formBackingObject(HttpServletRequest request) - throws ServletException { - WebContact wc = new WebContact(); - - return wc; + public void setContactManager(ContactManager contactManager) { + this.contactManager = contactManager; } } diff --git a/samples/contacts/src/main/java/sample/contact/WebContactValidator.java b/samples/contacts/src/main/java/sample/contact/WebContactValidator.java index b30069849f..d699809e1e 100644 --- a/samples/contacts/src/main/java/sample/contact/WebContactValidator.java +++ b/samples/contacts/src/main/java/sample/contact/WebContactValidator.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.springframework.validation.Validator; * @version $Id$ */ public class WebContactValidator implements Validator { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean supports(Class clazz) { return clazz.equals(WebContact.class); @@ -35,16 +35,12 @@ public class WebContactValidator implements Validator { public void validate(Object obj, Errors errors) { WebContact wc = (WebContact) obj; - if ((wc.getName() == null) || (wc.getName().length() < 3) - || (wc.getName().length() > 50)) { - errors.rejectValue("name", "err.name", - "Name 3-50 characters is required."); + if ((wc.getName() == null) || (wc.getName().length() < 3) || (wc.getName().length() > 50)) { + errors.rejectValue("name", "err.name", "Name 3-50 characters is required."); } - if ((wc.getEmail() == null) || (wc.getEmail().length() < 3) - || (wc.getEmail().length() > 50)) { - errors.rejectValue("email", "err.email", - "Email 3-50 characters is required."); + if ((wc.getEmail() == null) || (wc.getEmail().length() < 3) || (wc.getEmail().length() > 50)) { + errors.rejectValue("email", "err.email", "Email 3-50 characters is required."); } } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AccessControlEntry.java b/sandbox/src/main/java/org/acegisecurity/acls/AccessControlEntry.java index 12cc1184d5..154679f5f7 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AccessControlEntry.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AccessControlEntry.java @@ -1,8 +1,24 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls; +import org.acegisecurity.acls.sid.Sid; + import java.io.Serializable; -import org.acegisecurity.acls.sid.Sid; /** * Represents an individual permission assignment within an {@link Acl}. @@ -16,15 +32,20 @@ import org.acegisecurity.acls.sid.Sid; * */ public interface AccessControlEntry { + //~ Methods ======================================================================================================== + + public Acl getAcl(); + /** * Obtains an identifier that represents this ACE. * * @return the identifier, or null if unsaved */ public Serializable getId(); - - public Acl getAcl(); - public Sid getSid(); - public Permission getPermission(); - public boolean isGranting(); + + public Permission getPermission(); + + public Sid getSid(); + + public boolean isGranting(); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/Acl.java b/sandbox/src/main/java/org/acegisecurity/acls/Acl.java index 30c4b1ef84..63783de867 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/Acl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/Acl.java @@ -15,11 +15,11 @@ package org.acegisecurity.acls; -import java.io.Serializable; - import org.acegisecurity.acls.objectidentity.ObjectIdentity; import org.acegisecurity.acls.sid.Sid; +import java.io.Serializable; + /** * Represents an access control list (ACL) for a domain object. @@ -42,165 +42,103 @@ import org.acegisecurity.acls.sid.Sid; * @version $Id$ */ public interface Acl extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - /** - * Returns all of the entries represented by the present Acl - * (not parents). - * - *

- * This method is typically used for administrative purposes. - *

- * - *

- * The order that entries appear in the array is unspecified. However, if - * implementations use particular ordering logic in authorization - * decisions, the entries returned by this method MUST be ordered - * in that manner. - *

- * - *

- * Do NOT use this method for making authorization decisions. - * Instead use {@link #isGranted(Permission[], Sid[])}. - *

- * - *

- * This method must operate correctly even if the Acl only - * represents a subset of Sids. The caller is responsible for - * correctly handling the result if only a subset of Sids is - * represented. - *

+ * Returns all of the entries represented by the present Acl (not parents).

This method is + * typically used for administrative purposes.

+ *

The order that entries appear in the array is unspecified. However, if implementations use + * particular ordering logic in authorization decisions, the entries returned by this method MUST be + * ordered in that manner.

+ *

Do NOT use this method for making authorization decisions. Instead use {@link + * #isGranted(Permission[], Sid[])}.

+ *

This method must operate correctly even if the Acl only represents a subset of + * Sids. The caller is responsible for correctly handling the result if only a subset of + * Sids is represented.

* * @return the list of entries represented by the Acl */ public AccessControlEntry[] getEntries(); /** - * Obtains the domain object this Acl provides entries for. - * This is immutable once an Acl is created. + * Obtains the domain object this Acl provides entries for. This is immutable once an + * Acl is created. * * @return the object identity */ public ObjectIdentity getObjectIdentity(); /** - * A domain object may have a parent for the purpose of ACL inheritance. If - * there is a parent, its ACL can be accessed via this method. In turn, - * the parent's parent (grandparent) can be accessed and so on. - * - *

- * This method solely represents the presence of a navigation hierarchy - * between the parent Acl and this Acl. For - * actual inheritance to take place, the {@link #isEntriesInheriting()} - * must also be true. - *

- * - *

- * This method must operate correctly even if the Acl only - * represents a subset of Sids. The caller is responsible for - * correctly handling the result if only a subset of Sids is - * represented. - *

+ * A domain object may have a parent for the purpose of ACL inheritance. If there is a parent, its ACL can + * be accessed via this method. In turn, the parent's parent (grandparent) can be accessed and so on.

This + * method solely represents the presence of a navigation hierarchy between the parent Acl and this + * Acl. For actual inheritance to take place, the {@link #isEntriesInheriting()} must also be + * true.

+ *

This method must operate correctly even if the Acl only represents a subset of + * Sids. The caller is responsible for correctly handling the result if only a subset of + * Sids is represented.

* * @return the parent Acl */ public Acl getParentAcl(); /** - * Indicates whether the ACL entries from the {@link #getParentAcl()} - * should flow down into the current Acl. - * - *

- * The mere link between an Acl and a parent Acl - * on its own is insufficient to cause ACL entries to inherit down. This - * is because a domain object may wish to have entirely independent - * entries, but maintain the link with the parent for navigation purposes. - * Thus, this method denotes whether or not the navigation relationship - * also extends to the actual inheritence of entries. - *

+ * Indicates whether the ACL entries from the {@link #getParentAcl()} should flow down into the current + * Acl.

The mere link between an Acl and a parent Acl on its own + * is insufficient to cause ACL entries to inherit down. This is because a domain object may wish to have entirely + * independent entries, but maintain the link with the parent for navigation purposes. Thus, this method denotes + * whether or not the navigation relationship also extends to the actual inheritence of entries.

* - * @return true if parent ACL entries inherit into the current - * Acl + * @return true if parent ACL entries inherit into the current Acl */ public boolean isEntriesInheriting(); /** - * This is the actual authorization logic method, and must be used whenever - * ACL authorization decisions are required. - * - *

- * An array of Sids are presented, representing security - * identifies of the current principal. In addition, an array of - * Permissions is presented which will have one or more bits - * set in order to indicate the permissions needed for an affirmative - * authorization decision. An array is presented because holding - * any of the Permissions inside the array will be - * sufficient for an affirmative authorization. - *

- * - *

- * The actual approach used to make authorization decisions is left to the - * implementation and is not specified by this interface. For example, an - * implementation MAY search the current ACL in the order the ACL - * entries have been stored. If a single entry is found that has the same - * active bits as are shown in a passed Permission, that - * entry's grant or deny state may determine the authorization decision. - * If the case of a deny state, the deny decision will only be relevant if - * all other Permissions passed in the array have also been - * unsuccessfully searched. If no entry is found that match the bits in - * the current ACL, provided that {@link #isEntriesInheriting()} is - * true, the authorization decision may be passed to the - * parent ACL. If there is no matching entry, the implementation MAY throw - * an exception, or make a predefined authorization decision. - *

- * - *

- * This method must operate correctly even if the Acl only - * represents a subset of Sids. The caller is responsible for - * correctly handling the result if only a subset of Sids is - * represented. - *

+ * This is the actual authorization logic method, and must be used whenever ACL authorization decisions are + * required.

An array of Sids are presented, representing security identifies of the current + * principal. In addition, an array of Permissions is presented which will have one or more bits set + * in order to indicate the permissions needed for an affirmative authorization decision. An array is presented + * because holding any of the Permissions inside the array will be sufficient for an + * affirmative authorization.

+ *

The actual approach used to make authorization decisions is left to the implementation and is not + * specified by this interface. For example, an implementation MAY search the current ACL in the order + * the ACL entries have been stored. If a single entry is found that has the same active bits as are shown in a + * passed Permission, that entry's grant or deny state may determine the authorization decision. If + * the case of a deny state, the deny decision will only be relevant if all other Permissions passed + * in the array have also been unsuccessfully searched. If no entry is found that match the bits in the current + * ACL, provided that {@link #isEntriesInheriting()} is true, the authorization decision may be + * passed to the parent ACL. If there is no matching entry, the implementation MAY throw an exception, or make a + * predefined authorization decision.

+ *

This method must operate correctly even if the Acl only represents a subset of + * Sids. The caller is responsible for correctly handling the result if only a subset of + * Sids is represented.

* * @param permission the permission or permissions required * @param sids the security identities held by the principal - * @param administrativeMode if true denotes the query is for - * administrative purposes and no logger or auditing (if supported - * by the implementation) should be undertaken + * @param administrativeMode if true denotes the query is for administrative purposes and no logger or + * auditing (if supported by the implementation) should be undertaken * * @return true is authorization is granted * - * @throws NotFoundException MAY be thrown if an implementation cannot make - * an authoritative authorization decision - * @throws UnloadedSidException thrown if the Acl does not - * have details for one or more of the Sids passed as - * arguments + * @throws NotFoundException MAY be thrown if an implementation cannot make an authoritative authorization decision + * @throws UnloadedSidException thrown if the Acl does not have details for one or more of the + * Sids passed as arguments */ - public boolean isGranted(Permission[] permission, Sid[] sids, - boolean administrativeMode) + public boolean isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode) throws NotFoundException, UnloadedSidException; /** - * For efficiency reasons an Acl may be loaded and - * not contain entries for every Sid in the system. - * If an Acl has been loaded and does not represent every - * Sid, all methods of the Sid can only be used - * within the limited scope of the Sid instances it actually - * represents. - * - *

- * It is normal to load an Acl for only particular - * Sids if read-only authorization decisions are being made. - * However, if user interface reporting or modification of - * Acls are desired, an Acl should be loaded - * with all Sids. This method denotes whether or not the - * specified Sids have been loaded or not. - *

+ * For efficiency reasons an Acl may be loaded and not contain entries for every + * Sid in the system. If an Acl has been loaded and does not represent every + * Sid, all methods of the Sid can only be used within the limited scope of the + * Sid instances it actually represents.

It is normal to load an Acl for only + * particular Sids if read-only authorization decisions are being made. However, if user interface + * reporting or modification of Acls are desired, an Acl should be loaded with all + * Sids. This method denotes whether or not the specified Sids have been loaded or not.

* * @param sids DOCUMENT ME! * - * @return true if every passed Sid is - * represented by this Acl instance + * @return true if every passed Sid is represented by this Acl instance */ public boolean isSidLoaded(Sid[] sids); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AclFormattingUtils.java b/sandbox/src/main/java/org/acegisecurity/acls/AclFormattingUtils.java index a3aaf09816..af9969878d 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AclFormattingUtils.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AclFormattingUtils.java @@ -25,7 +25,7 @@ import org.springframework.util.Assert; * @version $Id$ */ public class AclFormattingUtils { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public static String demergePatterns(String original, String removeBits) { Assert.notNull(original, "Original string required"); @@ -74,13 +74,8 @@ public class AclFormattingUtils { } /** - * Returns a representation of the active bits in the presented mask, with - * each active bit being denoted by character "". - * - *

- * Inactive bits will be denoted by character {@link - * Permission#RESERVED_OFF}. - *

+ * Returns a representation of the active bits in the presented mask, with each active bit being denoted by + * character "".

Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.

* * @param i the integer bit mask to print the active bits for * @@ -91,13 +86,8 @@ public class AclFormattingUtils { } /** - * Returns a representation of the active bits in the presented mask, with - * each active bit being denoted by the passed character. - * - *

- * Inactive bits will be denoted by character {@link - * Permission#RESERVED_OFF}. - *

+ * Returns a representation of the active bits in the presented mask, with each active bit being denoted by + * the passed character.

Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.

* * @param mask the integer bit mask to print the active bits for * @param code the character to print when an active bit is detected @@ -105,14 +95,12 @@ public class AclFormattingUtils { * @return a 32-character representation of the bit mask */ public static String printBinary(int mask, char code) { - Assert.doesNotContain(new Character(code).toString(), - new Character(Permission.RESERVED_ON).toString(), + Assert.doesNotContain(new Character(code).toString(), new Character(Permission.RESERVED_ON).toString(), Permission.RESERVED_ON + " is a reserved character code"); - Assert.doesNotContain(new Character(code).toString(), - new Character(Permission.RESERVED_OFF).toString(), + Assert.doesNotContain(new Character(code).toString(), new Character(Permission.RESERVED_OFF).toString(), Permission.RESERVED_OFF + " is a reserved character code"); - return AclFormattingUtils.printBinary(mask, Permission.RESERVED_ON, - Permission.RESERVED_OFF).replace(Permission.RESERVED_ON, code); + return AclFormattingUtils.printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF) + .replace(Permission.RESERVED_ON, code); } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AclService.java b/sandbox/src/main/java/org/acegisecurity/acls/AclService.java index 1761f443a9..4f8357dc7d 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AclService.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AclService.java @@ -28,48 +28,39 @@ import java.util.Map; * @version $Id$ */ public interface AclService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Obtains all the Acls that apply for the passed - * Objects. - * - *

- * The returned map is keyed on the passed objects, with the values being - * the Acl instances. Any unknown objects will not have a map - * key. - *

+ * Obtains all the Acls that apply for the passed Objects.

The returned map is + * keyed on the passed objects, with the values being the Acl instances. Any unknown objects will not + * have a map key.

* * @param objects the objects to find ACL information for * * @return a map with zero or more elements (never null) + * + * @throws NotFoundException DOCUMENT ME! */ public Map readAclsById(ObjectIdentity[] objects) throws NotFoundException; /** - * Obtains all the Acls that apply for the passed - * Objects, but only for the security identifies passed. - * - *

- * Implementations MAY provide a subset of the ACLs via this - * method although this is NOT a requirement. This is intended to allow - * performance optimisations within implementations. Callers should - * therefore use this method in preference to the alternative overloaded - * version which does not have performance optimisation opportunities. - *

- * - *

- * The returned map is keyed on the passed objects, with the values being - * the Acl instances. Any unknown objects (or objects for - * which the interested Sids do not have entries) will not - * have a map key. - *

+ * Obtains all the Acls that apply for the passed Objects, but only for the + * security identifies passed.

Implementations MAY provide a subset of the ACLs via this method + * although this is NOT a requirement. This is intended to allow performance optimisations within implementations. + * Callers should therefore use this method in preference to the alternative overloaded version which does not + * have performance optimisation opportunities.

+ *

The returned map is keyed on the passed objects, with the values being the Acl + * instances. Any unknown objects (or objects for which the interested Sids do not have entries) will + * not have a map key.

* * @param objects the objects to find ACL information for - * @param sids the security identities for which ACL information is - * required (may be null to denote all entries) + * @param sids the security identities for which ACL information is required (may be null to denote + * all entries) * * @return a map with zero or more elements (never null) + * + * @throws NotFoundException DOCUMENT ME! */ - public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) throws NotFoundException; + public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) + throws NotFoundException; } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AlreadyExistsException.java b/sandbox/src/main/java/org/acegisecurity/acls/AlreadyExistsException.java index dcfde5d7a5..9ae2d3820e 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AlreadyExistsException.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AlreadyExistsException.java @@ -25,9 +25,9 @@ import org.acegisecurity.AcegiSecurityException; * @version $Id$ */ public class AlreadyExistsException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an AlreadyExistsException with the specified message. * * @param msg the detail message @@ -36,7 +36,7 @@ public class AlreadyExistsException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an AlreadyExistsException with the specified message * and root cause. * diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AuditableAccessControlEntry.java b/sandbox/src/main/java/org/acegisecurity/acls/AuditableAccessControlEntry.java index a37f1463a5..22f7a8fb3a 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AuditableAccessControlEntry.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AuditableAccessControlEntry.java @@ -1,3 +1,18 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls; /** @@ -8,6 +23,9 @@ package org.acegisecurity.acls; * */ public interface AuditableAccessControlEntry extends AccessControlEntry { - public boolean isAuditSuccess(); - public boolean isAuditFailure(); + //~ Methods ======================================================================================================== + + public boolean isAuditFailure(); + + public boolean isAuditSuccess(); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/AuditableAcl.java b/sandbox/src/main/java/org/acegisecurity/acls/AuditableAcl.java index 78dd668434..51bc15e1a9 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/AuditableAcl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/AuditableAcl.java @@ -1,3 +1,18 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls; /** @@ -8,5 +23,7 @@ package org.acegisecurity.acls; * */ public interface AuditableAcl extends MutableAcl { - public void updateAuditing(Long aceId, boolean auditSuccess, boolean auditFailure); + //~ Methods ======================================================================================================== + + public void updateAuditing(Long aceId, boolean auditSuccess, boolean auditFailure); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/ChildrenExistException.java b/sandbox/src/main/java/org/acegisecurity/acls/ChildrenExistException.java index e64366ce55..0c87da7968 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/ChildrenExistException.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/ChildrenExistException.java @@ -19,16 +19,15 @@ import org.acegisecurity.AcegiSecurityException; /** - * Thrown if an {@link Acl} cannot be deleted because children - * Acls exist. + * Thrown if an {@link Acl} cannot be deleted because children Acls exist. * * @author Ben Alex * @version $Id$ */ public class ChildrenExistException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an ChildrenExistException with the specified * message. * @@ -38,7 +37,7 @@ public class ChildrenExistException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an ChildrenExistException with the specified * message and root cause. * diff --git a/sandbox/src/main/java/org/acegisecurity/acls/IdentityUnavailableException.java b/sandbox/src/main/java/org/acegisecurity/acls/IdentityUnavailableException.java index 3256ccd68e..df97a57aa9 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/IdentityUnavailableException.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/IdentityUnavailableException.java @@ -25,9 +25,9 @@ import org.acegisecurity.AcegiSecurityException; * @version $Id$ */ public class IdentityUnavailableException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an IdentityUnavailableException with the specified message. * * @param msg the detail message @@ -36,7 +36,7 @@ public class IdentityUnavailableException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an IdentityUnavailableException with the specified message * and root cause. * diff --git a/sandbox/src/main/java/org/acegisecurity/acls/MutableAcl.java b/sandbox/src/main/java/org/acegisecurity/acls/MutableAcl.java index 773ecbc232..3cc7774df0 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/MutableAcl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/MutableAcl.java @@ -15,10 +15,10 @@ package org.acegisecurity.acls; -import java.io.Serializable; - import org.acegisecurity.acls.sid.Sid; +import java.io.Serializable; + /** * A mutable Acl. @@ -32,8 +32,9 @@ import org.acegisecurity.acls.sid.Sid; * @version $Id$ */ public interface MutableAcl extends Acl { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + public void deleteAce(Long aceId) throws NotFoundException; /** * Obtains an identifier that represents this MutableAcl. @@ -42,11 +43,10 @@ public interface MutableAcl extends Acl { */ public Serializable getId(); - - public void deleteAce(Long aceId) throws NotFoundException ; + public void insertAce(Long afterAceId, Permission permission, Sid sid, boolean granting) + throws NotFoundException; - public void insertAce(Long afterAceId, Permission permission, Sid sid, - boolean granting) throws NotFoundException; + public void setEntriesInheriting(boolean entriesInheriting); /** * Changes the parent of this ACL. @@ -54,8 +54,7 @@ public interface MutableAcl extends Acl { * @param newParent the new parent */ public void setParent(MutableAcl newParent); - - public void updateAce(Long aceId, Permission permission) throws NotFoundException; - - public void setEntriesInheriting(boolean entriesInheriting); + + public void updateAce(Long aceId, Permission permission) + throws NotFoundException; } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/MutableAclService.java b/sandbox/src/main/java/org/acegisecurity/acls/MutableAclService.java index 64676cbc2f..66b73f9fe5 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/MutableAclService.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/MutableAclService.java @@ -17,6 +17,7 @@ package org.acegisecurity.acls; import org.acegisecurity.acls.objectidentity.ObjectIdentity; + /** * Provides support for creating and storing Acl instances. * @@ -24,18 +25,17 @@ import org.acegisecurity.acls.objectidentity.ObjectIdentity; * @version $Id$ */ public interface MutableAclService extends AclService { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Creates an empty Acl object in the database. It will have - * no entries. The returned object will then be used to add entries. + * Creates an empty Acl object in the database. It will have no entries. The returned object + * will then be used to add entries. * * @param object the object identity to create * * @return an ACL object with its ID set * - * @throws AlreadyExistsException if the passed object identity already has - * a record + * @throws AlreadyExistsException if the passed object identity already has a record */ public MutableAcl createAcl(ObjectIdentity object) throws AlreadyExistsException; @@ -46,16 +46,14 @@ public interface MutableAclService extends AclService { * @param object the object identity to remove * @param deleteChildren whether to cascade the delete to children * - * @throws ChildrenExistException if the deleteChildren argument was - * false but children exist + * @throws ChildrenExistException if the deleteChildren argument was false but children exist */ public void deleteAcl(ObjectIdentity object, boolean deleteChildren) throws ChildrenExistException; /** - * Locates all object identities that use the specified parent. This is - * useful for administration tools, and before issuing a {@link - * #deleteAcl(ObjectIdentity, boolean)}. + * Locates all object identities that use the specified parent. This is useful for administration tools, + * and before issuing a {@link #deleteAcl(ObjectIdentity, boolean)}. * * @param parentIdentity to locate children of * @@ -68,10 +66,9 @@ public interface MutableAclService extends AclService { * * @param acl to modify * - * @throws NotFoundException if the relevant record could not be found (did - * you remember to use {@link #createAcl(ObjectIdentity)} to - * create the object, rather than creating it with the - * new keyword?) + * @throws NotFoundException if the relevant record could not be found (did you remember to use {@link + * #createAcl(ObjectIdentity)} to create the object, rather than creating it with the new + * keyword?) */ public void updateAcl(MutableAcl acl) throws NotFoundException; } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/NotFoundException.java b/sandbox/src/main/java/org/acegisecurity/acls/NotFoundException.java index 6309d284cf..4129bb18a6 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/NotFoundException.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/NotFoundException.java @@ -25,9 +25,9 @@ import org.acegisecurity.AcegiSecurityException; * @version $Id$ */ public class NotFoundException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an NotFoundException with the specified message. * * @param msg the detail message @@ -36,7 +36,7 @@ public class NotFoundException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an NotFoundException with the specified message * and root cause. * diff --git a/sandbox/src/main/java/org/acegisecurity/acls/OwnershipAcl.java b/sandbox/src/main/java/org/acegisecurity/acls/OwnershipAcl.java index 239d02f1d0..f4af13deb8 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/OwnershipAcl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/OwnershipAcl.java @@ -17,6 +17,7 @@ package org.acegisecurity.acls; import org.acegisecurity.acls.sid.Sid; + /** * A mutable ACL that provides ownership capabilities. * @@ -29,7 +30,7 @@ import org.acegisecurity.acls.sid.Sid; * @version $Id$ */ public interface OwnershipAcl extends MutableAcl { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Sid getOwner(); diff --git a/sandbox/src/main/java/org/acegisecurity/acls/Permission.java b/sandbox/src/main/java/org/acegisecurity/acls/Permission.java index f4d84511f0..667b226419 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/Permission.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/Permission.java @@ -25,13 +25,13 @@ import org.acegisecurity.acls.sid.Sid; * @version $Id$ */ public interface Permission { - //~ Static fields/initializers ============================================= + //~ Static fields/initializers ===================================================================================== public static final char RESERVED_ON = '~'; public static final char RESERVED_OFF = '.'; - public static final String THIRTY_TWO_RESERVED_OFF = "................................"; + public static final String THIRTY_TWO_RESERVED_OFF = "................................"; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Returns the bits that represents the permission. @@ -41,28 +41,15 @@ public interface Permission { public int getMask(); /** - * Returns a 32-character long bit pattern String representing - * this permission. - * - *

- * Implementations are free to format the pattern as they see fit, although - * under no circumstances may {@link #RESERVED_OFF} or {@link - * #RESERVED_ON} be used within the pattern. An exemption is in the case - * of {@link #RESERVED_OFF} which is used to denote a bit that is off - * (clear). Implementations may also elect to use {@link #RESERVED_ON} - * internally for computation purposes, although this method may not - * return any String containing {@link #RESERVED_ON}. - *

- * - *

- * The returned String must be 32 characters in length. - *

- * - *

- * This method is only used for user interface and logging purposes. It is - * not used in any permission calculations. Therefore, duplication of - * characters within the output is permitted. - *

+ * Returns a 32-character long bit pattern String representing this permission.

Implementations + * are free to format the pattern as they see fit, although under no circumstances may {@link #RESERVED_OFF} or + * {@link #RESERVED_ON} be used within the pattern. An exemption is in the case of {@link #RESERVED_OFF} which is + * used to denote a bit that is off (clear). Implementations may also elect to use {@link #RESERVED_ON} internally + * for computation purposes, although this method may not return any String containing {@link + * #RESERVED_ON}.

+ *

The returned String must be 32 characters in length.

+ *

This method is only used for user interface and logging purposes. It is not used in any permission + * calculations. Therefore, duplication of characters within the output is permitted.

* * @return a 32-character bit pattern */ diff --git a/sandbox/src/main/java/org/acegisecurity/acls/UnloadedSidException.java b/sandbox/src/main/java/org/acegisecurity/acls/UnloadedSidException.java index 1228cb98f6..c06130b095 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/UnloadedSidException.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/UnloadedSidException.java @@ -19,17 +19,16 @@ import org.acegisecurity.AcegiSecurityException; /** - * Thrown if an {@link Acl} cannot perform an operation because it only - * loaded a subset of Sids and the caller has requested details - * for an unloaded Sid. + * Thrown if an {@link Acl} cannot perform an operation because it only loaded a subset of Sids and + * the caller has requested details for an unloaded Sid. * * @author Ben Alex * @version $Id$ */ public class UnloadedSidException extends AcegiSecurityException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructs an NotFoundException with the specified message. * * @param msg the detail message @@ -38,7 +37,7 @@ public class UnloadedSidException extends AcegiSecurityException { super(msg); } - /** +/** * Constructs an NotFoundException with the specified message * and root cause. * diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/AccessControlEntryImpl.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/AccessControlEntryImpl.java index 4f1c89f0ad..b1c25929b4 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/AccessControlEntryImpl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/AccessControlEntryImpl.java @@ -1,124 +1,149 @@ -package org.acegisecurity.acls.domain; +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import java.io.Serializable; +package org.acegisecurity.acls.domain; import org.acegisecurity.acls.AccessControlEntry; import org.acegisecurity.acls.Acl; import org.acegisecurity.acls.AuditableAccessControlEntry; import org.acegisecurity.acls.Permission; import org.acegisecurity.acls.sid.Sid; + import org.springframework.util.Assert; +import java.io.Serializable; + + /** * An immutable default implementation of AccessControlEntry. - * + * * @author Ben Alex * @version $Id$ */ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAccessControlEntry { - private Serializable id; - private Acl acl; - private Sid sid; - private Permission permission; - private boolean granting; - private boolean auditSuccess = false; - private boolean auditFailure = false; - private boolean aceDirty = false; - - public void clearDirtyFlags() { - this.aceDirty = false; - } - - public boolean equals(Object arg0) { - if (!(arg0 instanceof AccessControlEntryImpl)) { - return false; - } - AccessControlEntryImpl rhs = (AccessControlEntryImpl) arg0; - if (this.aceDirty != rhs.isAceDirty() || - this.auditFailure != rhs.isAuditFailure() || - this.auditSuccess != rhs.isAuditSuccess() || - this.granting != rhs.isGranting() || - !this.acl.equals(rhs.getAcl()) || - !this.id.equals(rhs.getId()) || - !this.permission.equals(rhs.getPermission()) || - !this.sid.equals(rhs.getSid()) ) { - return false; - } - return true; - } + //~ Instance fields ================================================================================================ + private Acl acl; + private Permission permission; + private Serializable id; + private Sid sid; + private boolean aceDirty = false; + private boolean auditFailure = false; + private boolean auditSuccess = false; + private boolean granting; + //~ Constructors =================================================================================================== - public AccessControlEntryImpl(Serializable id, Acl acl, Sid sid, Permission permission, boolean granting, boolean auditSuccess, boolean auditFailure) { - Assert.notNull(acl, "Acl required"); - Assert.notNull(sid, "Sid required"); - Assert.notNull(permission, "Permission required"); - this.id = id; - this.acl = acl; // can be null - this.sid = sid; - this.permission = permission; - this.granting = granting; - this.auditSuccess = auditSuccess; - this.auditFailure = auditFailure; - } - - public Acl getAcl() { - return acl; - } - public boolean isGranting() { - return granting; - } - public Serializable getId() { - return id; - } - public Permission getPermission() { - return permission; - } - public Sid getSid() { - return sid; - } - - void setPermission(Permission permission) { - Assert.notNull(permission, "Permission required"); - this.permission = permission; - this.aceDirty = true; - } - - void setId(Serializable id) { - this.id = id; - } - - public boolean isAuditFailure() { - return auditFailure; - } + public AccessControlEntryImpl(Serializable id, Acl acl, Sid sid, Permission permission, boolean granting, + boolean auditSuccess, boolean auditFailure) { + Assert.notNull(acl, "Acl required"); + Assert.notNull(sid, "Sid required"); + Assert.notNull(permission, "Permission required"); + this.id = id; + this.acl = acl; // can be null + this.sid = sid; + this.permission = permission; + this.granting = granting; + this.auditSuccess = auditSuccess; + this.auditFailure = auditFailure; + } - void setAuditFailure(boolean auditFailure) { - this.auditFailure = auditFailure; - this.aceDirty = true; - } + //~ Methods ======================================================================================================== - public boolean isAuditSuccess() { - return auditSuccess; - } + public void clearDirtyFlags() { + this.aceDirty = false; + } - void setAuditSuccess(boolean auditSuccess) { - this.auditSuccess = auditSuccess; - this.aceDirty = true; - } - - public boolean isAceDirty() { - return aceDirty; - } - + public boolean equals(Object arg0) { + if (!(arg0 instanceof AccessControlEntryImpl)) { + return false; + } - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("AccessControlEntryImpl["); - sb.append("id: ").append(this.id).append("; "); - sb.append("granting: ").append(this.granting).append("; "); - sb.append("sid: ").append(this.sid).append("; "); - sb.append("permission: ").append(this.permission); - sb.append("]"); - return sb.toString(); - } + AccessControlEntryImpl rhs = (AccessControlEntryImpl) arg0; + + if ((this.aceDirty != rhs.isAceDirty()) || (this.auditFailure != rhs.isAuditFailure()) + || (this.auditSuccess != rhs.isAuditSuccess()) || (this.granting != rhs.isGranting()) + || !this.acl.equals(rhs.getAcl()) || !this.id.equals(rhs.getId()) + || !this.permission.equals(rhs.getPermission()) || !this.sid.equals(rhs.getSid())) { + return false; + } + + return true; + } + + public Acl getAcl() { + return acl; + } + + public Serializable getId() { + return id; + } + + public Permission getPermission() { + return permission; + } + + public Sid getSid() { + return sid; + } + + public boolean isAceDirty() { + return aceDirty; + } + + public boolean isAuditFailure() { + return auditFailure; + } + + public boolean isAuditSuccess() { + return auditSuccess; + } + + public boolean isGranting() { + return granting; + } + + void setAuditFailure(boolean auditFailure) { + this.auditFailure = auditFailure; + this.aceDirty = true; + } + + void setAuditSuccess(boolean auditSuccess) { + this.auditSuccess = auditSuccess; + this.aceDirty = true; + } + + void setId(Serializable id) { + this.id = id; + } + + void setPermission(Permission permission) { + Assert.notNull(permission, "Permission required"); + this.permission = permission; + this.aceDirty = true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("AccessControlEntryImpl["); + sb.append("id: ").append(this.id).append("; "); + sb.append("granting: ").append(this.granting).append("; "); + sb.append("sid: ").append(this.sid).append("; "); + sb.append("permission: ").append(this.permission); + sb.append("]"); + + return sb.toString(); + } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/AclImpl.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/AclImpl.java index bde9b465d0..b99fb33b69 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/AclImpl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/AclImpl.java @@ -15,14 +15,10 @@ package org.acegisecurity.acls.domain; -import java.io.Serializable; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; - import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.acls.AccessControlEntry; import org.acegisecurity.acls.Acl; import org.acegisecurity.acls.AuditableAcl; @@ -34,9 +30,17 @@ import org.acegisecurity.acls.UnloadedSidException; import org.acegisecurity.acls.objectidentity.ObjectIdentity; import org.acegisecurity.acls.sid.PrincipalSid; import org.acegisecurity.acls.sid.Sid; + import org.acegisecurity.context.SecurityContextHolder; + import org.springframework.util.Assert; +import java.io.Serializable; + +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + /** * Base implementation of Acl. @@ -45,31 +49,33 @@ import org.springframework.util.Assert; * @version $Id */ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { - //~ Instance fields ======================================================== - private static final int CHANGE_OWNERSHIP = 0; - private static final int CHANGE_AUDITING = 1; - private static final int CHANGE_GENERAL = 2; - - private GrantedAuthority gaTakeOwnership; - private GrantedAuthority gaModifyAuditing; - private GrantedAuthority gaGeneralChanges; - - private Acl parentAcl; + //~ Static fields/initializers ===================================================================================== + + private static final int CHANGE_OWNERSHIP = 0; + private static final int CHANGE_AUDITING = 1; + private static final int CHANGE_GENERAL = 2; + + //~ Instance fields ================================================================================================ + + private Acl parentAcl; private AuditLogger auditLogger = new ConsoleAuditLogger(); // AuditableAcl + private GrantedAuthority gaGeneralChanges; + private GrantedAuthority gaModifyAuditing; + private GrantedAuthority gaTakeOwnership; private List aces = new Vector(); private List deletedAces = new Vector(); private Long id; private ObjectIdentity objectIdentity; private Sid owner; // OwnershipAcl - private boolean entriesInheriting = false; private Sid[] loadedSids = null; // includes all SIDs the WHERE clause covered, even if there was no ACE for a SID private boolean aclDirty = false; // for snapshot detection private boolean addedAces = false; // for snapshot detection + private boolean entriesInheriting = false; private boolean updatedAces = false; // for snapshot detection - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Minimal constructor, which should be used {@link * org.acegisecurity.acls.MutableAclService#createAcl(ObjectIdentity)}. * @@ -81,37 +87,14 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { * index 2 is the authority needed to change other ACL and ACE details) (required) */ public AclImpl(ObjectIdentity objectIdentity, Long id, GrantedAuthority[] auths) { - Assert.notNull(objectIdentity, "Object Identity required"); + Assert.notNull(objectIdentity, "Object Identity required"); Assert.notNull(id, "Id required"); this.objectIdentity = objectIdentity; this.id = id; this.setAuthorities(auths); } - - /** - * Change the special adminstrative permissions honoured by this - * object. - * - *

- * Normally a principal must be the owner of the ACL in order to - * make most changes. The authorities passed to this method provide - * a way for non-owners to modify the ACL (and indeed modify audit - * parameters, which are not available to ACL owners). - * - * @param auths an array of GrantedAuthoritys that have - * administrative permissions (index 0 is the authority needed to change - * ownership, index 1 is the authority needed to modify auditing details, - * index 2 is the authority needed to change other ACL and ACE details) - */ - private void setAuthorities(GrantedAuthority[] auths) { - Assert.notEmpty(auths, "GrantedAuthority[] with three elements required"); - Assert.isTrue(auths.length == 3, "GrantedAuthority[] with three elements required"); - this.gaTakeOwnership = auths[0]; - this.gaModifyAuditing = auths[1]; - this.gaGeneralChanges = auths[2]; - } - /** +/** * Full constructor, which should be used by persistence tools that do not * provide field-level access features. * @@ -128,8 +111,8 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { * this ACL * @param owner the owner (required) */ - public AclImpl(ObjectIdentity objectIdentity, Long id, Acl parentAcl, GrantedAuthority[] auths, - Sid[] loadedSids, boolean entriesInheriting, Sid owner) { + public AclImpl(ObjectIdentity objectIdentity, Long id, Acl parentAcl, GrantedAuthority[] auths, Sid[] loadedSids, + boolean entriesInheriting, Sid owner) { Assert.notNull(objectIdentity, "Object Identity required"); Assert.notNull(id, "Id required"); Assert.notNull(owner, "Owner required"); @@ -142,54 +125,28 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { this.owner = owner; } - /** +/** * Private no-argument constructor for use by reflection-based persistence * tools along with field-level access. */ private AclImpl() {} - //~ Methods ================================================================ - - protected void securityCheck(int changeType) { - if (SecurityContextHolder.getContext() == null || SecurityContextHolder.getContext().getAuthentication() == null || !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) { - throw new AccessDeniedException("Authenticated principal required to operate with ACLs"); - } - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - // Check if authorized by virtue of ACL ownership - Sid currentUser = new PrincipalSid(authentication); - if (currentUser.equals(this.owner) && (changeType == CHANGE_GENERAL || changeType == CHANGE_OWNERSHIP)) { - return; - } - - // Not authorized by ACL ownership; try via adminstrative permissions - GrantedAuthority requiredAuthority = null; - if (changeType == CHANGE_AUDITING) { - requiredAuthority = this.gaModifyAuditing; - } else if (changeType == CHANGE_GENERAL) { - requiredAuthority = this.gaGeneralChanges; - } else if (changeType == CHANGE_OWNERSHIP) { - requiredAuthority = this.gaTakeOwnership; - } else { - throw new IllegalArgumentException("Unknown change type"); - } - - // Iterate this principal's authorities to determine right - GrantedAuthority[] auths = authentication.getAuthorities(); - for (int i = 0; i < auths.length; i++) { - if (requiredAuthority.equals(auths[i])) { - return; - } - } - - throw new AccessDeniedException("Principal does not have required ACL permissions to perform requested operation"); + //~ Methods ======================================================================================================== + + /** + * Clears the dirty flags on the Acl, but not any associated ACEs. + */ + public void clearDirtyFlags() { + this.aclDirty = false; + this.addedAces = false; + this.updatedAces = false; } public void deleteAce(Long aceId) throws NotFoundException { securityCheck(CHANGE_GENERAL); - - synchronized (aces) { - int offset = findAceOffset(aceId); + + synchronized (aces) { + int offset = findAceOffset(aceId); if (offset == 1) { throw new NotFoundException("Requested ACE ID not found"); @@ -221,12 +178,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { return (AccessControlEntry[]) aces.toArray(new AccessControlEntry[] {}); } - public void setEntriesInheriting(boolean entriesInheriting) { - securityCheck(CHANGE_GENERAL); - this.entriesInheriting = entriesInheriting; - this.aclDirty = true; - } - public Serializable getId() { return this.id; } @@ -243,14 +194,13 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { return parentAcl; } - public void insertAce(Long afterAceId, Permission permission, Sid sid, - boolean granting) throws NotFoundException { + public void insertAce(Long afterAceId, Permission permission, Sid sid, boolean granting) + throws NotFoundException { securityCheck(CHANGE_GENERAL); Assert.notNull(permission, "Permission required"); Assert.notNull(sid, "Sid required"); - AccessControlEntryImpl ace = new AccessControlEntryImpl(null, this, - sid, permission, granting, false, false); + AccessControlEntryImpl ace = new AccessControlEntryImpl(null, this, sid, permission, granting, false, false); synchronized (aces) { if (afterAceId != null) { @@ -264,34 +214,13 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { } else { aces.add(ace); } - } this.addedAces = true; } - public boolean isSidLoaded(Sid[] sids) { - // If loadedSides is null, this indicates all SIDs were loaded - // Also return true if the caller didn't specify a SID to find - if (this.loadedSids == null || sids == null || sids.length == 0) { - return true; - } - - // This ACL applies to a SID subset. Iterate to check it applies - for (int i = 0; i < sids.length; i++) { - boolean found = false; - for (int y = 0; y < this.loadedSids.length; y++) { - if (sids[i].equals(this.loadedSids[y])) { - // this SID is OK - found = true; - break; // out of loadedSids for loop - } - } - if (!found) { - return false; - } - } - return true; + public boolean isAclDirty() { + return aclDirty; } public boolean isEntriesInheriting() { @@ -299,44 +228,34 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { } /** - * Determines authorization. The order of the permission and - * sid arguments is extremely important! The method - * will iterate through each of the permissions in the order - * specified. For each iteration, all of the sids will be - * considered, again in the order they are presented. The iteration of - * each permission:sid combination will then inspect the ACEs - * in the order they appear in the ACL. When the first full match - * is found (ie an ACE that has the SID currently being searched for and - * the exact permission bit mask being search for), the grant or deny flag - * for that ACE will prevail. If the ACE specifies to grant access, the - * method will return true. If the ACE specifies to deny - * access, the loop will stop and the next permission - * iteration will be performed. If each permission indicates to deny - * access, the first deny ACE found will be considered the reason for the - * failure (as it was the first match found, and is therefore the one most - * logically requiring changes - although not always). If absolutely no - * matching ACE was found at all for any permission, the parent ACL will - * be tried (provided that there is a parent and {@link - * #isEntriesInheriting()} is true. The parent ACL will also - * scan its parent and so on. If ultimately no matching ACE is found, a - * NotFoundException will be thrown and the caller will need - * to decide how to handle the permission check. Similarly, if any of the - * passed SIDs were not loaded by the ACL, the - * UnloadedSidException will be thrown. + * Determines authorization. The order of the permission and sid arguments is + * extremely important! The method will iterate through each of the permissions in the order + * specified. For each iteration, all of the sids will be considered, again in the order they are + * presented. The iteration of each permission:sid combination will then inspect the ACEs in the + * order they appear in the ACL. When the first full match is found (ie an ACE that has the SID currently + * being searched for and the exact permission bit mask being search for), the grant or deny flag for that ACE + * will prevail. If the ACE specifies to grant access, the method will return true. If the ACE + * specifies to deny access, the loop will stop and the next permission iteration will be performed. + * If each permission indicates to deny access, the first deny ACE found will be considered the reason for the + * failure (as it was the first match found, and is therefore the one most logically requiring changes - although + * not always). If absolutely no matching ACE was found at all for any permission, the parent ACL will be tried + * (provided that there is a parent and {@link #isEntriesInheriting()} is true. The parent ACL will + * also scan its parent and so on. If ultimately no matching ACE is found, a NotFoundException will + * be thrown and the caller will need to decide how to handle the permission check. Similarly, if any of the + * passed SIDs were not loaded by the ACL, the UnloadedSidException will be thrown. * * @param permission the exact permissions to scan for (order is important) * @param sids the exact SIDs to scan for (order is important) - * @param administrativeMode if true denotes the query is for - * administrative purposes and no auditing will be undertaken + * @param administrativeMode if true denotes the query is for administrative purposes and no auditing + * will be undertaken * - * @return true if one of the permissions has been granted, - * false if one of the permissions has been - * specifically revoked + * @return true if one of the permissions has been granted, false if one of the + * permissions has been specifically revoked * - * @throws NotFoundException if an exact ACE for one of the permission bit - * masks and SID combination could not be found - * @throws UnloadedSidException if the passed SIDs are unknown to this ACL - * because the ACL was only loaded for a subset of SIDs + * @throws NotFoundException if an exact ACE for one of the permission bit masks and SID combination could not be + * found + * @throws UnloadedSidException if the passed SIDs are unknown to this ACL because the ACL was only loaded for a + * subset of SIDs */ public boolean isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode) throws NotFoundException, UnloadedSidException { @@ -346,7 +265,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { if (!this.isSidLoaded(sids)) { throw new UnloadedSidException("ACL was not loaded for one or more SID"); } - + AccessControlEntry firstRejection = null; for (int i = 0; i < permission.length; i++) { @@ -356,17 +275,15 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { boolean scanNextSid = true; while (acesIterator.hasNext()) { - AccessControlEntry ace = (AccessControlEntry) acesIterator - .next(); + AccessControlEntry ace = (AccessControlEntry) acesIterator.next(); - if ((ace.getPermission().getMask() == permission[i].getMask()) - && ace.getSid().equals(sids[x])) { + if ((ace.getPermission().getMask() == permission[i].getMask()) && ace.getSid().equals(sids[x])) { // Found a matching ACE, so its authorization decision will prevail if (ace.isGranting()) { // Success - if (!administrativeMode) { + if (!administrativeMode) { auditLogger.logIfNeeded(true, ace); - } + } return true; } else { @@ -394,10 +311,9 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { if (firstRejection != null) { // We found an ACE to reject the request at this point, as no // other ACEs were found that granted a different permission - - if (!administrativeMode) { - auditLogger.logIfNeeded(false, firstRejection); - } + if (!administrativeMode) { + auditLogger.logIfNeeded(false, firstRejection); + } return false; } @@ -405,14 +321,106 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { // No matches have been found so far if (isEntriesInheriting() && (parentAcl != null)) { // We have a parent, so let them try to find a matching ACE - return parentAcl.isGranted(permission, sids, false); + return parentAcl.isGranted(permission, sids, false); } else { // We either have no parent, or we're the uppermost parent - throw new NotFoundException( - "Unable to locate a matching ACE for passed permissions and SIDs"); + throw new NotFoundException("Unable to locate a matching ACE for passed permissions and SIDs"); } } + public boolean isSidLoaded(Sid[] sids) { + // If loadedSides is null, this indicates all SIDs were loaded + // Also return true if the caller didn't specify a SID to find + if ((this.loadedSids == null) || (sids == null) || (sids.length == 0)) { + return true; + } + + // This ACL applies to a SID subset. Iterate to check it applies + for (int i = 0; i < sids.length; i++) { + boolean found = false; + + for (int y = 0; y < this.loadedSids.length; y++) { + if (sids[i].equals(this.loadedSids[y])) { + // this SID is OK + found = true; + + break; // out of loadedSids for loop + } + } + + if (!found) { + return false; + } + } + + return true; + } + + protected void securityCheck(int changeType) { + if ((SecurityContextHolder.getContext() == null) + || (SecurityContextHolder.getContext().getAuthentication() == null) + || !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) { + throw new AccessDeniedException("Authenticated principal required to operate with ACLs"); + } + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // Check if authorized by virtue of ACL ownership + Sid currentUser = new PrincipalSid(authentication); + + if (currentUser.equals(this.owner) && ((changeType == CHANGE_GENERAL) || (changeType == CHANGE_OWNERSHIP))) { + return; + } + + // Not authorized by ACL ownership; try via adminstrative permissions + GrantedAuthority requiredAuthority = null; + + if (changeType == CHANGE_AUDITING) { + requiredAuthority = this.gaModifyAuditing; + } else if (changeType == CHANGE_GENERAL) { + requiredAuthority = this.gaGeneralChanges; + } else if (changeType == CHANGE_OWNERSHIP) { + requiredAuthority = this.gaTakeOwnership; + } else { + throw new IllegalArgumentException("Unknown change type"); + } + + // Iterate this principal's authorities to determine right + GrantedAuthority[] auths = authentication.getAuthorities(); + + for (int i = 0; i < auths.length; i++) { + if (requiredAuthority.equals(auths[i])) { + return; + } + } + + throw new AccessDeniedException( + "Principal does not have required ACL permissions to perform requested operation"); + } + + /** + * Change the special adminstrative permissions honoured by this object.

Normally a principal must be the + * owner of the ACL in order to make most changes. The authorities passed to this method provide a way for + * non-owners to modify the ACL (and indeed modify audit parameters, which are not available to ACL owners).

+ * + * @param auths an array of GrantedAuthoritys that have administrative permissions (index 0 is the + * authority needed to change ownership, index 1 is the authority needed to modify auditing details, index + * 2 is the authority needed to change other ACL and ACE details) + */ + private void setAuthorities(GrantedAuthority[] auths) { + Assert.notEmpty(auths, "GrantedAuthority[] with three elements required"); + Assert.isTrue(auths.length == 3, "GrantedAuthority[] with three elements required"); + this.gaTakeOwnership = auths[0]; + this.gaModifyAuditing = auths[1]; + this.gaGeneralChanges = auths[2]; + } + + public void setEntriesInheriting(boolean entriesInheriting) { + securityCheck(CHANGE_GENERAL); + this.entriesInheriting = entriesInheriting; + this.aclDirty = true; + } + public void setOwner(Sid newOwner) { securityCheck(CHANGE_OWNERSHIP); Assert.notNull(newOwner, "Owner required"); @@ -427,11 +435,39 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { this.aclDirty = true; } + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("AclImpl["); + sb.append("id: ").append(this.id).append("; "); + sb.append("objectIdentity: ").append(this.objectIdentity).append("; "); + sb.append("owner: ").append(this.owner).append("; "); + + Iterator iterator = this.aces.iterator(); + int count = 0; + + while (iterator.hasNext()) { + count++; + + if (count == 1) { + sb.append("\r\n"); + } + + sb.append(iterator.next().toString()).append("\r\n"); + } + + sb.append("inheriting: ").append(this.entriesInheriting).append("; "); + sb.append("parent: ").append((this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity()); + sb.append("]"); + + return sb.toString(); + } + public void updateAce(Long aceId, Permission permission) throws NotFoundException { securityCheck(CHANGE_GENERAL); + synchronized (aces) { - int offset = findAceOffset(aceId); + int offset = findAceOffset(aceId); if (offset == 1) { throw new NotFoundException("Requested ACE ID not found"); @@ -440,15 +476,14 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { AccessControlEntryImpl ace = (AccessControlEntryImpl) aces.get(offset); ace.setPermission(permission); } - + this.updatedAces = true; } - public void updateAuditing(Long aceId, boolean auditSuccess, - boolean auditFailure) { + public void updateAuditing(Long aceId, boolean auditSuccess, boolean auditFailure) { securityCheck(CHANGE_AUDITING); - - synchronized (aces) { + + synchronized (aces) { int offset = findAceOffset(aceId); if (offset == 1) { @@ -458,43 +493,8 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl { AccessControlEntryImpl ace = (AccessControlEntryImpl) aces.get(offset); ace.setAuditSuccess(auditSuccess); ace.setAuditFailure(auditFailure); - } + } + this.updatedAces = true; } - - /** - * Clears the dirty flags on the Acl, but not any - * associated ACEs. - */ - public void clearDirtyFlags() { - this.aclDirty = false; - this.addedAces = false; - this.updatedAces = false; - } - - public boolean isAclDirty() { - return aclDirty; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("AclImpl["); - sb.append("id: ").append(this.id).append("; "); - sb.append("objectIdentity: ").append(this.objectIdentity).append("; "); - sb.append("owner: ").append(this.owner).append("; "); - Iterator iterator = this.aces.iterator(); - int count = 0; - while (iterator.hasNext()) { - count++; - if (count == 1) { - sb.append("\r\n"); - } - sb.append(iterator.next().toString()).append("\r\n"); - } - sb.append("inheriting: ").append(this.entriesInheriting).append("; "); - sb.append("parent: ").append(this.parentAcl == null ? "Null" : this.parentAcl.getObjectIdentity()); - sb.append("]"); - return sb.toString(); - } - } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/AuditLogger.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/AuditLogger.java index 538816fc5c..d618761c7e 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/AuditLogger.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/AuditLogger.java @@ -1,7 +1,23 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.domain; import org.acegisecurity.acls.AccessControlEntry; + /** * Used by AclImpl to log audit events. * @@ -10,5 +26,7 @@ import org.acegisecurity.acls.AccessControlEntry; * */ public interface AuditLogger { - public void logIfNeeded(boolean granted, AccessControlEntry ace); + //~ Methods ======================================================================================================== + + public void logIfNeeded(boolean granted, AccessControlEntry ace); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/BasePermission.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/BasePermission.java index 143a513e98..e840c4a3bf 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/BasePermission.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/BasePermission.java @@ -1,66 +1,102 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.domain; import org.acegisecurity.acls.AclFormattingUtils; import org.acegisecurity.acls.Permission; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class BasePermission implements Permission { - public static final Permission READ = new BasePermission(1<<0, 'R'); // 1 - public static final Permission WRITE = new BasePermission(1<<1, 'W'); // 2 - public static final Permission CREATE = new BasePermission(1<<2, 'C'); // 4 - public static final Permission ADMINISTRATION = new BasePermission(1<<3, 'A'); // 8 - - private int mask; - private char code; - - private BasePermission(int mask, char code) { - this.mask = mask; - this.code = code; - } - - public boolean equals(Object arg0) { - if (!(arg0 instanceof BasePermission)) { - return false; - } - BasePermission rhs = (BasePermission) arg0; - return (this.mask == rhs.getMask()); - } + //~ Static fields/initializers ===================================================================================== - /** - * Dynamically creates a CumulativePermission - * representing the active bits in the passed mask. - * NB: Only uses BasePermission! - * - * @param mask to review - */ - public static Permission buildFromMask(int mask) { - CumulativePermission permission = new CumulativePermission(); - - // TODO: Write the rest of it to iterate through the 32 bits and instantiate BasePermissions - if (mask == 1) { - permission.set(READ); - } - if (mask == 2) { - permission.set(WRITE); - } - if (mask == 4) { - permission.set(CREATE); - } - if (mask == 8) { - permission.set(ADMINISTRATION); - } - return permission; - } - - public int getMask() { - return mask; - } + public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1 + public static final Permission WRITE = new BasePermission(1 << 1, 'W'); // 2 + public static final Permission CREATE = new BasePermission(1 << 2, 'C'); // 4 + public static final Permission ADMINISTRATION = new BasePermission(1 << 3, 'A'); // 8 - public String toString() { - return "BasePermission[" + getPattern() + "=" + mask + "]"; - } + //~ Instance fields ================================================================================================ - public String getPattern() { - return AclFormattingUtils.printBinary(mask, code); - } + private char code; + private int mask; + //~ Constructors =================================================================================================== + + private BasePermission(int mask, char code) { + this.mask = mask; + this.code = code; + } + + //~ Methods ======================================================================================================== + + /** + * Dynamically creates a CumulativePermission representing the active bits in the passed mask. + * NB: Only uses BasePermission! + * + * @param mask to review + * + * @return DOCUMENT ME! + */ + public static Permission buildFromMask(int mask) { + CumulativePermission permission = new CumulativePermission(); + + // TODO: Write the rest of it to iterate through the 32 bits and instantiate BasePermissions + if (mask == 1) { + permission.set(READ); + } + + if (mask == 2) { + permission.set(WRITE); + } + + if (mask == 4) { + permission.set(CREATE); + } + + if (mask == 8) { + permission.set(ADMINISTRATION); + } + + return permission; + } + + public boolean equals(Object arg0) { + if (!(arg0 instanceof BasePermission)) { + return false; + } + + BasePermission rhs = (BasePermission) arg0; + + return (this.mask == rhs.getMask()); + } + + public int getMask() { + return mask; + } + + public String getPattern() { + return AclFormattingUtils.printBinary(mask, code); + } + + public String toString() { + return "BasePermission[" + getPattern() + "=" + mask + "]"; + } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/ConsoleAuditLogger.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/ConsoleAuditLogger.java index fe44081fc6..a0f2ff230f 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/ConsoleAuditLogger.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/ConsoleAuditLogger.java @@ -1,19 +1,46 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.domain; import org.acegisecurity.acls.AccessControlEntry; import org.acegisecurity.acls.AuditableAccessControlEntry; + import org.springframework.util.Assert; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class ConsoleAuditLogger implements AuditLogger { - public void logIfNeeded(boolean granted, AccessControlEntry ace) { - Assert.notNull(ace, "AccessControlEntry required"); - if (ace instanceof AuditableAccessControlEntry) { - AuditableAccessControlEntry auditableAce = (AuditableAccessControlEntry) ace; - if (granted && auditableAce.isAuditSuccess()) { - System.out.println("GRANTED due to ACE: " + ace); - } else if (!granted && auditableAce.isAuditFailure()) { - System.out.println("DENIED due to ACE: " + ace); - } - } - } + //~ Methods ======================================================================================================== + + public void logIfNeeded(boolean granted, AccessControlEntry ace) { + Assert.notNull(ace, "AccessControlEntry required"); + + if (ace instanceof AuditableAccessControlEntry) { + AuditableAccessControlEntry auditableAce = (AuditableAccessControlEntry) ace; + + if (granted && auditableAce.isAuditSuccess()) { + System.out.println("GRANTED due to ACE: " + ace); + } else if (!granted && auditableAce.isAuditFailure()) { + System.out.println("DENIED due to ACE: " + ace); + } + } + } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/domain/CumulativePermission.java b/sandbox/src/main/java/org/acegisecurity/acls/domain/CumulativePermission.java index bcdb0f7b96..6bf953f855 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/domain/CumulativePermission.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/domain/CumulativePermission.java @@ -20,40 +20,26 @@ import org.acegisecurity.acls.Permission; /** - * Represents a Permission that is constructed at runtime from - * other permissions. - * - *

- * Methods return this, in order to facilitate method chaining. - *

+ * Represents a Permission that is constructed at runtime from other permissions.

Methods return + * this, in order to facilitate method chaining.

* * @author Ben Alex * @version $Id$ */ public class CumulativePermission implements Permission { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String pattern = THIRTY_TWO_RESERVED_OFF; private int mask = 0; - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public CumulativePermission clear(Permission permission) { this.mask &= ~permission.getMask(); - this.pattern = AclFormattingUtils.demergePatterns(this.pattern, - permission.getPattern()); + this.pattern = AclFormattingUtils.demergePatterns(this.pattern, permission.getPattern()); return this; } - - public boolean equals(Object arg0) { - if (!(arg0 instanceof CumulativePermission)) { - return false; - } - CumulativePermission rhs = (CumulativePermission) arg0; - return (this.mask == rhs.getMask()); - } - public CumulativePermission clear() { this.mask = 0; @@ -62,6 +48,16 @@ public class CumulativePermission implements Permission { return this; } + public boolean equals(Object arg0) { + if (!(arg0 instanceof CumulativePermission)) { + return false; + } + + CumulativePermission rhs = (CumulativePermission) arg0; + + return (this.mask == rhs.getMask()); + } + public int getMask() { return this.mask; } @@ -72,8 +68,7 @@ public class CumulativePermission implements Permission { public CumulativePermission set(Permission permission) { this.mask |= permission.getMask(); - this.pattern = AclFormattingUtils.mergePatterns(this.pattern, - permission.getPattern()); + this.pattern = AclFormattingUtils.mergePatterns(this.pattern, permission.getPattern()); return this; } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/AclCache.java b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/AclCache.java index 63fb694a5a..672a8c7820 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/AclCache.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/AclCache.java @@ -1,8 +1,24 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.jdbc; import org.acegisecurity.acls.domain.AclImpl; import org.acegisecurity.acls.objectidentity.ObjectIdentity; + /** * A caching layer for {@link JdbcAclService}. * @@ -11,8 +27,13 @@ import org.acegisecurity.acls.objectidentity.ObjectIdentity; * */ public interface AclCache { - public AclImpl getFromCache(ObjectIdentity objectIdentity); - public AclImpl getFromCache(Long pk); - public void putInCache(AclImpl acl); // should walk tree as well! - public void evictFromCache(Long pk); + //~ Methods ======================================================================================================== + + public void evictFromCache(Long pk); + + public AclImpl getFromCache(ObjectIdentity objectIdentity); + + public AclImpl getFromCache(Long pk); + + public void putInCache(AclImpl acl); // should walk tree as well! } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/BasicLookupStrategy.java b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/BasicLookupStrategy.java index 175c2f4be2..9196e57eec 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/BasicLookupStrategy.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/BasicLookupStrategy.java @@ -15,20 +15,8 @@ package org.acegisecurity.acls.jdbc; -import java.lang.reflect.Field; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.sql.DataSource; - import org.acegisecurity.GrantedAuthority; + import org.acegisecurity.acls.AccessControlEntry; import org.acegisecurity.acls.Acl; import org.acegisecurity.acls.NotFoundException; @@ -42,41 +30,53 @@ import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl; import org.acegisecurity.acls.sid.GrantedAuthoritySid; import org.acegisecurity.acls.sid.PrincipalSid; import org.acegisecurity.acls.sid.Sid; + import org.springframework.dao.DataAccessException; + import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementSetter; import org.springframework.jdbc.core.ResultSetExtractor; + import org.springframework.util.Assert; +import java.lang.reflect.Field; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.sql.DataSource; + /** - * Performs lookups in a manner that is compatible with ANSI SQL. - * - *

- * NB: This implementation does attempt to provide reasonably optimised lookups - * - within the constraints of a normalised database and standard ANSI SQL - * features. If you are willing to sacrifice either of these constraints (eg - * use a particular database feature such as hierarchical queries or - * materalized views, or reduce normalisation) you are likely to achieve better - * performance. In such situations you will need to provide your own custom - * LookupStrategy. This class does not support subclassing, as - * it is likely to change in future releases and therefore subclassing is - * unsupported. - *

+ * Performs lookups in a manner that is compatible with ANSI SQL.

NB: This implementation does attempt to provide + * reasonably optimised lookups - within the constraints of a normalised database and standard ANSI SQL features. If + * you are willing to sacrifice either of these constraints (eg use a particular database feature such as hierarchical + * queries or materalized views, or reduce normalisation) you are likely to achieve better performance. In such + * situations you will need to provide your own custom LookupStrategy. This class does not support + * subclassing, as it is likely to change in future releases and therefore subclassing is unsupported.

* * @author Ben Alex * @version $Id$ */ public final class BasicLookupStrategy implements LookupStrategy { - - private int batchSize = 50; + //~ Instance fields ================================================================================================ + private AclCache aclCache; private JdbcTemplate jdbcTemplate; private GrantedAuthority[] auths; + private int batchSize = 50; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - /** +/** * Constructor accepting mandatory arguments * * @param dataSource to access the database @@ -85,306 +85,31 @@ public final class BasicLookupStrategy implements LookupStrategy { * AclImpl#setAuthorities(GrantedAuthority[])} for instances * created by this implementation */ - public BasicLookupStrategy(DataSource dataSource, AclCache aclCache, - GrantedAuthority[] auths) { + public BasicLookupStrategy(DataSource dataSource, AclCache aclCache, GrantedAuthority[] auths) { Assert.notNull(dataSource, "DataSource required"); Assert.notNull(aclCache, "AclCache required"); Assert.notEmpty(auths, "GrantedAuthority[] with three elements required"); - Assert.isTrue(auths.length == 3, - "GrantedAuthority[] with three elements required"); + Assert.isTrue(auths.length == 3, "GrantedAuthority[] with three elements required"); this.jdbcTemplate = new JdbcTemplate(dataSource); this.aclCache = aclCache; this.auths = auths; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void setBatchSize(int batchSize) { - this.batchSize = batchSize; - } + private static String computeRepeatingSql(String repeatingSql, int requiredRepetitions) { + Assert.isTrue(requiredRepetitions >= 1, "Must be => 1"); - /** - * The main method. - * - *

- * WARNING: This implementation completely disregards the "sids" argument! - * Every item in the cache is expected to contain all SIDs. - * - *

- * The implementation works in batch sizes specfied by {@link #batchSize}. - * - */ - public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) - throws NotFoundException { - Assert.isTrue(batchSize >= 1, "BatchSize must be >= 1"); - Assert.notEmpty(objects, "Objects to lookup required"); - - Map result = new HashMap(); // contains FULLY loaded Acl objects - - Set currentBatchToLoad = new HashSet(); // contains ObjectIdentitys - - for (int i = 0; i < objects.length; i++) { - // Check we don't already have this ACL in the results - if (result.containsKey(objects[i])) { - continue; // already in results, so move to next element - } - - // Check cache for the present ACL entry - Acl acl = aclCache.getFromCache(objects[i]); - - // Ensure any cached element supports all the requested SIDs - // (they should always, as our base impl doesn't filter on SID) - if (acl != null) { - if (acl.isSidLoaded(sids)) { - result.put(acl.getObjectIdentity(), acl); - continue; // now in results, so move to next element - } else { - throw new IllegalStateException( - "Error: SID-filtered element detected when implementation does not perform SID filtering - have you added something to the cache manually?"); - } - } - - // To get this far, we have no choice but to retrieve it via JDBC - // (although we don't do it until we get a batch of them to load) - currentBatchToLoad.add(objects[i]); - - // Is it time to load from JDBC the currentBatchToLoad? - if ((currentBatchToLoad.size() == this.batchSize) || (i+1 == objects.length)) { - Map loadedBatch = lookupObjectIdentities((ObjectIdentity[]) currentBatchToLoad - .toArray(new ObjectIdentity[] {})); - - // Add loaded batch (all elements 100% initialized) to results - result.putAll(loadedBatch); - - // Add the loaded batch to the cache - Iterator loadedAclIterator = loadedBatch.values().iterator(); - - while (loadedAclIterator.hasNext()) { - aclCache.putInCache((AclImpl) loadedAclIterator.next()); - } - - currentBatchToLoad.clear(); - } - } - - // TODO: Now we're done, check every requested object identity was found (throw NotFoundException if needed) - - return result; - } - - /** - * Looks up a batch of ObjectIdentitys directly from the - * database. - * - *

- * The caller is responsible for optimization issues, such as selecting the - * identities to lookup, ensuring the cache doesn't contain them already, - * and adding the returned elements to the cache etc. - *

- * - *

- * This subclass is required to return fully valid Acls, - * including properly-configured parent ACLs. - *

- */ - private Map lookupObjectIdentities(final ObjectIdentity[] objectIdentities) { - Assert.notEmpty(objectIdentities, "Must provide identities to lookup"); - - final Map acls = new HashMap(); // contains Acls with StubAclParents - - // Make the "acls" map contain all requested objectIdentities - // (including markers to each parent in the hierarchy) - String sql = computeRepeatingSql("(ACL_OBJECT_IDENTITY.OBJECT_ID_IDENTITY = ? and ACL_CLASS.CLASS = ?)", objectIdentities.length); - System.out.println("Executing lookupObjectIdentities; length: " + objectIdentities.length); - jdbcTemplate.query(sql, - new PreparedStatementSetter() { - public void setValues(PreparedStatement ps) - throws SQLException { - for (int i = 0; i < objectIdentities.length; i++) { - // Determine prepared statement values for this iteration - String javaType = objectIdentities[i].getJavaType().getName(); - Assert.isInstanceOf(Long.class, objectIdentities[i].getIdentifier(),"This class requires ObjectIdentity.getIdentifier() to be a Long"); - long id = ((Long) objectIdentities[i].getIdentifier()).longValue(); - - // Inject values - ps.setLong((2 * i) + 1, id); - ps.setString((2 * i) + 2, javaType); - } - } - }, new ProcessResultSet(acls)); - - // Finally, convert our "acls" containing StubAclParents into true Acls - Map resultMap = new HashMap(); - Iterator iter = acls.values().iterator(); - while (iter.hasNext()) { - Acl inputAcl = (Acl) iter.next(); - Assert.isInstanceOf(AclImpl.class, inputAcl, "Map should have contained an AclImpl"); - Assert.isInstanceOf(Long.class, ((AclImpl)inputAcl).getId(), "Acl.getId() must be Long"); - Acl result = convert(acls, (Long)((AclImpl)inputAcl).getId()); - resultMap.put(result.getObjectIdentity(), result); - } - - return resultMap; - } - - /** - * Locates the primary key IDs specified in "findNow", adding AclImpl - * instances with StubAclParents to the "acls" Map. - * - * @param acls the AclImpls (with StubAclParents) - * @param findNow Long-based primary keys to retrieve - */ - private void lookupPrimaryKeys(final Map acls, final Set findNow) { - Assert.notNull(acls, "ACLs are required"); - Assert.notEmpty(findNow, "Items to find now required"); - - String sql = computeRepeatingSql("(ACL_OBJECT_IDENTITY.ID = ?)",findNow.size()); - System.out.println("Executing lookupPrimaryKeys; length: " + findNow.size()); - - jdbcTemplate.query(sql, - new PreparedStatementSetter() { - public void setValues(PreparedStatement ps) throws SQLException { - Iterator iter = findNow.iterator(); - int i = 0; - while (iter.hasNext()) { - i++; - ps.setLong(i, ((Long)iter.next()).longValue()); - } - } - }, new ProcessResultSet(acls)); - } - - /** - * Accepts the current ResultSet row, and converts it into - * an AclImpl that contains a StubAclParent - * - * @param acls the Map we should add the converted Acl to - * @param rs the ResultSet focused on a current row - * @throws SQLException if something goes wrong converting values - */ - private void convertCurrentResultIntoObject(Map acls, ResultSet rs) throws SQLException { - Long id = new Long(rs.getLong("ACL_ID")); - - // If we already have an ACL for this ID, just create the ACE - AclImpl acl = (AclImpl) acls.get(id); - - if (acl == null) { - // Make an AclImpl and pop it into the Map - ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString( - "CLASS"), new Long(rs.getLong("OBJECT_ID_IDENTITY"))); - - Acl parentAcl = null; - long parentAclId = rs.getLong("PARENT_OBJECT"); - - if (parentAclId != 0) { - parentAcl = new StubAclParent(new Long(parentAclId)); - } - - boolean entriesInheriting = rs.getBoolean("ENTRIES_INHERITING"); - Sid owner; - - if (rs.getBoolean("ACL_PRINCIPAL")) { - owner = new PrincipalSid(rs.getString("ACL_SID")); - } else { - owner = new GrantedAuthoritySid(rs.getString("ACL_SID")); - } - - acl = new AclImpl(objectIdentity, id, parentAcl, auths, null, - entriesInheriting, owner); - acls.put(id, acl); - } - - // Add an extra ACE to the ACL (ORDER BY maintains the ACE list order) - Long aceId = new Long(rs.getLong("ACE_ID")); - Sid recipient; - - if (rs.getBoolean("ACE_PRINCIPAL")) { - recipient = new PrincipalSid(rs.getString("ACE_SID")); - } else { - recipient = new GrantedAuthoritySid(rs.getString("ACE_SID")); - } - - Permission permission = BasePermission.buildFromMask(rs.getInt("MASK")); - boolean granting = rs.getBoolean("GRANTING"); - boolean auditSuccess = rs.getBoolean("AUDIT_SUCCESS"); - boolean auditFailure = rs.getBoolean("AUDIT_FAILURE"); - - AccessControlEntryImpl ace = new AccessControlEntryImpl(aceId, acl, - recipient, permission, granting, auditSuccess, auditFailure); - - - Field acesField = getAccessibleField(AclImpl.class, "aces"); - List aces; - - try { - aces = (List) acesField.get(acl); - } catch (IllegalAccessException ex) { - throw new IllegalStateException( - "Could not obtain AclImpl.ace field", ex); - } - - // Add the ACE if it doesn't already exist in the ACL.aces field - if (!aces.contains(ace)) { - aces.add(ace); - } - } - - /** - * The final phase of converting the Map of AclImpl instances - * which contain StubAclParents into proper, valid AclImpls with - * correct ACL parents. - * - * @param inputMap the unconverted AclImpls - * @param inputAcl the current Acl that we wish to convert (this may be - * @return - */ - private AclImpl convert(Map inputMap, Long currentIdentity) { - Assert.notEmpty(inputMap, "InputMap required"); - Assert.notNull(currentIdentity, "CurrentIdentity required"); - - // Retrieve this Acl from the InputMap - Acl uncastAcl = (Acl) inputMap.get(currentIdentity); - Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl"); - AclImpl inputAcl = (AclImpl) uncastAcl; - - Acl parent = inputAcl.getParentAcl(); - if (parent != null && parent instanceof StubAclParent) { - // Lookup the parent - StubAclParent stubAclParent = (StubAclParent) parent; - parent = convert(inputMap, stubAclParent.getId()); - } - - // Now we have the parent (if there is one), create the true AclImpl - AclImpl result = new AclImpl(inputAcl.getObjectIdentity(), (Long)inputAcl.getId(), parent, auths, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner()); - - // Copy the "aces" from the input to the destination - Field field = getAccessibleField(AclImpl.class, "aces"); - try { - field.set(result, field.get(inputAcl)); - } catch (IllegalAccessException ex) { - throw new IllegalStateException("Could not obtain or set AclImpl.ace field"); - } - - return result; - } - - private static String computeRepeatingSql(String repeatingSql, int requiredRepetitions) { - Assert.isTrue(requiredRepetitions >= 1, "Must be => 1"); - String startSql = "select ACL_OBJECT_IDENTITY.OBJECT_ID_IDENTITY, ACL_ENTRY.ACE_ORDER, " - + "ACL_OBJECT_IDENTITY.ID as ACL_ID, " - + "ACL_OBJECT_IDENTITY.PARENT_OBJECT, " + + "ACL_OBJECT_IDENTITY.ID as ACL_ID, " + "ACL_OBJECT_IDENTITY.PARENT_OBJECT, " + "ACL_OBJECT_IDENTITY,ENTRIES_INHERITING, " + "ACL_ENTRY.ID as ACE_ID, ACL_ENTRY.MASK, ACL_ENTRY.GRANTING, ACL_ENTRY.AUDIT_SUCCESS, ACL_ENTRY.AUDIT_FAILURE, " + "ACE_SID.PRINCIPAL as ACE_PRINCIPAL, ACE_SID.SID as ACE_SID, " - + "ACL_SID.PRINCIPAL as ACL_PRINCIPAL, ACL_SID.SID as ACL_SID, " - + "ACL_CLASS.CLASS " + + "ACL_SID.PRINCIPAL as ACL_PRINCIPAL, ACL_SID.SID as ACL_SID, " + "ACL_CLASS.CLASS " + "from ACL_OBJECT_IDENTITY, ACL_ENTRY, ACL_SID ACE_SID, ACL_SID ACL_SID, ACL_CLASS " - + "where ACL_ENTRY.ACL_OBJECT_IDENTITY = ACL_OBJECT_IDENTITY.ID " - + "and ACE_SID.ID = ACL_ENTRY.SID " + + "where ACL_ENTRY.ACL_OBJECT_IDENTITY = ACL_OBJECT_IDENTITY.ID " + "and ACE_SID.ID = ACL_ENTRY.SID " + "and ACL_SID.ID = ACL_OBJECT_IDENTITY.OWNER_SID " - + "and ACL_CLASS.ID = ACL_OBJECT_IDENTITY.OBJECT_ID_CLASS " - + "and ( "; + + "and ACL_CLASS.ID = ACL_OBJECT_IDENTITY.OBJECT_ID_CLASS " + "and ( "; String endSql = ") order by ACL_ENTRY.ACL_OBJECT_IDENTITY asc, ACL_ENTRY.ACE_ORDER asc"; @@ -404,6 +129,126 @@ public final class BasicLookupStrategy implements LookupStrategy { return sqlStringBuffer.toString(); } + /** + * The final phase of converting the Map of AclImpl instances which contain + * StubAclParents into proper, valid AclImpls with correct ACL parents. + * + * @param inputMap the unconverted AclImpls + * @param currentIdentity the currentAcl that we wish to convert (this may be + * + * @return + * + * @throws IllegalStateException DOCUMENT ME! + */ + private AclImpl convert(Map inputMap, Long currentIdentity) { + Assert.notEmpty(inputMap, "InputMap required"); + Assert.notNull(currentIdentity, "CurrentIdentity required"); + + // Retrieve this Acl from the InputMap + Acl uncastAcl = (Acl) inputMap.get(currentIdentity); + Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl"); + + AclImpl inputAcl = (AclImpl) uncastAcl; + + Acl parent = inputAcl.getParentAcl(); + + if ((parent != null) && parent instanceof StubAclParent) { + // Lookup the parent + StubAclParent stubAclParent = (StubAclParent) parent; + parent = convert(inputMap, stubAclParent.getId()); + } + + // Now we have the parent (if there is one), create the true AclImpl + AclImpl result = new AclImpl(inputAcl.getObjectIdentity(), (Long) inputAcl.getId(), parent, auths, null, + inputAcl.isEntriesInheriting(), inputAcl.getOwner()); + + // Copy the "aces" from the input to the destination + Field field = getAccessibleField(AclImpl.class, "aces"); + + try { + field.set(result, field.get(inputAcl)); + } catch (IllegalAccessException ex) { + throw new IllegalStateException("Could not obtain or set AclImpl.ace field"); + } + + return result; + } + + /** + * Accepts the current ResultSet row, and converts it into an AclImpl that + * contains a StubAclParent + * + * @param acls the Map we should add the converted Acl to + * @param rs the ResultSet focused on a current row + * + * @throws SQLException if something goes wrong converting values + * @throws IllegalStateException DOCUMENT ME! + */ + private void convertCurrentResultIntoObject(Map acls, ResultSet rs) + throws SQLException { + Long id = new Long(rs.getLong("ACL_ID")); + + // If we already have an ACL for this ID, just create the ACE + AclImpl acl = (AclImpl) acls.get(id); + + if (acl == null) { + // Make an AclImpl and pop it into the Map + ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString("CLASS"), + new Long(rs.getLong("OBJECT_ID_IDENTITY"))); + + Acl parentAcl = null; + long parentAclId = rs.getLong("PARENT_OBJECT"); + + if (parentAclId != 0) { + parentAcl = new StubAclParent(new Long(parentAclId)); + } + + boolean entriesInheriting = rs.getBoolean("ENTRIES_INHERITING"); + Sid owner; + + if (rs.getBoolean("ACL_PRINCIPAL")) { + owner = new PrincipalSid(rs.getString("ACL_SID")); + } else { + owner = new GrantedAuthoritySid(rs.getString("ACL_SID")); + } + + acl = new AclImpl(objectIdentity, id, parentAcl, auths, null, entriesInheriting, owner); + acls.put(id, acl); + } + + // Add an extra ACE to the ACL (ORDER BY maintains the ACE list order) + Long aceId = new Long(rs.getLong("ACE_ID")); + Sid recipient; + + if (rs.getBoolean("ACE_PRINCIPAL")) { + recipient = new PrincipalSid(rs.getString("ACE_SID")); + } else { + recipient = new GrantedAuthoritySid(rs.getString("ACE_SID")); + } + + Permission permission = BasePermission.buildFromMask(rs.getInt("MASK")); + boolean granting = rs.getBoolean("GRANTING"); + boolean auditSuccess = rs.getBoolean("AUDIT_SUCCESS"); + boolean auditFailure = rs.getBoolean("AUDIT_FAILURE"); + + AccessControlEntryImpl ace = new AccessControlEntryImpl(aceId, acl, recipient, permission, granting, + auditSuccess, auditFailure); + + Field acesField = getAccessibleField(AclImpl.class, "aces"); + List aces; + + try { + aces = (List) acesField.get(acl); + } catch (IllegalAccessException ex) { + throw new IllegalStateException("Could not obtain AclImpl.ace field", ex); + } + + // Add the ACE if it doesn't already exist in the ACL.aces field + if (!aces.contains(ace)) { + aces.add(ace); + } + } + private static Field getAccessibleField(Class clazz, String protectedField) { Field field = null; @@ -416,8 +261,7 @@ public final class BasicLookupStrategy implements LookupStrategy { if (clazz.getSuperclass() != null) { getAccessibleField(clazz.getSuperclass(), protectedField); } else { - throw new IllegalArgumentException("Couldn't find '" - + protectedField + "' field"); + throw new IllegalArgumentException("Couldn't find '" + protectedField + "' field"); } } @@ -426,8 +270,216 @@ public final class BasicLookupStrategy implements LookupStrategy { return field; } - - //~ Inner Classes ========================================================== + + /** + * Looks up a batch of ObjectIdentitys directly from the database.

The caller is responsible + * for optimization issues, such as selecting the identities to lookup, ensuring the cache doesn't contain them + * already, and adding the returned elements to the cache etc.

+ *

This subclass is required to return fully valid Acls, including properly-configured + * parent ACLs.

+ * + * @param objectIdentities DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private Map lookupObjectIdentities(final ObjectIdentity[] objectIdentities) { + Assert.notEmpty(objectIdentities, "Must provide identities to lookup"); + + final Map acls = new HashMap(); // contains Acls with StubAclParents + + // Make the "acls" map contain all requested objectIdentities + // (including markers to each parent in the hierarchy) + String sql = computeRepeatingSql("(ACL_OBJECT_IDENTITY.OBJECT_ID_IDENTITY = ? and ACL_CLASS.CLASS = ?)", + objectIdentities.length); + System.out.println("Executing lookupObjectIdentities; length: " + objectIdentities.length); + jdbcTemplate.query(sql, + new PreparedStatementSetter() { + public void setValues(PreparedStatement ps) + throws SQLException { + for (int i = 0; i < objectIdentities.length; i++) { + // Determine prepared statement values for this iteration + String javaType = objectIdentities[i].getJavaType().getName(); + Assert.isInstanceOf(Long.class, objectIdentities[i].getIdentifier(), + "This class requires ObjectIdentity.getIdentifier() to be a Long"); + + long id = ((Long) objectIdentities[i].getIdentifier()).longValue(); + + // Inject values + ps.setLong((2 * i) + 1, id); + ps.setString((2 * i) + 2, javaType); + } + } + }, new ProcessResultSet(acls)); + + // Finally, convert our "acls" containing StubAclParents into true Acls + Map resultMap = new HashMap(); + Iterator iter = acls.values().iterator(); + + while (iter.hasNext()) { + Acl inputAcl = (Acl) iter.next(); + Assert.isInstanceOf(AclImpl.class, inputAcl, "Map should have contained an AclImpl"); + Assert.isInstanceOf(Long.class, ((AclImpl) inputAcl).getId(), "Acl.getId() must be Long"); + + Acl result = convert(acls, (Long) ((AclImpl) inputAcl).getId()); + resultMap.put(result.getObjectIdentity(), result); + } + + return resultMap; + } + + /** + * Locates the primary key IDs specified in "findNow", adding AclImpl instances with StubAclParents to the + * "acls" Map. + * + * @param acls the AclImpls (with StubAclParents) + * @param findNow Long-based primary keys to retrieve + */ + private void lookupPrimaryKeys(final Map acls, final Set findNow) { + Assert.notNull(acls, "ACLs are required"); + Assert.notEmpty(findNow, "Items to find now required"); + + String sql = computeRepeatingSql("(ACL_OBJECT_IDENTITY.ID = ?)", findNow.size()); + System.out.println("Executing lookupPrimaryKeys; length: " + findNow.size()); + + jdbcTemplate.query(sql, + new PreparedStatementSetter() { + public void setValues(PreparedStatement ps) + throws SQLException { + Iterator iter = findNow.iterator(); + int i = 0; + + while (iter.hasNext()) { + i++; + ps.setLong(i, ((Long) iter.next()).longValue()); + } + } + }, new ProcessResultSet(acls)); + } + + /** + * The main method.

WARNING: This implementation completely disregards the "sids" argument! Every item in + * the cache is expected to contain all SIDs.

+ *

The implementation works in batch sizes specfied by {@link #batchSize}.

+ * + * @param objects DOCUMENT ME! + * @param sids DOCUMENT ME! + * + * @return DOCUMENT ME! + * + * @throws NotFoundException DOCUMENT ME! + * @throws IllegalStateException DOCUMENT ME! + */ + public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) + throws NotFoundException { + Assert.isTrue(batchSize >= 1, "BatchSize must be >= 1"); + Assert.notEmpty(objects, "Objects to lookup required"); + + Map result = new HashMap(); // contains FULLY loaded Acl objects + + Set currentBatchToLoad = new HashSet(); // contains ObjectIdentitys + + for (int i = 0; i < objects.length; i++) { + // Check we don't already have this ACL in the results + if (result.containsKey(objects[i])) { + continue; // already in results, so move to next element + } + + // Check cache for the present ACL entry + Acl acl = aclCache.getFromCache(objects[i]); + + // Ensure any cached element supports all the requested SIDs + // (they should always, as our base impl doesn't filter on SID) + if (acl != null) { + if (acl.isSidLoaded(sids)) { + result.put(acl.getObjectIdentity(), acl); + + continue; // now in results, so move to next element + } else { + throw new IllegalStateException( + "Error: SID-filtered element detected when implementation does not perform SID filtering - have you added something to the cache manually?"); + } + } + + // To get this far, we have no choice but to retrieve it via JDBC + // (although we don't do it until we get a batch of them to load) + currentBatchToLoad.add(objects[i]); + + // Is it time to load from JDBC the currentBatchToLoad? + if ((currentBatchToLoad.size() == this.batchSize) || ((i + 1) == objects.length)) { + Map loadedBatch = lookupObjectIdentities((ObjectIdentity[]) currentBatchToLoad.toArray( + new ObjectIdentity[] {})); + + // Add loaded batch (all elements 100% initialized) to results + result.putAll(loadedBatch); + + // Add the loaded batch to the cache + Iterator loadedAclIterator = loadedBatch.values().iterator(); + + while (loadedAclIterator.hasNext()) { + aclCache.putInCache((AclImpl) loadedAclIterator.next()); + } + + currentBatchToLoad.clear(); + } + } + + // TODO: Now we're done, check every requested object identity was found (throw NotFoundException if needed) + return result; + } + + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + + //~ Inner Classes ================================================================================================== + + private class ProcessResultSet implements ResultSetExtractor { + private Map acls; + + public ProcessResultSet(Map acls) { + Assert.notNull(acls, "ACLs cannot be null"); + this.acls = acls; + } + + public Object extractData(ResultSet rs) throws SQLException, DataAccessException { + Set parentIdsToLookup = new HashSet(); // Set of parent_id Longs + + while (rs.next()) { + // Convert current row into an Acl (albeit with a StubAclParent) + convertCurrentResultIntoObject(acls, rs); + + // Figure out if this row means we need to lookup another parent + long parentId = rs.getLong("PARENT_OBJECT"); + + if (parentId != 0) { + // See if its already in the "acls" + if (acls.containsKey(new Long(parentId))) { + continue; // skip this while element + } + + // Now try to find it in the cache + Acl cached = aclCache.getFromCache(new Long(parentId)); + + if (cached == null) { + parentIdsToLookup.add(new Long(parentId)); + } else { + // Pop into the acls map, so our convert method doesn't + // need to deal with an unsynchronized AclCache + Assert.isInstanceOf(AclImpl.class, cached, "Cached ACL must be an AclImpl"); + acls.put(((AclImpl) cached).getId(), cached); + } + } + } + + // Lookup parents, adding Acls (with StubAclParents) to "acl" map + if (parentIdsToLookup.size() > 0) { + lookupPrimaryKeys(acls, parentIdsToLookup); + } + + // Return null to meet ResultSetExtractor method contract + return null; + } + } private class StubAclParent implements Acl { private Long id; @@ -456,8 +508,7 @@ public final class BasicLookupStrategy implements LookupStrategy { throw new UnsupportedOperationException("Stub only"); } - public boolean isGranted(Permission[] permission, Sid[] sids, - boolean administrativeMode) + public boolean isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode) throws NotFoundException, UnloadedSidException { throw new UnsupportedOperationException("Stub only"); } @@ -466,52 +517,4 @@ public final class BasicLookupStrategy implements LookupStrategy { throw new UnsupportedOperationException("Stub only"); } } - - private class ProcessResultSet implements ResultSetExtractor { - private Map acls; - - public ProcessResultSet(Map acls) { - Assert.notNull(acls, "ACLs cannot be null"); - this.acls = acls; - } - - public Object extractData(ResultSet rs) throws SQLException, DataAccessException { - Set parentIdsToLookup = new HashSet(); // Set of parent_id Longs - - while (rs.next()) { - // Convert current row into an Acl (albeit with a StubAclParent) - convertCurrentResultIntoObject(acls, rs); - - // Figure out if this row means we need to lookup another parent - long parentId = rs.getLong("PARENT_OBJECT"); - - if (parentId != 0) { - // See if its already in the "acls" - if (acls.containsKey(new Long(parentId))) { - continue; // skip this while element - } - - // Now try to find it in the cache - Acl cached = aclCache.getFromCache(new Long(parentId)); - - if (cached == null) { - parentIdsToLookup.add(new Long(parentId)); - } else { - // Pop into the acls map, so our convert method doesn't - // need to deal with an unsynchronized AclCache - Assert.isInstanceOf(AclImpl.class, cached, "Cached ACL must be an AclImpl"); - acls.put(((AclImpl)cached).getId(), cached); - } - } - } - - // Lookup parents, adding Acls (with StubAclParents) to "acl" map - if (parentIdsToLookup.size() > 0) { - lookupPrimaryKeys(acls, parentIdsToLookup); - } - - // Return null to meet ResultSetExtractor method contract - return null; - } - } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/EhCacheBasedAclCache.java b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/EhCacheBasedAclCache.java index f50913b6e3..656668a6ec 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/EhCacheBasedAclCache.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/EhCacheBasedAclCache.java @@ -1,3 +1,18 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.jdbc; import net.sf.ehcache.Cache; @@ -6,53 +21,73 @@ import net.sf.ehcache.Element; import org.acegisecurity.acls.domain.AclImpl; import org.acegisecurity.acls.objectidentity.ObjectIdentity; + import org.springframework.util.Assert; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class EhCacheBasedAclCache implements AclCache { + //~ Instance fields ================================================================================================ - private Cache cache; - - public EhCacheBasedAclCache(Cache cache) { - Assert.notNull(cache, "Cache required"); - this.cache = cache; - } - - public AclImpl getFromCache(ObjectIdentity objectIdentity) { - Element element = null; - try { - element = cache.get(objectIdentity); - } catch (CacheException ignored) {} - if (element == null) { - return null; - } - return (AclImpl) element.getValue(); - } + private Cache cache; - public AclImpl getFromCache(Long pk) { - Element element = null; - try { - element = cache.get(pk); - } catch (CacheException ignored) {} - if (element == null) { - return null; - } - return (AclImpl) element.getValue(); - } + //~ Constructors =================================================================================================== - public void putInCache(AclImpl acl) { - if (acl.getParentAcl() != null && acl.getParentAcl() instanceof AclImpl) { - putInCache((AclImpl)acl.getParentAcl()); - } - cache.put(new Element(acl.getObjectIdentity(), acl)); - cache.put(new Element(acl.getId(), acl)); - } + public EhCacheBasedAclCache(Cache cache) { + Assert.notNull(cache, "Cache required"); + this.cache = cache; + } - public void evictFromCache(Long pk) { - AclImpl acl = getFromCache(pk); - if (acl != null) { - cache.remove(pk); - cache.remove(acl.getObjectIdentity()); - } - } + //~ Methods ======================================================================================================== + public void evictFromCache(Long pk) { + AclImpl acl = getFromCache(pk); + + if (acl != null) { + cache.remove(pk); + cache.remove(acl.getObjectIdentity()); + } + } + + public AclImpl getFromCache(ObjectIdentity objectIdentity) { + Element element = null; + + try { + element = cache.get(objectIdentity); + } catch (CacheException ignored) {} + + if (element == null) { + return null; + } + + return (AclImpl) element.getValue(); + } + + public AclImpl getFromCache(Long pk) { + Element element = null; + + try { + element = cache.get(pk); + } catch (CacheException ignored) {} + + if (element == null) { + return null; + } + + return (AclImpl) element.getValue(); + } + + public void putInCache(AclImpl acl) { + if ((acl.getParentAcl() != null) && acl.getParentAcl() instanceof AclImpl) { + putInCache((AclImpl) acl.getParentAcl()); + } + + cache.put(new Element(acl.getObjectIdentity(), acl)); + cache.put(new Element(acl.getId(), acl)); + } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/JdbcAclService.java b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/JdbcAclService.java index e0b61ff2b5..c27d26dcba 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/JdbcAclService.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/JdbcAclService.java @@ -1,51 +1,78 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.jdbc; -import java.util.Map; - -import javax.sql.DataSource; - import org.acegisecurity.acls.AclService; import org.acegisecurity.acls.NotFoundException; import org.acegisecurity.acls.objectidentity.ObjectIdentity; import org.acegisecurity.acls.sid.Sid; + import org.springframework.jdbc.core.JdbcTemplate; + import org.springframework.util.Assert; +import java.util.Map; + +import javax.sql.DataSource; + + /** - * Simple JDBC-based implementation of AclService. - * - *

- * Requires the "dirty" flags in {@link org.acegisecurity.acls.domain.AclImpl} and {@link org.acegisecurity.acls.domain.AccessControlEntryImpl} - * to be set, so that the implementation can detect changed parameters easily. - * + * Simple JDBC-based implementation of AclService.

Requires the "dirty" flags in {@link + * org.acegisecurity.acls.domain.AclImpl} and {@link org.acegisecurity.acls.domain.AccessControlEntryImpl} to be set, + * so that the implementation can detect changed parameters easily.

+ * * @author Ben Alex * @version $Id$ */ -public class JdbcAclService implements AclService/*, MutableAclService */ { +public class JdbcAclService implements AclService /*, MutableAclService */ { + //~ Instance fields ================================================================================================ - private AclCache aclCache; - private JdbcTemplate template; - private LookupStrategy lookupStrategy; + private AclCache aclCache; + private JdbcTemplate template; + private LookupStrategy lookupStrategy; - public JdbcAclService(DataSource dataSource, AclCache aclCache, LookupStrategy lookupStrategy) { + //~ Constructors =================================================================================================== + + public JdbcAclService(DataSource dataSource, AclCache aclCache, LookupStrategy lookupStrategy) { Assert.notNull(dataSource, "DataSource required"); Assert.notNull(aclCache, "AclCache required"); - Assert.notNull(lookupStrategy, "LookupStrategy required"); - this.template = new JdbcTemplate(dataSource); - this.aclCache = aclCache; - this.lookupStrategy = lookupStrategy; - } - - public Map readAclsById(ObjectIdentity[] objects) { - return readAclsById(objects, null); - } + Assert.notNull(lookupStrategy, "LookupStrategy required"); + this.template = new JdbcTemplate(dataSource); + this.aclCache = aclCache; + this.lookupStrategy = lookupStrategy; + } - /** - * Method required by interface. - */ - public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) throws NotFoundException { - return lookupStrategy.readAclsById(objects, sids); - } - + //~ Methods ======================================================================================================== + public Map readAclsById(ObjectIdentity[] objects) { + return readAclsById(objects, null); + } + + /** + * Method required by interface. + * + * @param objects DOCUMENT ME! + * @param sids DOCUMENT ME! + * + * @return DOCUMENT ME! + * + * @throws NotFoundException DOCUMENT ME! + */ + public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) + throws NotFoundException { + return lookupStrategy.readAclsById(objects, sids); + } } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/LookupStrategy.java b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/LookupStrategy.java index eb5bec6e90..2ace12b6fc 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/jdbc/LookupStrategy.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/jdbc/LookupStrategy.java @@ -28,20 +28,17 @@ import java.util.Map; * @version $Id$ */ public interface LookupStrategy { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Perform database-specific optimized lookup. * * @param objects the identities to lookup (required) - * @param sids the SIDs for which identities are required (may be - * null - implementations may elect not to provide SID - * optimisations) + * @param sids the SIDs for which identities are required (may be null - implementations may elect not + * to provide SID optimisations) * - * @return the Map pursuant to the interface contract for - * {@link - * org.acegisecurity.acls.AclService#readAclsById(ObjectIdentity[], - * Sid[])} + * @return the Map pursuant to the interface contract for {@link + * org.acegisecurity.acls.AclService#readAclsById(ObjectIdentity[], Sid[])} */ public Map readAclsById(ObjectIdentity[] objects, Sid[] sids); } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentity.java b/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentity.java index 7721ebd40f..b92cd44565 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentity.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentity.java @@ -17,6 +17,7 @@ package org.acegisecurity.acls.objectidentity; import java.io.Serializable; + /** * Interface representing the identity of an individual domain object instance. * @@ -33,29 +34,22 @@ import java.io.Serializable; * @version $Id$ */ public interface ObjectIdentity extends Serializable { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @param obj to be compared * - * @return true if the objects are equal, false - * otherwise + * @return true if the objects are equal, false otherwise */ public boolean equals(Object obj); /** - * Obtains the actual identifier. This identifier must not be reused to - * represent other domain objects with the same javaType. - * - *

- * Because ACLs are largely immutable, it is strongly recommended to use a - * synthetic identifier (such as a database sequence number for the - * primary key). Do not use an identifier with business meaning, as that - * business meaning may change. - *

+ * Obtains the actual identifier. This identifier must not be reused to represent other domain objects with + * the same javaType.

Because ACLs are largely immutable, it is strongly recommended to use + * a synthetic identifier (such as a database sequence number for the primary key). Do not use an identifier with + * business meaning, as that business meaning may change.

* * @return the identifier (unique within this javaType */ @@ -69,8 +63,7 @@ public interface ObjectIdentity extends Serializable { public Class getJavaType(); /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @return a hash code representation of this object */ diff --git a/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentityImpl.java b/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentityImpl.java index 29425d5ad6..816cbbf473 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentityImpl.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/objectidentity/ObjectIdentityImpl.java @@ -28,33 +28,30 @@ import java.lang.reflect.Method; /** - * Simple implementation of {@link AclObjectIdentity}. - * - *

- * Uses Strings to store the identity of the domain object - * instance. Also offers a constructor that uses reflection to build the - * identity information. - *

+ * Simple implementation of {@link AclObjectIdentity}.

Uses Strings to store the identity of the + * domain object instance. Also offers a constructor that uses reflection to build the identity information.

*/ public class ObjectIdentityImpl implements ObjectIdentity { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private Class javaType; private Serializable identifier; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ObjectIdentityImpl(String javaType, Serializable identifier) { Assert.hasText(javaType, "Java Type required"); Assert.notNull(identifier, "identifier required"); - try { - this.javaType = Class.forName(javaType); - } catch (Exception ex) { - ReflectionUtils.handleReflectionException(ex); - } - this.identifier = identifier; + + try { + this.javaType = Class.forName(javaType); + } catch (Exception ex) { + ReflectionUtils.handleReflectionException(ex); + } + + this.identifier = identifier; } - + public ObjectIdentityImpl(Class javaType, Serializable identifier) { Assert.notNull(javaType, "Java Type required"); Assert.notNull(identifier, "identifier required"); @@ -62,7 +59,7 @@ public class ObjectIdentityImpl implements ObjectIdentity { this.identifier = identifier; } - /** +/** * Creates the NamedEntityObjectIdentity based on the passed * object instance. The passed object must provide a getId() * method, otherwise an exception will be thrown. @@ -71,8 +68,7 @@ public class ObjectIdentityImpl implements ObjectIdentity { * * @throws IdentityUnavailableException if identity could not be extracted */ - public ObjectIdentityImpl(Object object) - throws IdentityUnavailableException { + public ObjectIdentityImpl(Object object) throws IdentityUnavailableException { Assert.notNull(object, "object cannot be null"); this.javaType = object.getClass(); @@ -83,24 +79,18 @@ public class ObjectIdentityImpl implements ObjectIdentity { Method method = this.javaType.getMethod("getId", new Class[] {}); result = method.invoke(object, new Object[] {}); } catch (Exception e) { - throw new IdentityUnavailableException( - "Could not extract identity from object " + object, e); + throw new IdentityUnavailableException("Could not extract identity from object " + object, e); } - Assert.isInstanceOf(Serializable.class, result, - "Getter must provide a return value of type Serializable"); + Assert.isInstanceOf(Serializable.class, result, "Getter must provide a return value of type Serializable"); this.identifier = (Serializable) result; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Important so caching operates properly. - * - *

- * Considers an object of the same class equal if it has the same - * classname and id properties. - *

+ * Important so caching operates properly.

Considers an object of the same class equal if it has the same + * classname and id properties.

* * @param arg0 object to compare * @@ -117,8 +107,7 @@ public class ObjectIdentityImpl implements ObjectIdentity { ObjectIdentityImpl other = (ObjectIdentityImpl) arg0; - if (this.getIdentifier().equals(other.getIdentifier()) - && this.getJavaType().equals(other.getJavaType())) { + if (this.getIdentifier().equals(other.getIdentifier()) && this.getJavaType().equals(other.getJavaType())) { return true; } diff --git a/sandbox/src/main/java/org/acegisecurity/acls/sid/GrantedAuthoritySid.java b/sandbox/src/main/java/org/acegisecurity/acls/sid/GrantedAuthoritySid.java index 5794ebc953..b298f93f2a 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/sid/GrantedAuthoritySid.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/sid/GrantedAuthoritySid.java @@ -21,30 +21,25 @@ import org.springframework.util.Assert; /** - * Represents a GrantedAuthority as a Sid. - * - *

- * This is a basic implementation that simply uses the - * String-based principal for Sid comparison. More - * complex principal objects may wish to provide an alternative - * Sid implementation that uses some other identifier. - *

+ * Represents a GrantedAuthority as a Sid.

This is a basic implementation that simply + * uses the String-based principal for Sid comparison. More complex principal objects may + * wish to provide an alternative Sid implementation that uses some other identifier.

* * @author Ben Alex * @version $Id$ */ public class GrantedAuthoritySid implements Sid { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String grantedAuthority; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public GrantedAuthoritySid(String grantedAuthority) { - Assert.hasText(grantedAuthority, "GrantedAuthority required"); - this.grantedAuthority = grantedAuthority; + Assert.hasText(grantedAuthority, "GrantedAuthority required"); + this.grantedAuthority = grantedAuthority; } - + public GrantedAuthoritySid(GrantedAuthority grantedAuthority) { Assert.notNull(grantedAuthority, "GrantedAuthority required"); Assert.notNull(grantedAuthority.getAuthority(), @@ -52,7 +47,7 @@ public class GrantedAuthoritySid implements Sid { this.grantedAuthority = grantedAuthority.getAuthority(); } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object object) { if ((object == null) || !(object instanceof GrantedAuthoritySid)) { @@ -60,8 +55,7 @@ public class GrantedAuthoritySid implements Sid { } // Delegate to getGrantedAuthority() to perform actual comparison (both should be identical) - return ((GrantedAuthoritySid) object).getGrantedAuthority() - .equals(this.getGrantedAuthority()); + return ((GrantedAuthoritySid) object).getGrantedAuthority().equals(this.getGrantedAuthority()); } public String getGrantedAuthority() { diff --git a/sandbox/src/main/java/org/acegisecurity/acls/sid/PrincipalSid.java b/sandbox/src/main/java/org/acegisecurity/acls/sid/PrincipalSid.java index 78d5edffbf..c76d68fe7c 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/sid/PrincipalSid.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/sid/PrincipalSid.java @@ -23,43 +23,36 @@ import org.springframework.util.Assert; /** - * Represents an Authentication.getPrincipal() as a - * Sid. - * - *

- * This is a basic implementation that simply uses the - * String-based principal for Sid comparison. More - * complex principal objects may wish to provide an alternative - * Sid implementation that uses some other identifier. - *

+ * Represents an Authentication.getPrincipal() as a Sid.

This is a basic implementation + * that simply uses the String-based principal for Sid comparison. More complex principal + * objects may wish to provide an alternative Sid implementation that uses some other identifier.

* * @author Ben Alex * @version $Id$ */ public class PrincipalSid implements Sid { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private String principal; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public PrincipalSid(String principal) { - Assert.hasText(principal, "Principal required"); - this.principal = principal; + Assert.hasText(principal, "Principal required"); + this.principal = principal; } - + public PrincipalSid(Authentication authentication) { Assert.notNull(authentication, "Authentication required"); Assert.notNull(authentication.getPrincipal(), "Principal required"); this.principal = authentication.getPrincipal().toString(); if (authentication.getPrincipal() instanceof UserDetails) { - this.principal = ((UserDetails) authentication.getPrincipal()) - .getUsername(); + this.principal = ((UserDetails) authentication.getPrincipal()).getUsername(); } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public boolean equals(Object object) { if ((object == null) || !(object instanceof PrincipalSid)) { @@ -67,8 +60,7 @@ public class PrincipalSid implements Sid { } // Delegate to getPrincipal() to perform actual comparison (both should be identical) - return ((PrincipalSid) object).getPrincipal() - .equals(this.getPrincipal()); + return ((PrincipalSid) object).getPrincipal().equals(this.getPrincipal()); } public String getPrincipal() { diff --git a/sandbox/src/main/java/org/acegisecurity/acls/sid/Sid.java b/sandbox/src/main/java/org/acegisecurity/acls/sid/Sid.java index 018d8e03d7..a72289046d 100644 --- a/sandbox/src/main/java/org/acegisecurity/acls/sid/Sid.java +++ b/sandbox/src/main/java/org/acegisecurity/acls/sid/Sid.java @@ -31,22 +31,19 @@ package org.acegisecurity.acls.sid; * @version $Id$ */ public interface Sid { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @param obj to be compared * - * @return true if the objects are equal, false - * otherwise + * @return true if the objects are equal, false otherwise */ public boolean equals(Object obj); /** - * Refer to the java.lang.Object documentation for the - * interface contract. + * Refer to the java.lang.Object documentation for the interface contract. * * @return a hash code representation of this object */ diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java index 4eee63ed43..611cceaa71 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControl.java @@ -17,43 +17,39 @@ package org.acegisecurity.providers.ldap.authenticator.controls; import javax.naming.ldap.Control; + /** - * A Password Policy request control. - *

- * Based on the information in the corresponding internet draft on - * LDAP password policy. - *

- * - * @see PasswordPolicyResponseControl - * @see Password Policy for LDAP Directories + * A Password Policy request control.

Based on the information in the corresponding internet draft on LDAP + * password policy.

* * @author Stefan Zoerner * @author Luke Taylor - * * @version $Id$ * + * @see PasswordPolicyResponseControl + * @see Password Policy for LDAP + * Directories */ public class PasswordPolicyControl implements Control { - - //~ Static fields/initializers ============================================ + //~ Static fields/initializers ===================================================================================== /** OID of the Password Policy Control */ public static final String OID = "1.3.6.1.4.1.42.2.27.8.5.1"; - //~ Instance fields ======================================================= + //~ Instance fields ================================================================================================ private boolean critical; - //~ Constructors ========================================================== + //~ Constructors =================================================================================================== - /** +/** * Creates a non-critical (request) control. */ public PasswordPolicyControl() { this(Control.NONCRITICAL); } - /** +/** * Creates a (request) control. * * @param critical indicates whether the control is @@ -63,10 +59,22 @@ public class PasswordPolicyControl implements Control { this.critical = critical; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== + + /** + * Retrieves the ASN.1 BER encoded value of the LDAP control. The request value for this control is always + * empty. + * + * @return always null + */ + public byte[] getEncodedValue() { + return null; + } /** * Returns the OID of the Password Policy Control. + * + * @return DOCUMENT ME! */ public String getID() { return OID; @@ -74,18 +82,10 @@ public class PasswordPolicyControl implements Control { /** * Returns whether the control is critical for the client. + * + * @return DOCUMENT ME! */ public boolean isCritical() { return critical; } - - /** - * Retrieves the ASN.1 BER encoded value of the LDAP control. The request - * value for this control is always empty. - * - * @return always null - */ - public byte[] getEncodedValue() { - return null; - } -} \ No newline at end of file +} diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java index 08109bcecc..c22cab48ed 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyControlFactory.java @@ -20,25 +20,22 @@ import javax.naming.ldap.ControlFactory; /** - * Transforms a control object to a PasswordPolicyResponseControl object, if - * appropriate. + * Transforms a control object to a PasswordPolicyResponseControl object, if appropriate. * * @author Stefan Zoerner * @author Luke Taylor * @version $Id$ */ public class PasswordPolicyControlFactory extends ControlFactory { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Creates an instance of PasswordPolicyResponseControl if the passed - * control is a response control of this type. Attributes of the result - * are filled with the correct values (e.g. error code). + * Creates an instance of PasswordPolicyResponseControl if the passed control is a response control of this + * type. Attributes of the result are filled with the correct values (e.g. error code). * * @param ctl the control the check * - * @return a response control of type PasswordPolicyResponseControl, or - * null + * @return a response control of type PasswordPolicyResponseControl, or null */ public Control getControlInstance(Control ctl) { if (ctl.getID().equals(PasswordPolicyControl.OID)) { @@ -47,5 +44,4 @@ public class PasswordPolicyControlFactory extends ControlFactory { return null; } -} - +} diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java index 0216360e20..7eeffcd166 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControl.java @@ -15,74 +15,66 @@ package org.acegisecurity.providers.ldap.authenticator.controls; - -import java.io.IOException; -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import org.acegisecurity.ldap.LdapDataAccessException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import netscape.ldap.ber.stream.BERChoice; +import netscape.ldap.ber.stream.BERElement; +import netscape.ldap.ber.stream.BEREnumerated; +import netscape.ldap.ber.stream.BERInteger; //import com.novell.ldap.asn1.LBERDecoder; //import com.novell.ldap.asn1.ASN1Sequence; //import com.novell.ldap.asn1.ASN1Tagged; //import com.novell.ldap.asn1.ASN1OctetString; import netscape.ldap.ber.stream.BERSequence; -import netscape.ldap.ber.stream.BERElement; -import netscape.ldap.ber.stream.BERTagDecoder; import netscape.ldap.ber.stream.BERTag; -import netscape.ldap.ber.stream.BERChoice; -import netscape.ldap.ber.stream.BERInteger; -import netscape.ldap.ber.stream.BEREnumerated; +import netscape.ldap.ber.stream.BERTagDecoder; + +import org.acegisecurity.ldap.LdapDataAccessException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + /** - * Represent the response control received when a PasswordPolicyControl - * is used when binding to a directory. - * - * Currently tested with the OpenLDAP 2.3.19 implementation of the LDAP Password - * Policy Draft. - * - * It extends the request control with the control specific data. This is - * accomplished by the properties timeBeforeExpiration, graceLoginsRemaining and - * errorCodes. getEncodedValue returns the - * unchanged value of the response control as a byte array. - * - * @see PasswordPolicyControl - * @see Stefan Zoerner's IBM developerworks article on LDAP controls. + * Represent the response control received when a PasswordPolicyControl is used when binding to a + * directory. Currently tested with the OpenLDAP 2.3.19 implementation of the LDAP Password Policy Draft. It extends + * the request control with the control specific data. This is accomplished by the properties timeBeforeExpiration, + * graceLoginsRemaining and errorCodes. getEncodedValue returns the unchanged value of the response control as a byte + * array. * * @author Stefan Zoerner * @author Luke Taylor * @version $Id$ + * + * @see PasswordPolicyControl + * @see Stefan Zoerner's IBM developerworks + * article on LDAP controls. */ public class PasswordPolicyResponseControl extends PasswordPolicyControl { - - //~ Static fields/initializers ============================================ + //~ Static fields/initializers ===================================================================================== private static final Log logger = LogFactory.getLog(PasswordPolicyResponseControl.class); - public static final int ERROR_NONE = -1; public static final int ERROR_PASSWORD_EXPIRED = 0; public static final int ERROR_ACCOUNT_LOCKED = 1; public static final int WARNINGS_DEFAULT = -1; + private static final String[] errorText = { + "password expired", "account locked", "change after reset", "password mod not allowed", + "must supply old password", "invalid password syntax", "password too short", "password too young", + "password in history" + }; - - //~ Instance fields ======================================================= + //~ Instance fields ================================================================================================ private byte[] encodedValue; - private int errorCode = ERROR_NONE; - + private int graceLoginsRemaining = WARNINGS_DEFAULT; private int timeBeforeExpiration = WARNINGS_DEFAULT; - private int graceLoginsRemaining = WARNINGS_DEFAULT; - - private static final String[] errorText = { "password expired", "account locked", - "change after reset", "password mod not allowed", "must supply old password", - "invalid password syntax", "password too short", "password too young", - "password in history" }; - - //~ Constructors ========================================================== + //~ Constructors =================================================================================================== public PasswordPolicyResponseControl(byte[] encodedValue) { this.encodedValue = encodedValue; @@ -97,36 +89,43 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { } } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** - * Decodes the Ber encoded control data. - * - * The ASN.1 value of the control data is: - * - *
-     *    PasswordPolicyResponseValue ::= SEQUENCE {
-     *        warning [0] CHOICE {
-     *           timeBeforeExpiration [0] INTEGER (0 .. maxInt),
-     *           graceAuthNsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL,
-     *        error   [1] ENUMERATED {
-     *           passwordExpired             (0),
-     *           accountLocked               (1),
-     *           changeAfterReset            (2),
-     *           passwordModNotAllowed       (3),
-     *           mustSupplyOldPassword       (4),
-     *           insufficientPasswordQuality (5),
-     *           passwordTooShort            (6),
-     *           passwordTooYoung            (7),
-     *           passwordInHistory           (8) } OPTIONAL }
-     * 
+ * Returns the unchanged value of the response control. Returns the unchanged value of the response + * control as byte array. * + * @return DOCUMENT ME! */ + public byte[] getEncodedValue() { + return encodedValue; + } + /** + * Returns the error code, or ERROR_NONE, if no error is present. + * + * @return the error code (0-8), or ERROR_NONE + */ + public int getErrorCode() { + return errorCode; + } + /** + * Decodes the Ber encoded control data. The ASN.1 value of the control data is:
+     *    PasswordPolicyResponseValue ::= SEQUENCE {       warning [0] CHOICE {
+     *           timeBeforeExpiration [0] INTEGER (0 .. maxInt),
+     *           graceAuthNsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL,       error   [1] ENUMERATED {
+     *           passwordExpired             (0),          accountLocked               (1),
+     *           changeAfterReset            (2),          passwordModNotAllowed       (3),
+     *           mustSupplyOldPassword       (4),          insufficientPasswordQuality (5),
+     *           passwordTooShort            (6),          passwordTooYoung            (7),
+     *           passwordInHistory           (8) } OPTIONAL }
+ * + * @return DOCUMENT ME! + */ /** * Returns the graceLoginsRemaining. - * + * * @return Returns the graceLoginsRemaining. */ public int getGraceLoginsRemaining() { @@ -135,34 +134,16 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { /** * Returns the timeBeforeExpiration. - * + * * @return Returns the time before expiration in seconds */ public int getTimeBeforeExpiration() { return timeBeforeExpiration; } - /** - * Returns the unchanged value of the response control. - * - * Returns the unchanged value of the response control as byte array. - */ - public byte[] getEncodedValue() { - return encodedValue; - } - - /** - * Returns the error code, or ERROR_NONE, if no error is present. - * - * @return the error code (0-8), or ERROR_NONE - */ - public int getErrorCode() { - return errorCode; - } - /** * Checks whether an error is present. - * + * * @return true, if an error is present */ public boolean hasError() { @@ -171,12 +152,11 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { /** * Checks whether a warning is present. - * + * * @return true, if a warning is present */ public boolean hasWarning() { - return graceLoginsRemaining != WARNINGS_DEFAULT - || timeBeforeExpiration != WARNINGS_DEFAULT; + return (graceLoginsRemaining != WARNINGS_DEFAULT) || (timeBeforeExpiration != WARNINGS_DEFAULT); } public boolean isExpired() { @@ -184,8 +164,7 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { } /** - * Determines whether an account locked error has - * been returned. + * Determines whether an account locked error has been returned. * * @return true if the account is locked. */ @@ -194,24 +173,25 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { } /** - * Create a textual representation containing error and warning messages, if - * any are present. - * + * Create a textual representation containing error and warning messages, if any are present. + * * @return error and warning messages */ public String toString() { - StringBuffer sb = new StringBuffer("PasswordPolicyResponseControl"); if (hasError()) { sb.append(", error: ").append(errorText[errorCode]); } + if (graceLoginsRemaining != WARNINGS_DEFAULT) { sb.append(", warning: ").append(graceLoginsRemaining).append(" grace logins remain"); } + if (timeBeforeExpiration != WARNINGS_DEFAULT) { sb.append(", warning: time before expiration is ").append(timeBeforeExpiration); } + if (!hasError() && !hasWarning()) { sb.append(" (no error, no warning)"); } @@ -219,64 +199,64 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { return sb.toString(); } - //~ Inner Classes ========================================================= + //~ Inner Interfaces =============================================================================================== private interface PPolicyDecoder { void decode() throws IOException; } - /** Decoder based on Netscape ldapsdk library */ - private class NetscapeDecoder implements PPolicyDecoder { + //~ Inner Classes ================================================================================================== + /** + * Decoder based on Netscape ldapsdk library + */ + private class NetscapeDecoder implements PPolicyDecoder { public void decode() throws IOException { - int[] bread = { 0 }; - BERSequence seq = (BERSequence) BERElement.getElement( - new SpecificTagDecoder(), new ByteArrayInputStream(encodedValue), bread); + int[] bread = {0}; + BERSequence seq = (BERSequence) BERElement.getElement(new SpecificTagDecoder(), + new ByteArrayInputStream(encodedValue), bread); int size = seq.size(); - if(logger.isDebugEnabled()) { - logger.debug("PasswordPolicyResponse, ASN.1 sequence has " + - size + " elements"); + if (logger.isDebugEnabled()) { + logger.debug("PasswordPolicyResponse, ASN.1 sequence has " + size + " elements"); } for (int i = 0; i < seq.size(); i++) { - BERTag elt = (BERTag)seq.elementAt(i); + BERTag elt = (BERTag) seq.elementAt(i); int tag = elt.getTag() & 0x1F; - if(tag == 0) { - BERChoice warning = (BERChoice)elt.getValue(); + if (tag == 0) { + BERChoice warning = (BERChoice) elt.getValue(); - BERTag content = (BERTag)warning.getValue(); - int value = ((BERInteger)content.getValue()).getValue(); + BERTag content = (BERTag) warning.getValue(); + int value = ((BERInteger) content.getValue()).getValue(); - if((content.getTag() & 0x1F) == 0) { + if ((content.getTag() & 0x1F) == 0) { timeBeforeExpiration = value; } else { graceLoginsRemaining = value; } - } else if(tag == 1) { - BEREnumerated error = (BEREnumerated)elt.getValue(); + } else if (tag == 1) { + BEREnumerated error = (BEREnumerated) elt.getValue(); errorCode = error.getValue(); } } - } class SpecificTagDecoder extends BERTagDecoder { /** Allows us to remember which of the two options we're decoding */ private Boolean inChoice = null; - public BERElement getElement(BERTagDecoder decoder, int tag, InputStream stream, - int[] bytesRead, boolean[] implicit) throws IOException { - + public BERElement getElement(BERTagDecoder decoder, int tag, InputStream stream, int[] bytesRead, + boolean[] implicit) throws IOException { tag &= 0x1F; implicit[0] = false; - if(tag == 0) { + if (tag == 0) { // Either the choice or the time before expiry within it - if(inChoice == null) { + if (inChoice == null) { setInChoice(true); // Read the choice length from the stream (ignored) @@ -292,16 +272,15 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { // Must be time before expiry return new BERInteger(stream, bytesRead); } - } else if(tag == 1) { + } else if (tag == 1) { // Either the graceLogins or the error enumeration. - if(inChoice == null) { + if (inChoice == null) { // The enumeration setInChoice(false); return new BEREnumerated(stream, bytesRead); - } else { - if(inChoice.booleanValue()) { + if (inChoice.booleanValue()) { // graceLogins return new BERInteger(stream, bytesRead); } @@ -317,7 +296,8 @@ public class PasswordPolicyResponseControl extends PasswordPolicyControl { } } - /** Decoder based on the OpenLDAP/Novell JLDAP library */ +/** Decoder based on the OpenLDAP/Novell JLDAP library */ + // private class JLdapDecoder implements PPolicyDecoder { // // public void decode() throws IOException { diff --git a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java index a31695e650..1d5971589a 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/ldap/authenticator/controls/PasswordPolicyResponseControlTests.java @@ -25,7 +25,7 @@ import junit.framework.TestCase; * @version $Id$ */ public class PasswordPolicyResponseControlTests extends TestCase { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== /** * Useful method for obtaining data from a server for use in tests diff --git a/sandbox/src/main/java/org/acegisecurity/providers/smb/AbstractSmbAuthenticationProvider.java b/sandbox/src/main/java/org/acegisecurity/providers/smb/AbstractSmbAuthenticationProvider.java index 3a62605205..82ab5c2515 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/smb/AbstractSmbAuthenticationProvider.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/smb/AbstractSmbAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; import org.apache.commons.logging.Log; @@ -33,42 +34,24 @@ import org.apache.commons.logging.LogFactory; /** - * An {@link AuthenticationProvider} implementation that relies on jcifs in order to provide an authentication - * service on a Windows network. This implementation relies on a {@link - * #setAuthorizationProvider(AuthenticationProvider) delegate provider} in - * order for authorization information to be filled into the authorized {@link - * Authentication token}. Subclasses must implement the logic that {@link - * #getNtlmPasswordAuthentication(Authentication) extracts the jcifs }{@link - * NtlmPasswordAuthentication } object from the particular {@link - * Authentication } token implementation and the one that {@link - * #getDomainController(Authentication, NtlmPasswordAuthentication) extracts - * the domain controller address }. + * An {@link AuthenticationProvider} implementation that relies on jcifs in + * order to provide an authentication service on a Windows network. This implementation relies on a {@link + * #setAuthorizationProvider(AuthenticationProvider) delegate provider} in order for authorization information to be + * filled into the authorized {@link Authentication token}. Subclasses must implement the logic that {@link + * #getNtlmPasswordAuthentication(Authentication) extracts the jcifs }{@link NtlmPasswordAuthentication } object from + * the particular {@link Authentication } token implementation and the one that {@link + * #getDomainController(Authentication, NtlmPasswordAuthentication) extracts the domain controller address }. * * @author Davide Baroncelli * @version $Id$ */ -public abstract class AbstractSmbAuthenticationProvider - implements AuthenticationProvider { - //~ Instance fields ======================================================== +public abstract class AbstractSmbAuthenticationProvider implements AuthenticationProvider { + //~ Instance fields ================================================================================================ private AuthenticationProvider authorizationProvider; private Log log = LogFactory.getLog(this.getClass()); - //~ Methods ================================================================ - - /** - * DOCUMENT ME! - * - * @param authorizationProvider The {@link AuthenticationProvider } which - * will be contacted in order for it to fill authorization info in - * the (already authenticated) {@link Authentication } object that - * they will be passed. - */ - public void setAuthorizationProvider( - AuthenticationProvider authorizationProvider) { - this.authorizationProvider = authorizationProvider; - } + //~ Methods ======================================================================================================== public Authentication authenticate(Authentication authentication) throws AuthenticationException { @@ -78,15 +61,13 @@ public abstract class AbstractSmbAuthenticationProvider return performAuthentication(dc, ntlm, authentication); } - protected abstract UniAddress getDomainController( - Authentication authentication, + protected abstract UniAddress getDomainController(Authentication authentication, NtlmPasswordAuthentication ntlmAuthentication); - protected abstract NtlmPasswordAuthentication getNtlmPasswordAuthentication( - Authentication authentication); + protected abstract NtlmPasswordAuthentication getNtlmPasswordAuthentication(Authentication authentication); - protected Authentication performAuthentication(UniAddress dc, - NtlmPasswordAuthentication ntlm, Authentication authentication) { + protected Authentication performAuthentication(UniAddress dc, NtlmPasswordAuthentication ntlm, + Authentication authentication) { try { // this performs authentication... SmbSession.logon(dc, ntlm); @@ -96,14 +77,11 @@ public abstract class AbstractSmbAuthenticationProvider } // ...and this performs authorization. - Authentication authorizedResult = authorizationProvider - .authenticate(authentication); + Authentication authorizedResult = authorizationProvider.authenticate(authentication); return authorizedResult; } catch (SmbException se) { - log.error(ntlm.getName() + ": 0x" - + jcifs.util.Hexdump.toHexString(se.getNtStatus(), 8) + ": " - + se); + log.error(ntlm.getName() + ": 0x" + jcifs.util.Hexdump.toHexString(se.getNtStatus(), 8) + ": " + se); if (se instanceof SmbAuthException) { SmbAuthException sae = (SmbAuthException) se; @@ -118,4 +96,15 @@ public abstract class AbstractSmbAuthenticationProvider } } } + + /** + * DOCUMENT ME! + * + * @param authorizationProvider The {@link AuthenticationProvider } which will be contacted in order for it to fill + * authorization info in the (already authenticated) {@link Authentication } object that they will be + * passed. + */ + public void setAuthorizationProvider(AuthenticationProvider authorizationProvider) { + this.authorizationProvider = authorizationProvider; + } } diff --git a/sandbox/src/main/java/org/acegisecurity/providers/smb/ChallengeExpiredException.java b/sandbox/src/main/java/org/acegisecurity/providers/smb/ChallengeExpiredException.java index fcff3df791..96392860fe 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/smb/ChallengeExpiredException.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/smb/ChallengeExpiredException.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import org.acegisecurity.AuthenticationException; * @version $Id$ */ public class ChallengeExpiredException extends AuthenticationException { - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== public ChallengeExpiredException(String msg) { super(msg); diff --git a/sandbox/src/main/java/org/acegisecurity/providers/smb/NtlmAuthenticationToken.java b/sandbox/src/main/java/org/acegisecurity/providers/smb/NtlmAuthenticationToken.java index c035af4278..9962bf3a77 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/smb/NtlmAuthenticationToken.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/smb/NtlmAuthenticationToken.java @@ -34,22 +34,20 @@ import org.acegisecurity.providers.AbstractAuthenticationToken; * @see org.acegisecurity.providers.smb.SmbNtlmAuthenticationProvider */ public class NtlmAuthenticationToken extends AbstractAuthenticationToken { - //~ Instance fields ======================================================== + //~ Instance fields ================================================================================================ private NtlmPasswordAuthentication ntlmPasswordAuthentication; private transient UniAddress domainController; - //~ Constructors =========================================================== + //~ Constructors =================================================================================================== - public NtlmAuthenticationToken( - NtlmPasswordAuthentication ntlmPasswordAuthentication, - UniAddress domainController) { + public NtlmAuthenticationToken(NtlmPasswordAuthentication ntlmPasswordAuthentication, UniAddress domainController) { super(null); this.ntlmPasswordAuthentication = ntlmPasswordAuthentication; this.domainController = domainController; } - //~ Methods ================================================================ + //~ Methods ======================================================================================================== public Object getCredentials() { return ntlmPasswordAuthentication.getPassword(); diff --git a/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbBasicAuthenticationProvider.java b/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbBasicAuthenticationProvider.java index f1019eaa10..3e1ae79b03 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbBasicAuthenticationProvider.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbBasicAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,33 +22,24 @@ import jcifs.smb.NtlmPasswordAuthentication; import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import java.net.UnknownHostException; /** - * Provides authentication of a basic {@link - * UsernamePasswordAuthenticationToken } on a ntlm domain via smb/cifs. + * Provides authentication of a basic {@link UsernamePasswordAuthenticationToken } on a ntlm domain via smb/cifs. * * @author Davide Baroncelli * @version $Id$ */ -public class SmbBasicAuthenticationProvider - extends AbstractSmbAuthenticationProvider { - //~ Instance fields ======================================================== +public class SmbBasicAuthenticationProvider extends AbstractSmbAuthenticationProvider { + //~ Instance fields ================================================================================================ String domainController; - //~ Methods ================================================================ - - public void setDomainController(String domainController) { - this.domainController = domainController; - } - - public boolean supports(Class authentication) { - return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); - } + //~ Methods ======================================================================================================== protected UniAddress getDomainController(Authentication authentication, NtlmPasswordAuthentication ntlmAuthentication) { @@ -67,14 +58,12 @@ public class SmbBasicAuthenticationProvider return dc; } catch (UnknownHostException uhe) { - throw new BadCredentialsException( - "no host could be found for the name " - + ntlmAuthentication.getDomain(), uhe); + throw new BadCredentialsException("no host could be found for the name " + ntlmAuthentication.getDomain(), + uhe); } } - protected NtlmPasswordAuthentication getNtlmPasswordAuthentication( - Authentication authentication) { + protected NtlmPasswordAuthentication getNtlmPasswordAuthentication(Authentication authentication) { UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication; String username = token.getPrincipal().toString(); String password = (String) token.getCredentials(); @@ -89,9 +78,16 @@ public class SmbBasicAuthenticationProvider String domain = (index != -1) ? username.substring(0, index) : null; username = (index != -1) ? username.substring(index + 1) : username; - NtlmPasswordAuthentication ntlm = new NtlmPasswordAuthentication(domain, - username, password); + NtlmPasswordAuthentication ntlm = new NtlmPasswordAuthentication(domain, username, password); return ntlm; } + + public void setDomainController(String domainController) { + this.domainController = domainController; + } + + public boolean supports(Class authentication) { + return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); + } } diff --git a/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbNtlmAuthenticationProvider.java b/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbNtlmAuthenticationProvider.java index 799242c3e2..aa33f4a686 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbNtlmAuthenticationProvider.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/smb/SmbNtlmAuthenticationProvider.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,26 +20,21 @@ import jcifs.UniAddress; import jcifs.smb.NtlmPasswordAuthentication; import org.acegisecurity.Authentication; + import org.acegisecurity.ui.ntlm.NtlmProcessingFilter; /** - * This class provides authentication through smb of {@link - * NtlmAuthenticationToken } (i.e. tokens obtained through the NTLM - * Authorization method by {@link NtlmProcessingFilter } ). + * This class provides authentication through smb of {@link NtlmAuthenticationToken } (i.e. tokens obtained through + * the NTLM Authorization method by {@link NtlmProcessingFilter } ). * * @author Davide Baroncelli * @version $Id$ * * @see org.acegisecurity.ui.ntlm.NtlmProcessingFilter */ -public class SmbNtlmAuthenticationProvider - extends AbstractSmbAuthenticationProvider { - //~ Methods ================================================================ - - public boolean supports(Class authentication) { - return NtlmAuthenticationToken.class.isAssignableFrom(authentication); - } +public class SmbNtlmAuthenticationProvider extends AbstractSmbAuthenticationProvider { + //~ Methods ======================================================================================================== protected UniAddress getDomainController(Authentication authentication, NtlmPasswordAuthentication ntlmAuthentication) { @@ -49,12 +44,14 @@ public class SmbNtlmAuthenticationProvider return dc; } - protected NtlmPasswordAuthentication getNtlmPasswordAuthentication( - Authentication authentication) { + protected NtlmPasswordAuthentication getNtlmPasswordAuthentication(Authentication authentication) { NtlmAuthenticationToken ntlmToken = (NtlmAuthenticationToken) authentication; - NtlmPasswordAuthentication ntlm = ntlmToken - .getNtlmPasswordAuthentication(); + NtlmPasswordAuthentication ntlm = ntlmToken.getNtlmPasswordAuthentication(); return ntlm; } + + public boolean supports(Class authentication) { + return NtlmAuthenticationToken.class.isAssignableFrom(authentication); + } } diff --git a/sandbox/src/main/java/org/acegisecurity/ui/ntlm/NtlmProcessingFilterEntryPoint.java b/sandbox/src/main/java/org/acegisecurity/ui/ntlm/NtlmProcessingFilterEntryPoint.java index d0539d287f..21472d2d8a 100644 --- a/sandbox/src/main/java/org/acegisecurity/ui/ntlm/NtlmProcessingFilterEntryPoint.java +++ b/sandbox/src/main/java/org/acegisecurity/ui/ntlm/NtlmProcessingFilterEntryPoint.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.acegisecurity.ui.ntlm; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.ui.AuthenticationEntryPoint; import java.io.IOException; @@ -33,15 +34,13 @@ import javax.servlet.http.HttpServletResponse; * @version $Id$ */ public class NtlmProcessingFilterEntryPoint implements AuthenticationEntryPoint { - //~ Methods ================================================================ + //~ Methods ======================================================================================================== - public void commence(ServletRequest request, ServletResponse response, - AuthenticationException authException) + public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletResponse resp = (HttpServletResponse) response; resp.setHeader("WWW-Authenticate", "NTLM"); resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, - (authException != null) ? authException.getMessage() : ""); + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, (authException != null) ? authException.getMessage() : ""); } } diff --git a/sandbox/src/test/java/org/acegisecurity/acls/domain/PermissionTests.java b/sandbox/src/test/java/org/acegisecurity/acls/domain/PermissionTests.java index 450f625f6b..e5e19db92f 100644 --- a/sandbox/src/test/java/org/acegisecurity/acls/domain/PermissionTests.java +++ b/sandbox/src/test/java/org/acegisecurity/acls/domain/PermissionTests.java @@ -1,41 +1,70 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.domain; import junit.framework.TestCase; + /** * Tests BasePermission and CumulativePermission. - * + * * @author Ben Alex * @version $Id${date} - * */ public class PermissionTests extends TestCase { - public void testStringConversion() { - System.out.println("R = " + BasePermission.READ.toString()); - assertEquals("BasePermission[...............................R=1]", BasePermission.READ.toString()); - - System.out.println("A = " + BasePermission.ADMINISTRATION.toString()); - assertEquals("BasePermission[............................A...=8]", BasePermission.ADMINISTRATION.toString()); - - System.out.println("R = " + new CumulativePermission().set(BasePermission.READ).toString()); - assertEquals("CumulativePermission[...............................R=1]", new CumulativePermission().set(BasePermission.READ).toString()); - - System.out.println("A = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).toString()); - assertEquals("CumulativePermission[............................A...=8]", new CumulativePermission().set(BasePermission.ADMINISTRATION).toString()); - - System.out.println("RA = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString()); - assertEquals("CumulativePermission[............................A..R=9]", new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString()); - - System.out.println("R = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).clear(BasePermission.ADMINISTRATION).toString()); - assertEquals("CumulativePermission[...............................R=1]", new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).clear(BasePermission.ADMINISTRATION).toString()); - - System.out.println("0 = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString()); - assertEquals("CumulativePermission[................................=0]", new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString()); - } - - public void testExpectedIntegerValues() { - assertEquals(1, BasePermission.READ.getMask()); - assertEquals(8, BasePermission.ADMINISTRATION.getMask()); - assertEquals(9, new CumulativePermission().set(BasePermission.READ).set(BasePermission.ADMINISTRATION).getMask()); - } + //~ Methods ======================================================================================================== + + public void testExpectedIntegerValues() { + assertEquals(1, BasePermission.READ.getMask()); + assertEquals(8, BasePermission.ADMINISTRATION.getMask()); + assertEquals(9, new CumulativePermission().set(BasePermission.READ).set(BasePermission.ADMINISTRATION).getMask()); + } + + public void testStringConversion() { + System.out.println("R = " + BasePermission.READ.toString()); + assertEquals("BasePermission[...............................R=1]", BasePermission.READ.toString()); + + System.out.println("A = " + BasePermission.ADMINISTRATION.toString()); + assertEquals("BasePermission[............................A...=8]", BasePermission.ADMINISTRATION.toString()); + + System.out.println("R = " + new CumulativePermission().set(BasePermission.READ).toString()); + assertEquals("CumulativePermission[...............................R=1]", + new CumulativePermission().set(BasePermission.READ).toString()); + + System.out.println("A = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).toString()); + assertEquals("CumulativePermission[............................A...=8]", + new CumulativePermission().set(BasePermission.ADMINISTRATION).toString()); + + System.out.println("RA = " + + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString()); + assertEquals("CumulativePermission[............................A..R=9]", + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString()); + + System.out.println("R = " + + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ) + .clear(BasePermission.ADMINISTRATION).toString()); + assertEquals("CumulativePermission[...............................R=1]", + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ) + .clear(BasePermission.ADMINISTRATION).toString()); + + System.out.println("0 = " + + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ) + .clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString()); + assertEquals("CumulativePermission[................................=0]", + new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ) + .clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString()); + } } diff --git a/sandbox/src/test/java/org/acegisecurity/acls/jdbc/DatabaseSeeder.java b/sandbox/src/test/java/org/acegisecurity/acls/jdbc/DatabaseSeeder.java index d173bc08a4..4502ddd538 100644 --- a/sandbox/src/test/java/org/acegisecurity/acls/jdbc/DatabaseSeeder.java +++ b/sandbox/src/test/java/org/acegisecurity/acls/jdbc/DatabaseSeeder.java @@ -1,23 +1,48 @@ +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.acegisecurity.acls.jdbc; +import org.springframework.core.io.Resource; + +import org.springframework.jdbc.core.JdbcTemplate; + +import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; + import java.io.IOException; import javax.sql.DataSource; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.util.Assert; -import org.springframework.util.FileCopyUtils; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class DatabaseSeeder { - - public DatabaseSeeder(DataSource dataSource, Resource resource) throws IOException { - Assert.notNull(dataSource, "dataSource required"); - Assert.notNull(resource, "resource required"); - - JdbcTemplate template = new JdbcTemplate(dataSource); - String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream())); - template.execute(sql); - } + //~ Constructors =================================================================================================== + public DatabaseSeeder(DataSource dataSource, Resource resource) + throws IOException { + Assert.notNull(dataSource, "dataSource required"); + Assert.notNull(resource, "resource required"); + + JdbcTemplate template = new JdbcTemplate(dataSource); + String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream())); + template.execute(sql); + } } diff --git a/sandbox/src/test/java/org/acegisecurity/acls/jdbc/JdbcAclServiceTests.java b/sandbox/src/test/java/org/acegisecurity/acls/jdbc/JdbcAclServiceTests.java index f537192674..b52995fb09 100644 --- a/sandbox/src/test/java/org/acegisecurity/acls/jdbc/JdbcAclServiceTests.java +++ b/sandbox/src/test/java/org/acegisecurity/acls/jdbc/JdbcAclServiceTests.java @@ -1,40 +1,65 @@ -package org.acegisecurity.acls.jdbc; +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import java.util.Iterator; -import java.util.Map; +package org.acegisecurity.acls.jdbc; import org.acegisecurity.acls.Acl; import org.acegisecurity.acls.objectidentity.ObjectIdentity; import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl; + import org.springframework.test.AbstractDependencyInjectionSpringContextTests; +import java.util.Iterator; +import java.util.Map; + + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ public class JdbcAclServiceTests extends AbstractDependencyInjectionSpringContextTests { + //~ Instance fields ================================================================================================ - protected String[] getConfigLocations() { - return new String[] {"classpath:org/acegisecurity/acls/jdbc/applicationContext-test.xml"}; - } - - private JdbcAclService jdbcAclService; - - public void testStub() { - ObjectIdentity id1 = new ObjectIdentityImpl("sample.contact.Contact", new Long(1)); - ObjectIdentity id2 = new ObjectIdentityImpl("sample.contact.Contact", new Long(2)); - ObjectIdentity id3 = new ObjectIdentityImpl("sample.contact.Contact", new Long(3)); - ObjectIdentity id4 = new ObjectIdentityImpl("sample.contact.Contact", new Long(4)); - ObjectIdentity id5 = new ObjectIdentityImpl("sample.contact.Contact", new Long(5)); - ObjectIdentity id6 = new ObjectIdentityImpl("sample.contact.Contact", new Long(6)); - Map map = jdbcAclService.readAclsById(new ObjectIdentity[] {id1, id2, id3, id4, id5, id6}); - Iterator iterator = map.keySet().iterator(); - while (iterator.hasNext()) { - ObjectIdentity identity = (ObjectIdentity) iterator.next(); - assertEquals(identity, ((Acl)map.get(identity)).getObjectIdentity()); - System.out.println(map.get(identity)); - } - } + private JdbcAclService jdbcAclService; - public void setJdbcAclService(JdbcAclService jdbcAclService) { - this.jdbcAclService = jdbcAclService; - } + //~ Methods ======================================================================================================== + protected String[] getConfigLocations() { + return new String[] {"classpath:org/acegisecurity/acls/jdbc/applicationContext-test.xml"}; + } + public void setJdbcAclService(JdbcAclService jdbcAclService) { + this.jdbcAclService = jdbcAclService; + } + + public void testStub() { + ObjectIdentity id1 = new ObjectIdentityImpl("sample.contact.Contact", new Long(1)); + ObjectIdentity id2 = new ObjectIdentityImpl("sample.contact.Contact", new Long(2)); + ObjectIdentity id3 = new ObjectIdentityImpl("sample.contact.Contact", new Long(3)); + ObjectIdentity id4 = new ObjectIdentityImpl("sample.contact.Contact", new Long(4)); + ObjectIdentity id5 = new ObjectIdentityImpl("sample.contact.Contact", new Long(5)); + ObjectIdentity id6 = new ObjectIdentityImpl("sample.contact.Contact", new Long(6)); + Map map = jdbcAclService.readAclsById(new ObjectIdentity[] {id1, id2, id3, id4, id5, id6}); + Iterator iterator = map.keySet().iterator(); + + while (iterator.hasNext()) { + ObjectIdentity identity = (ObjectIdentity) iterator.next(); + assertEquals(identity, ((Acl) map.get(identity)).getObjectIdentity()); + System.out.println(map.get(identity)); + } + } }