SEC-239: New ACL module.
This commit is contained in:
+50
-37
@@ -12,15 +12,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact.annotation;
|
||||
|
||||
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.acls.AccessControlEntry;
|
||||
import org.acegisecurity.acls.MutableAcl;
|
||||
import org.acegisecurity.acls.MutableAclService;
|
||||
import org.acegisecurity.acls.NotFoundException;
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
import org.acegisecurity.acls.sid.Sid;
|
||||
|
||||
import org.acegisecurity.annotation.Secured;
|
||||
|
||||
@@ -54,28 +59,36 @@ import java.util.Random;
|
||||
public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private BasicAclExtendedDao basicAclExtendedDao;
|
||||
private ContactDao contactDao;
|
||||
private int counter = 100;
|
||||
|
||||
// TODO: Assignment of annotations against class does not result in match in sample application
|
||||
private MutableAclService mutableAclService;
|
||||
private int counter = 1000;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@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);
|
||||
public void addPermission(Contact contact, Sid recipient, Permission permission) {
|
||||
MutableAcl acl;
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
|
||||
try {
|
||||
acl = (MutableAcl) mutableAclService.readAclById(oid);
|
||||
} catch (NotFoundException nfe) {
|
||||
acl = mutableAclService.createAcl(oid);
|
||||
}
|
||||
|
||||
acl.insertAce(null, permission, recipient, true);
|
||||
mutableAclService.updateAcl(acl);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added permission " + permission + " for recipient " + recipient + " contact " + contact);
|
||||
logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(contactDao, "contactDao required");
|
||||
Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required");
|
||||
Assert.notNull(mutableAclService, "mutableAclService required");
|
||||
}
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
@@ -84,8 +97,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
contact.setId(new Long(counter++));
|
||||
contactDao.create(contact);
|
||||
|
||||
// Grant the current principal access to the contact
|
||||
addPermission(contact, getUsername(), new Integer(SimpleAclEntry.ADMINISTRATION));
|
||||
// Grant the current principal administrative permission to the contact
|
||||
addPermission(contact, new PrincipalSid(getUsername()), BasePermission.ADMINISTRATION);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername());
|
||||
@@ -97,7 +110,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
contactDao.delete(contact.getId());
|
||||
|
||||
// Delete the ACL information as well
|
||||
basicAclExtendedDao.delete(makeObjectIdentity(contact));
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
mutableAclService.deleteAcl(oid, false);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Deleted contact " + contact + " including ACL permissions");
|
||||
@@ -105,8 +119,20 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
}
|
||||
|
||||
@Secured({"ACL_CONTACT_ADMIN"})
|
||||
public void deletePermission(Contact contact, String recipient) {
|
||||
basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient);
|
||||
public void deletePermission(Contact contact, Sid recipient, Permission permission) {
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
|
||||
|
||||
// Remove all permissions associated with this particular recipient (string equality to KISS)
|
||||
AccessControlEntry[] entries = acl.getEntries();
|
||||
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].getSid().equals(recipient) && entries[i].getPermission().equals(permission)) {
|
||||
acl.deleteAce(entries[i].getId());
|
||||
}
|
||||
}
|
||||
|
||||
mutableAclService.updateAcl(acl);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient);
|
||||
@@ -131,15 +157,10 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
}
|
||||
|
||||
List list = contactDao.findAllPrincipals();
|
||||
list.addAll(contactDao.findAllRoles());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public BasicAclExtendedDao getBasicAclExtendedDao() {
|
||||
return basicAclExtendedDao;
|
||||
}
|
||||
|
||||
@Secured({"ROLE_USER", "AFTER_ACL_READ"})
|
||||
@Transactional(readOnly = true)
|
||||
public Contact getById(Long id) {
|
||||
@@ -150,10 +171,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
return contactDao.getById(id);
|
||||
}
|
||||
|
||||
public ContactDao getContactDao() {
|
||||
return contactDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a public method.
|
||||
*
|
||||
@@ -181,18 +198,14 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
}
|
||||
}
|
||||
|
||||
private AclObjectIdentity makeObjectIdentity(Contact contact) {
|
||||
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 setMutableAclService(MutableAclService mutableAclService) {
|
||||
this.mutableAclService = mutableAclService;
|
||||
}
|
||||
|
||||
public void update(Contact contact) {
|
||||
contactDao.update(contact);
|
||||
|
||||
|
||||
-163
@@ -1,163 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing authentication beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
- $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- ~~~~~~~~~~~~~~~~~~ "BEFORE INVOCATION" AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~ -->
|
||||
|
||||
<!-- ACL permission masks used by this application -->
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION</value></property>
|
||||
</bean>
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ</value></property>
|
||||
</bean>
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE</value></property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- An access decision voter that reads ROLE_* configuration settings -->
|
||||
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_READ configuration settings -->
|
||||
<bean id="aclContactReadVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_READ</value></property>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_DELETE configuration settings -->
|
||||
<bean id="aclContactDeleteVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_DELETE</value></property>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_ADMIN configuration settings -->
|
||||
<bean id="aclContactAdminVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_ADMIN</value></property>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision manager used by the business objects -->
|
||||
<bean id="businessAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
|
||||
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
|
||||
<property name="decisionVoters">
|
||||
<list>
|
||||
<ref local="roleVoter"/>
|
||||
<ref local="aclContactReadVoter"/>
|
||||
<ref local="aclContactDeleteVoter"/>
|
||||
<ref local="aclContactAdminVoter"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- ========= ACCESS CONTROL LIST LOOKUP MANAGER DEFINITIONS ========= -->
|
||||
|
||||
<bean id="aclManager" class="net.sf.acegisecurity.acl.AclProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref local="basicAclProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclProvider" class="net.sf.acegisecurity.acl.basic.BasicAclProvider">
|
||||
<property name="basicAclDao"><ref local="basicAclExtendedDao"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclExtendedDao" class="net.sf.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl">
|
||||
<property name="dataSource"><ref bean="dataSource"/></property>
|
||||
</bean>
|
||||
|
||||
<!-- ============== "AFTER INTERCEPTION" AUTHORIZATION DEFINITIONS =========== -->
|
||||
|
||||
<bean id="afterInvocationManager" class="net.sf.acegisecurity.afterinvocation.AfterInvocationProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref local="afterAclRead"/>
|
||||
<ref local="afterAclCollectionRead"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_COLLECTION_READ configuration settings -->
|
||||
<bean id="afterAclCollectionRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_READ configuration settings -->
|
||||
<bean id="afterAclRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ================= METHOD INVOCATION AUTHORIZATION ==================== -->
|
||||
|
||||
<!-- getRandomContact() is public.
|
||||
|
||||
The create, getAll, getById etc have ROLE_USER to ensure user is
|
||||
authenticated (all users hold ROLE_USER in this application).
|
||||
|
||||
The delete and update methods don't need a ROLE_USER as they will
|
||||
ensure the user is authenticated via their ACL_CONTACT_DELETE or
|
||||
ACL_CONTACT_READ attribute, which also ensures the user has permission
|
||||
to the Contact presented as a method argument.
|
||||
-->
|
||||
<bean id="contactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
|
||||
<property name="objectDefinitionSource">
|
||||
<value>
|
||||
sample.contact.ContactManager.create=ROLE_USER
|
||||
sample.contact.ContactManager.getAllRecipients=ROLE_USER
|
||||
sample.contact.ContactManager.getAll=ROLE_USER,AFTER_ACL_COLLECTION_READ
|
||||
sample.contact.ContactManager.getById=ROLE_USER,AFTER_ACL_READ
|
||||
sample.contact.ContactManager.delete=ACL_CONTACT_DELETE
|
||||
sample.contact.ContactManager.deletePermission=ACL_CONTACT_ADMIN
|
||||
sample.contact.ContactManager.addPermission=ACL_CONTACT_ADMIN
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing business beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
- $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName">
|
||||
<value>org.hsqldb.jdbcDriver</value>
|
||||
</property>
|
||||
<property name="url">
|
||||
<value>jdbc:hsqldb:mem:contacts</value>
|
||||
</property>
|
||||
<property name="username">
|
||||
<value>sa</value>
|
||||
</property>
|
||||
<property name="password">
|
||||
<value></value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource"><ref local="dataSource"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||
<property name="transactionManager"><ref bean="transactionManager"/></property>
|
||||
<property name="transactionAttributeSource">
|
||||
<value>
|
||||
sample.contact.ContactManager.create=PROPAGATION_REQUIRED
|
||||
sample.contact.ContactManager.getAllRecipients=PROPAGATION_REQUIRED,readOnly
|
||||
sample.contact.ContactManager.getAll=PROPAGATION_REQUIRED,readOnly
|
||||
sample.contact.ContactManager.getById=PROPAGATION_REQUIRED,readOnly
|
||||
sample.contact.ContactManager.delete=PROPAGATION_REQUIRED
|
||||
sample.contact.ContactManager.deletePermission=PROPAGATION_REQUIRED
|
||||
sample.contact.ContactManager.addPermission=PROPAGATION_REQUIRED
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSourcePopulator" class="sample.contact.DataSourcePopulator">
|
||||
<property name="dataSource"><ref local="dataSource"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="contactDao" class="sample.contact.ContactDaoSpring">
|
||||
<property name="dataSource"><ref local="dataSource"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="contactManager" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces"><value>sample.contact.ContactManager</value></property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="transactionInterceptor"/>
|
||||
<idref bean="contactManagerSecurity"/>
|
||||
<idref local="contactManagerTarget"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="contactManagerTarget" class="sample.contact.ContactManagerBackend">
|
||||
<property name="contactDao"><ref local="contactDao"/></property>
|
||||
<property name="basicAclExtendedDao"><ref bean="basicAclExtendedDao"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
+32
-2
@@ -21,7 +21,7 @@
|
||||
<value>
|
||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||
PATTERN_TYPE_APACHE_ANT
|
||||
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
|
||||
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -38,7 +38,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcDaoImpl" class="org.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
|
||||
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
|
||||
<property name="dataSource"><ref bean="dataSource"/></property>
|
||||
</bean>
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="rememberMeServices"><ref local="rememberMeServices"/></property>
|
||||
</bean>
|
||||
|
||||
@@ -101,6 +102,18 @@
|
||||
<bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
|
||||
<property name="key"><value>springRocks</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
|
||||
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout -->
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref bean="rememberMeServices"/>
|
||||
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
|
||||
|
||||
<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->
|
||||
|
||||
@@ -136,6 +149,11 @@
|
||||
|
||||
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
|
||||
<property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
|
||||
<property name="accessDeniedHandler">
|
||||
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
|
||||
<property name="errorPage" value="/accessDenied.jsp"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
|
||||
@@ -173,10 +191,22 @@
|
||||
/index.jsp=ROLE_ANONYMOUS,ROLE_USER
|
||||
/hello.htm=ROLE_ANONYMOUS,ROLE_USER
|
||||
/logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
|
||||
/switchuser.jsp=ROLE_SUPERVISOR
|
||||
/j_acegi_switch_user=ROLE_SUPERVISOR
|
||||
/acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
|
||||
/**=ROLE_USER
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Filter used to switch the user context. Note: the switch and exit url must be secured
|
||||
based on the role granted the ability to 'switch' to another user -->
|
||||
<!-- In this example 'marissa' has ROLE_SUPERVISOR that can switch to regular ROLE_USER(s) -->
|
||||
<bean id="switchUserProcessingFilter" class="org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter">
|
||||
<property name="userDetailsService" 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>/acegi-security-sample-contacts-filter/secure/index.htm</value></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
+114
-71
@@ -12,60 +12,72 @@
|
||||
<!-- ~~~~~~~~~~~~~~~~~~ "BEFORE INVOCATION" AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~ -->
|
||||
|
||||
<!-- ACL permission masks used by this application -->
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION</value></property>
|
||||
</bean>
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.READ</value></property>
|
||||
</bean>
|
||||
<bean id="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.DELETE</value></property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- An access decision voter that reads ROLE_* configuration settings -->
|
||||
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
|
||||
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter"/>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_READ configuration settings -->
|
||||
<bean id="aclContactReadVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_READ</value></property>
|
||||
<bean id="aclContactReadVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_READ</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_DELETE configuration settings -->
|
||||
<bean id="aclContactDeleteVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_DELETE</value></property>
|
||||
<bean id="aclContactDeleteVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_DELETE</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.DELETE"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_ADMIN configuration settings -->
|
||||
<bean id="aclContactAdminVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_ADMIN</value></property>
|
||||
<bean id="aclContactAdminVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_ADMIN</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision manager used by the business objects -->
|
||||
<bean id="businessAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
|
||||
<bean id="businessAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
|
||||
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
|
||||
<property name="decisionVoters">
|
||||
<list>
|
||||
@@ -79,25 +91,53 @@
|
||||
|
||||
<!-- ========= ACCESS CONTROL LIST LOOKUP MANAGER DEFINITIONS ========= -->
|
||||
|
||||
<bean id="aclManager" class="net.sf.acegisecurity.acl.AclProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref local="basicAclProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclProvider" class="net.sf.acegisecurity.acl.basic.BasicAclProvider">
|
||||
<property name="basicAclDao"><ref local="basicAclExtendedDao"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclExtendedDao" class="net.sf.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl">
|
||||
<property name="dataSource"><ref bean="dataSource"/></property>
|
||||
</bean>
|
||||
<bean id="aclCache" class="org.acegisecurity.acls.jdbc.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName">
|
||||
<value>aclCache</value>
|
||||
</property>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.acegisecurity.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.acegisecurity.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.acegisecurity.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.acegisecurity.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
</bean>
|
||||
|
||||
<!-- ============== "AFTER INTERCEPTION" AUTHORIZATION DEFINITIONS =========== -->
|
||||
|
||||
<bean id="afterInvocationManager" class="net.sf.acegisecurity.afterinvocation.AfterInvocationProviderManager">
|
||||
<bean id="afterInvocationManager" class="org.acegisecurity.afterinvocation.AfterInvocationProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref local="afterAclRead"/>
|
||||
@@ -107,38 +147,41 @@
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_COLLECTION_READ configuration settings -->
|
||||
<bean id="afterAclCollectionRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
<bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_READ configuration settings -->
|
||||
<bean id="afterAclRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
<bean id="afterAclRead" class="org.acegisecurity.afterinvocation.AclEntryAfterInvocationProvider">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ================= METHOD INVOCATION AUTHORIZATION ==================== -->
|
||||
|
||||
<bean id="attributes" class="net.sf.acegisecurity.annotation.SecurityAnnotationAttributes"/>
|
||||
<bean id="attributes" class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/>
|
||||
|
||||
<bean id="objectDefinitionSource" class="net.sf.acegisecurity.intercept.method.MethodDefinitionAttributes">
|
||||
<bean id="objectDefinitionSource" class="org.acegisecurity.intercept.method.MethodDefinitionAttributes">
|
||||
<property name="attributes"><ref local="attributes"/></property>
|
||||
</bean>
|
||||
|
||||
<!-- We don't validate config attributes, as it's unsupported by MethodDefinitionAttributes -->
|
||||
<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<bean id="securityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="validateConfigAttributes"><value>false</value></property>
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref bean="businessAccessDecisionManager"/></property>
|
||||
@@ -160,7 +203,7 @@
|
||||
which in the above configuration is a JDK 5 Annotations Attributes-based source.
|
||||
-->
|
||||
<bean id="methodSecurityAdvisor"
|
||||
class="net.sf.acegisecurity.intercept.method.aopalliance.MethodDefinitionSourceAdvisor"
|
||||
class="org.acegisecurity.intercept.method.aopalliance.MethodDefinitionSourceAdvisor"
|
||||
autowire="constructor" >
|
||||
</bean>
|
||||
|
||||
|
||||
+4
-2
@@ -31,7 +31,9 @@
|
||||
</bean>
|
||||
|
||||
<bean id="dataSourcePopulator" class="sample.contact.DataSourcePopulator">
|
||||
<property name="dataSource"><ref local="dataSource"/></property>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="mutableAclService" ref="aclService"/>
|
||||
<property name="platformTransactionManager" ref="transactionManager"/>
|
||||
</bean>
|
||||
|
||||
<bean id="contactDao" class="sample.contact.ContactDaoSpring">
|
||||
@@ -42,7 +44,7 @@
|
||||
<!-- Advised Contact Manager using Java 5 Annotations -->
|
||||
<bean id="contactManager" class="sample.contact.annotation.ContactManagerBackend">
|
||||
<property name="contactDao"><ref local="contactDao"/></property>
|
||||
<property name="basicAclExtendedDao"><ref bean="basicAclExtendedDao"/></property>
|
||||
<property name="mutableAclService"><ref bean="aclService"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
|
||||
<filter>
|
||||
<filter-name>Acegi Filter Chain Proxy</filter-name>
|
||||
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
|
||||
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
|
||||
<init-param>
|
||||
<param-name>targetClass</param-name>
|
||||
<param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
|
||||
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
to the WebApplicationContext
|
||||
-->
|
||||
<listener>
|
||||
<listener-class>net.sf.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
|
||||
<listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
|
||||
</listener>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<%@ page import="org.acegisecurity.context.SecurityContextHolder" %>
|
||||
<%@ page import="org.acegisecurity.Authentication" %>
|
||||
<%@ page import="org.acegisecurity.ui.AccessDeniedHandlerImpl" %>
|
||||
|
||||
<h1>Sorry, access is denied</h1>
|
||||
|
||||
|
||||
<p>
|
||||
<%= request.getAttribute(AccessDeniedHandlerImpl.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY)%>
|
||||
|
||||
<p>
|
||||
|
||||
<% Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth != null) { %>
|
||||
Authentication object as a String: <%= auth.toString() %><BR><BR>
|
||||
<% } %>
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<title>Access denied!</title>
|
||||
<h1>Access Denied</h1>
|
||||
We're sorry, but you are not authorized to perform the requested operation.
|
||||
</html>
|
||||
@@ -12,7 +12,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
@@ -28,7 +27,7 @@ public class AddPermission {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
public Contact contact;
|
||||
public Integer permission = new Integer(SimpleAclEntry.NOTHING);
|
||||
public Integer permission = new Integer(SimpleAclEntry.READ);
|
||||
public String recipient;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -59,7 +60,7 @@ public class AddPermissionController extends SimpleFormController implements Ini
|
||||
protected ModelAndView disallowDuplicateFormSubmission(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
BindException errors = new BindException(formBackingObject(request), getCommandName());
|
||||
errors.reject("err.duplicateFormSubmission", "Duplicate form submission.");
|
||||
errors.reject("err.duplicateFormSubmission", "Duplicate form submission. *");
|
||||
|
||||
return showForm(request, response, errors);
|
||||
}
|
||||
@@ -76,10 +77,6 @@ public class AddPermissionController extends SimpleFormController implements Ini
|
||||
return addPermission;
|
||||
}
|
||||
|
||||
public ContactManager getContactManager() {
|
||||
return contactManager;
|
||||
}
|
||||
|
||||
protected ModelAndView handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return disallowDuplicateFormSubmission(request, response);
|
||||
@@ -87,16 +84,12 @@ public class AddPermissionController extends SimpleFormController implements Ini
|
||||
|
||||
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),
|
||||
map.put(new Integer(BasePermission.ADMINISTRATION.getMask()),
|
||||
getApplicationContext().getMessage("select.administer", null, "Administer", request.getLocale()));
|
||||
map.put(new Integer(SimpleAclEntry.READ),
|
||||
map.put(new Integer(BasePermission.READ.getMask()),
|
||||
getApplicationContext().getMessage("select.read", null, "Read", request.getLocale()));
|
||||
map.put(new Integer(SimpleAclEntry.DELETE),
|
||||
map.put(new Integer(BasePermission.DELETE.getMask()),
|
||||
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;
|
||||
}
|
||||
@@ -120,13 +113,14 @@ public class AddPermissionController extends SimpleFormController implements Ini
|
||||
BindException errors) throws Exception {
|
||||
AddPermission addPermission = (AddPermission) command;
|
||||
|
||||
PrincipalSid sid = new PrincipalSid(addPermission.getRecipient());
|
||||
Permission permission = BasePermission.buildFromMask(addPermission.getPermission().intValue());
|
||||
|
||||
try {
|
||||
contactManager.addPermission(addPermission.getContact(), addPermission.getRecipient(),
|
||||
addPermission.getPermission());
|
||||
contactManager.addPermission(addPermission.getContact(), sid, permission);
|
||||
} catch (DataAccessException existingPermission) {
|
||||
existingPermission.printStackTrace();
|
||||
errors.rejectValue("recipient", "err.recipientExistsForContact",
|
||||
"This recipient already has permissions to this contact.");
|
||||
errors.rejectValue("recipient", "err.recipientExistsForContact", "Addition failure.");
|
||||
|
||||
return showForm(request, response, errors);
|
||||
}
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ValidationUtils;
|
||||
@@ -44,9 +43,8 @@ public class AddPermissionValidator implements Validator {
|
||||
if (addPermission.getPermission() != null) {
|
||||
int permission = addPermission.getPermission().intValue();
|
||||
|
||||
if ((permission != SimpleAclEntry.NOTHING) && (permission != SimpleAclEntry.ADMINISTRATION)
|
||||
&& (permission != SimpleAclEntry.READ) && (permission != SimpleAclEntry.DELETE)
|
||||
&& (permission != SimpleAclEntry.READ_WRITE_DELETE)) {
|
||||
if ((permission != BasePermission.ADMINISTRATION.getMask())
|
||||
&& (permission != BasePermission.READ.getMask()) && (permission != BasePermission.DELETE.getMask())) {
|
||||
errors.rejectValue("permission", "err.permission.invalid", "The indicated permission is invalid. *");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acls.Acl;
|
||||
import org.acegisecurity.acls.AclService;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -45,22 +45,14 @@ import javax.servlet.http.HttpServletResponse;
|
||||
public class AdminPermissionController implements Controller, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclManager aclManager;
|
||||
private AclService aclService;
|
||||
private ContactManager contactManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
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 ContactManager getContactManager() {
|
||||
return contactManager;
|
||||
Assert.notNull(aclService, "An aclService implementation is required");
|
||||
}
|
||||
|
||||
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
@@ -68,17 +60,17 @@ public class AdminPermissionController implements Controller, InitializingBean {
|
||||
int id = RequestUtils.getRequiredIntParameter(request, "contactId");
|
||||
|
||||
Contact contact = contactManager.getById(new Long(id));
|
||||
AclEntry[] acls = aclManager.getAcls(contact);
|
||||
Acl acl = aclService.readAclById(new ObjectIdentityImpl(contact));
|
||||
|
||||
Map model = new HashMap();
|
||||
model.put("contact", contact);
|
||||
model.put("acls", acls);
|
||||
model.put("acl", acl);
|
||||
|
||||
return new ModelAndView("adminPermission", "model", model);
|
||||
}
|
||||
|
||||
public void setAclManager(AclManager aclManager) {
|
||||
this.aclManager = aclManager;
|
||||
public void setAclService(AclService aclService) {
|
||||
this.aclService = aclService;
|
||||
}
|
||||
|
||||
public void setContactManager(ContactManager contact) {
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.sid.Sid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -27,13 +29,13 @@ import java.util.List;
|
||||
public interface ContactManager {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void addPermission(Contact contact, String recipient, Integer permission);
|
||||
public void addPermission(Contact contact, Sid recipient, Permission permission);
|
||||
|
||||
public void create(Contact contact);
|
||||
|
||||
public void delete(Contact contact);
|
||||
|
||||
public void deletePermission(Contact contact, String recipient);
|
||||
public void deletePermission(Contact contact, Sid recipient, Permission permission);
|
||||
|
||||
public List getAll();
|
||||
|
||||
|
||||
@@ -12,15 +12,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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.acls.AccessControlEntry;
|
||||
import org.acegisecurity.acls.MutableAcl;
|
||||
import org.acegisecurity.acls.MutableAclService;
|
||||
import org.acegisecurity.acls.NotFoundException;
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
import org.acegisecurity.acls.sid.Sid;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
@@ -45,27 +50,33 @@ import java.util.Random;
|
||||
public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private BasicAclExtendedDao basicAclExtendedDao;
|
||||
private ContactDao contactDao;
|
||||
private MutableAclService mutableAclService;
|
||||
private int counter = 1000;
|
||||
|
||||
//~ 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);
|
||||
public void addPermission(Contact contact, Sid recipient, Permission permission) {
|
||||
MutableAcl acl;
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
|
||||
try {
|
||||
acl = (MutableAcl) mutableAclService.readAclById(oid);
|
||||
} catch (NotFoundException nfe) {
|
||||
acl = mutableAclService.createAcl(oid);
|
||||
}
|
||||
|
||||
acl.insertAce(null, permission, recipient, true);
|
||||
mutableAclService.updateAcl(acl);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added permission " + permission + " for recipient " + recipient + " contact " + contact);
|
||||
logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(contactDao, "contactDao required");
|
||||
Assert.notNull(basicAclExtendedDao, "basicAclExtendedDao required");
|
||||
Assert.notNull(mutableAclService, "mutableAclService required");
|
||||
}
|
||||
|
||||
public void create(Contact contact) {
|
||||
@@ -73,8 +84,8 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
contact.setId(new Long(counter++));
|
||||
contactDao.create(contact);
|
||||
|
||||
// Grant the current principal access to the contact
|
||||
addPermission(contact, getUsername(), new Integer(SimpleAclEntry.ADMINISTRATION));
|
||||
// Grant the current principal administrative permission to the contact
|
||||
addPermission(contact, new PrincipalSid(getUsername()), BasePermission.ADMINISTRATION);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername());
|
||||
@@ -85,15 +96,28 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
contactDao.delete(contact.getId());
|
||||
|
||||
// Delete the ACL information as well
|
||||
basicAclExtendedDao.delete(makeObjectIdentity(contact));
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
mutableAclService.deleteAcl(oid, false);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Deleted contact " + contact + " including ACL permissions");
|
||||
}
|
||||
}
|
||||
|
||||
public void deletePermission(Contact contact, String recipient) {
|
||||
basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient);
|
||||
public void deletePermission(Contact contact, Sid recipient, Permission permission) {
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
|
||||
MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
|
||||
|
||||
// Remove all permissions associated with this particular recipient (string equality to KISS)
|
||||
AccessControlEntry[] entries = acl.getEntries();
|
||||
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].getSid().equals(recipient) && entries[i].getPermission().equals(permission)) {
|
||||
acl.deleteAce(entries[i].getId());
|
||||
}
|
||||
}
|
||||
|
||||
mutableAclService.updateAcl(acl);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient);
|
||||
@@ -114,15 +138,10 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
}
|
||||
|
||||
List list = contactDao.findAllPrincipals();
|
||||
list.addAll(contactDao.findAllRoles());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public BasicAclExtendedDao getBasicAclExtendedDao() {
|
||||
return basicAclExtendedDao;
|
||||
}
|
||||
|
||||
public Contact getById(Long id) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Returning contact with id: " + id);
|
||||
@@ -131,10 +150,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
return contactDao.getById(id);
|
||||
}
|
||||
|
||||
public ContactDao getContactDao() {
|
||||
return contactDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a public method.
|
||||
*
|
||||
@@ -162,18 +177,14 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C
|
||||
}
|
||||
}
|
||||
|
||||
private AclObjectIdentity makeObjectIdentity(Contact contact) {
|
||||
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 setMutableAclService(MutableAclService mutableAclService) {
|
||||
this.mutableAclService = mutableAclService;
|
||||
}
|
||||
|
||||
public void update(Contact contact) {
|
||||
contactDao.update(contact);
|
||||
|
||||
|
||||
@@ -12,13 +12,34 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import org.acegisecurity.acls.MutableAcl;
|
||||
import org.acegisecurity.acls.MutableAclService;
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.domain.AclImpl;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentity;
|
||||
import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Random;
|
||||
@@ -35,8 +56,10 @@ import javax.sql.DataSource;
|
||||
public class DataSourcePopulator implements InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private DataSource dataSource;
|
||||
JdbcTemplate template;
|
||||
private MutableAclService mutableAclService;
|
||||
Random rnd = new Random();
|
||||
TransactionTemplate tt;
|
||||
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",
|
||||
@@ -47,91 +70,28 @@ public class DataSourcePopulator implements InitializingBean {
|
||||
"Edwards", "Gates", "Black", "Brown", "Gray", "Marwell", "Booch", "Johnson", "McTaggart", "Parklin",
|
||||
"Findlay", "Robinson", "Giugni", "Lang", "Chi", "Carmichael"
|
||||
};
|
||||
private int createEntities = 1000;
|
||||
private int createEntities = 50;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(dataSource, "dataSource required");
|
||||
Assert.notNull(mutableAclService, "mutableAclService required");
|
||||
Assert.notNull(template, "dataSource required");
|
||||
Assert.notNull(tt, "platformTransactionManager required");
|
||||
|
||||
JdbcTemplate template = new JdbcTemplate(dataSource);
|
||||
// Set a user account that will initially own all the created data
|
||||
Authentication authRequest = new UsernamePasswordAuthenticationToken("marissa", "koala",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_IGNORED")});
|
||||
SecurityContextHolder.getContext().setAuthentication(authRequest);
|
||||
|
||||
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
|
||||
|
||||
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');");
|
||||
}
|
||||
|
||||
"CREATE TABLE ACL_SID(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,PRINCIPAL BOOLEAN NOT NULL,SID VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_1 UNIQUE(SID,PRINCIPAL));");
|
||||
template.execute(
|
||||
"CREATE TABLE ACL_OBJECT_IDENTITY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) 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))");
|
||||
"CREATE TABLE ACL_CLASS(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,CLASS VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_2 UNIQUE(CLASS));");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (1, 'sample.contact.Contact:1', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
"CREATE TABLE ACL_OBJECT_IDENTITY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,OBJECT_ID_CLASS BIGINT NOT NULL,OBJECT_ID_IDENTITY BIGINT NOT NULL,PARENT_OBJECT BIGINT,OWNER_SID BIGINT,ENTRIES_INHERITING BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_3 UNIQUE(OBJECT_ID_CLASS,OBJECT_ID_IDENTITY),CONSTRAINT FOREIGN_FK_1 FOREIGN KEY(PARENT_OBJECT)REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_2 FOREIGN KEY(OBJECT_ID_CLASS)REFERENCES ACL_CLASS(ID),CONSTRAINT FOREIGN_FK_3 FOREIGN KEY(OWNER_SID)REFERENCES ACL_SID(ID));");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (2, 'sample.contact.Contact:2', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (3, 'sample.contact.Contact:3', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (4, 'sample.contact.Contact:4', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (5, 'sample.contact.Contact:5', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (6, 'sample.contact.Contact:6', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (7, 'sample.contact.Contact:7', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"INSERT INTO acl_object_identity VALUES (8, 'sample.contact.Contact:8', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');");
|
||||
template.execute(
|
||||
"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
|
||||
+ "', 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
|
||||
|
||||
String[] users = {"bill", "bob", "jane"}; // don't want to mess around with consistent sample data
|
||||
int[] permissions = {1, 2, 22};
|
||||
|
||||
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 + ");");
|
||||
|
||||
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
|
||||
+ ");");
|
||||
}
|
||||
}
|
||||
"CREATE TABLE ACL_ENTRY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,ACL_OBJECT_IDENTITY BIGINT NOT NULL,ACE_ORDER INT NOT NULL,SID BIGINT NOT NULL,MASK INTEGER NOT NULL,GRANTING BOOLEAN NOT NULL,AUDIT_SUCCESS BOOLEAN NOT NULL,AUDIT_FAILURE BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_4 UNIQUE(ACL_OBJECT_IDENTITY,ACE_ORDER),CONSTRAINT FOREIGN_FK_4 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_5 FOREIGN KEY(SID) REFERENCES ACL_SID(ID));");
|
||||
|
||||
template.execute(
|
||||
"CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);");
|
||||
@@ -139,6 +99,9 @@ public class DataSourcePopulator implements InitializingBean {
|
||||
"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 TABLE CONTACTS(ID BIGINT NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)");
|
||||
|
||||
/*
|
||||
Passwords encoded using MD5, NOT in Base64 format, with null as salt
|
||||
Encoded password for marissa is "koala"
|
||||
@@ -165,14 +128,100 @@ public class DataSourcePopulator implements InitializingBean {
|
||||
template.execute("INSERT INTO AUTHORITIES VALUES('bill','ROLE_USER');");
|
||||
template.execute("INSERT INTO AUTHORITIES VALUES('bob','ROLE_USER');");
|
||||
template.execute("INSERT INTO AUTHORITIES VALUES('jane','ROLE_USER');");
|
||||
|
||||
template.execute("INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');");
|
||||
template.execute("INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');");
|
||||
|
||||
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');");
|
||||
}
|
||||
|
||||
// Create acl_object_identity rows (and also acl_class rows as needed
|
||||
for (int i = 1; i < createEntities; i++) {
|
||||
final ObjectIdentity objectIdentity = new ObjectIdentityImpl(Contact.class, new Long(i));
|
||||
tt.execute(new TransactionCallback() {
|
||||
public Object doInTransaction(TransactionStatus arg0) {
|
||||
MutableAcl acl = mutableAclService.createAcl(objectIdentity);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Now grant some permissions
|
||||
grantPermissions(1, "marissa", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(2, "marissa", BasePermission.READ);
|
||||
grantPermissions(3, "marissa", BasePermission.READ);
|
||||
grantPermissions(3, "marissa", BasePermission.WRITE);
|
||||
grantPermissions(3, "marissa", BasePermission.DELETE);
|
||||
grantPermissions(4, "marissa", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(4, "dianne", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(4, "scott", BasePermission.READ);
|
||||
grantPermissions(5, "dianne", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(5, "dianne", BasePermission.READ);
|
||||
grantPermissions(6, "dianne", BasePermission.READ);
|
||||
grantPermissions(6, "dianne", BasePermission.WRITE);
|
||||
grantPermissions(6, "dianne", BasePermission.DELETE);
|
||||
grantPermissions(6, "scott", BasePermission.READ);
|
||||
grantPermissions(7, "scott", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(8, "dianne", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(8, "dianne", BasePermission.READ);
|
||||
grantPermissions(8, "scott", BasePermission.READ);
|
||||
grantPermissions(9, "scott", BasePermission.ADMINISTRATION);
|
||||
grantPermissions(9, "scott", BasePermission.READ);
|
||||
grantPermissions(9, "scott", BasePermission.WRITE);
|
||||
grantPermissions(9, "scott", BasePermission.DELETE);
|
||||
|
||||
// Now expressly change the owner of the first ten contacts
|
||||
// We have to do this last, because "marissa" owns all of them (doing it sooner would prevent ACL updates)
|
||||
// Note that ownership has no impact on permissions - they're separate (ownership only allows ACl editing)
|
||||
changeOwner(5, "dianne");
|
||||
changeOwner(6, "dianne");
|
||||
changeOwner(7, "scott");
|
||||
changeOwner(8, "dianne");
|
||||
changeOwner(9, "scott");
|
||||
|
||||
String[] users = {"bill", "bob", "jane"}; // don't want to mess around with consistent sample data
|
||||
Permission[] permissions = {BasePermission.ADMINISTRATION, BasePermission.READ, BasePermission.DELETE};
|
||||
|
||||
for (int i = 10; i < createEntities; i++) {
|
||||
String user = users[rnd.nextInt(users.length)];
|
||||
Permission permission = permissions[rnd.nextInt(permissions.length)];
|
||||
grantPermissions(i, user, permission);
|
||||
|
||||
String user2 = users[rnd.nextInt(users.length)];
|
||||
Permission permission2 = permissions[rnd.nextInt(permissions.length)];
|
||||
grantPermissions(i, user2, permission2);
|
||||
}
|
||||
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private void changeOwner(int contactNumber, String newOwnerUsername) {
|
||||
AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
|
||||
new Long(contactNumber)));
|
||||
acl.setOwner(new PrincipalSid(newOwnerUsername));
|
||||
updateAclInTransaction(acl);
|
||||
}
|
||||
|
||||
public int getCreateEntities() {
|
||||
return createEntities;
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
private void grantPermissions(int contactNumber, String recipientUsername, Permission permission) {
|
||||
AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
|
||||
new Long(contactNumber)));
|
||||
acl.insertAce(null, permission, new PrincipalSid(recipientUsername), true);
|
||||
updateAclInTransaction(acl);
|
||||
}
|
||||
|
||||
private String[] selectPerson() {
|
||||
@@ -187,6 +236,24 @@ public class DataSourcePopulator implements InitializingBean {
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
this.template = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
public void setMutableAclService(MutableAclService mutableAclService) {
|
||||
this.mutableAclService = mutableAclService;
|
||||
}
|
||||
|
||||
public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
|
||||
this.tt = new TransactionTemplate(platformTransactionManager);
|
||||
}
|
||||
|
||||
private void updateAclInTransaction(final MutableAcl acl) {
|
||||
tt.execute(new TransactionCallback() {
|
||||
public Object doInTransaction(TransactionStatus arg0) {
|
||||
mutableAclService.updateAcl(acl);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acls.AclService;
|
||||
import org.acegisecurity.acls.Permission;
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
import org.acegisecurity.acls.sid.Sid;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -44,42 +47,40 @@ import javax.servlet.http.HttpServletResponse;
|
||||
public class DeletePermissionController implements Controller, InitializingBean {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AclManager aclManager;
|
||||
private AclService aclService;
|
||||
private ContactManager contactManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
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 ContactManager getContactManager() {
|
||||
return contactManager;
|
||||
Assert.notNull(aclService, "An aclService implementation is required");
|
||||
}
|
||||
|
||||
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
// <c:param name="sid" value="${acl.sid.principal}"/><c:param name="permission" value="${acl.permission.mask}"/></c:url>">Del</A>
|
||||
int contactId = RequestUtils.getRequiredIntParameter(request, "contactId");
|
||||
String recipient = RequestUtils.getRequiredStringParameter(request, "recipient");
|
||||
String sid = RequestUtils.getRequiredStringParameter(request, "sid");
|
||||
int mask = RequestUtils.getRequiredIntParameter(request, "permission");
|
||||
|
||||
Contact contact = contactManager.getById(new Long(contactId));
|
||||
|
||||
contactManager.deletePermission(contact, recipient);
|
||||
Sid sidObject = new PrincipalSid(sid);
|
||||
Permission permission = BasePermission.buildFromMask(mask);
|
||||
|
||||
contactManager.deletePermission(contact, sidObject, permission);
|
||||
|
||||
Map model = new HashMap();
|
||||
model.put("contact", contact);
|
||||
model.put("recipient", recipient);
|
||||
model.put("sid", sidObject);
|
||||
model.put("permission", permission);
|
||||
|
||||
return new ModelAndView("deletePermission", "model", model);
|
||||
}
|
||||
|
||||
public void setAclManager(AclManager aclManager) {
|
||||
this.aclManager = aclManager;
|
||||
public void setAclService(AclService aclService) {
|
||||
this.aclService = aclService;
|
||||
}
|
||||
|
||||
public void setContactManager(ContactManager contact) {
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
<!-- ~~~~~~~~~~~~~~~~~~ "BEFORE INVOCATION" AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~ -->
|
||||
|
||||
<!-- ACL permission masks used by this application -->
|
||||
<bean id="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION</value></property>
|
||||
</bean>
|
||||
<bean id="org.acegisecurity.acl.basic.SimpleAclEntry.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acl.basic.SimpleAclEntry.READ</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.READ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.READ</value></property>
|
||||
</bean>
|
||||
<bean id="org.acegisecurity.acl.basic.SimpleAclEntry.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acl.basic.SimpleAclEntry.DELETE</value></property>
|
||||
<bean id="org.acegisecurity.acls.domain.BasePermission.DELETE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
|
||||
<property name="staticField"><value>org.acegisecurity.acls.domain.BasePermission.DELETE</value></property>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -37,41 +37,53 @@
|
||||
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter"/>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_READ configuration settings -->
|
||||
<bean id="aclContactReadVoter" class="org.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_READ</value></property>
|
||||
<bean id="aclContactReadVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_READ</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_DELETE configuration settings -->
|
||||
<bean id="aclContactDeleteVoter" class="org.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_DELETE</value></property>
|
||||
<bean id="aclContactDeleteVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_DELETE</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.DELETE"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision voter that reads ACL_CONTACT_ADMIN configuration settings -->
|
||||
<bean id="aclContactAdminVoter" class="org.acegisecurity.vote.BasicAclEntryVoter">
|
||||
<property name="processConfigAttribute"><value>ACL_CONTACT_ADMIN</value></property>
|
||||
<bean id="aclContactAdminVoter" class="org.acegisecurity.vote.AclEntryVoter">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<value>ACL_CONTACT_ADMIN</value>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- An access decision manager used by the business objects -->
|
||||
@@ -89,21 +101,49 @@
|
||||
|
||||
<!-- ========= ACCESS CONTROL LIST LOOKUP MANAGER DEFINITIONS ========= -->
|
||||
|
||||
<bean id="aclManager" class="org.acegisecurity.acl.AclProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref local="basicAclProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclProvider" class="org.acegisecurity.acl.basic.BasicAclProvider">
|
||||
<property name="basicAclDao"><ref local="basicAclExtendedDao"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="basicAclExtendedDao" class="org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl">
|
||||
<property name="dataSource"><ref bean="dataSource"/></property>
|
||||
</bean>
|
||||
<bean id="aclCache" class="org.acegisecurity.acls.jdbc.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName">
|
||||
<value>aclCache</value>
|
||||
</property>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.acegisecurity.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.acegisecurity.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.acegisecurity.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.acegisecurity.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.acegisecurity.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
</bean>
|
||||
|
||||
<!-- ============== "AFTER INTERCEPTION" AUTHORIZATION DEFINITIONS =========== -->
|
||||
|
||||
@@ -117,28 +157,31 @@
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_COLLECTION_READ configuration settings -->
|
||||
<bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
<bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<!-- Processes AFTER_ACL_READ configuration settings -->
|
||||
<bean id="afterAclRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider">
|
||||
<property name="aclManager"><ref local="aclManager"/></property>
|
||||
<property name="requirePermission">
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
|
||||
</list>
|
||||
</property>
|
||||
<bean id="afterAclRead" class="org.acegisecurity.afterinvocation.AclEntryAfterInvocationProvider">
|
||||
<constructor-arg>
|
||||
<ref bean="aclService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION"/>
|
||||
<ref local="org.acegisecurity.acls.domain.BasePermission.READ"/>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ================= METHOD INVOCATION AUTHORIZATION ==================== -->
|
||||
|
||||
<!-- getRandomContact() is public.
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
<value>org.hsqldb.jdbcDriver</value>
|
||||
</property>
|
||||
<property name="url">
|
||||
<value>jdbc:hsqldb:mem:contacts</value>
|
||||
<value>jdbc:hsqldb:mem:test</value>
|
||||
<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
|
||||
</property>
|
||||
<property name="username">
|
||||
<value>sa</value>
|
||||
@@ -46,7 +47,9 @@
|
||||
</bean>
|
||||
|
||||
<bean id="dataSourcePopulator" class="sample.contact.DataSourcePopulator">
|
||||
<property name="dataSource"><ref local="dataSource"/></property>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="mutableAclService" ref="aclService"/>
|
||||
<property name="platformTransactionManager" ref="transactionManager"/>
|
||||
</bean>
|
||||
|
||||
<bean id="contactDao" class="sample.contact.ContactDaoSpring">
|
||||
@@ -66,7 +69,7 @@
|
||||
|
||||
<bean id="contactManagerTarget" class="sample.contact.ContactManagerBackend">
|
||||
<property name="contactDao"><ref local="contactDao"/></property>
|
||||
<property name="basicAclExtendedDao"><ref bean="basicAclExtendedDao"/></property>
|
||||
<property name="mutableAclService"><ref bean="aclService"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
|
||||
<bean id="adminPermissionController" class="sample.contact.AdminPermissionController">
|
||||
<property name="contactManager"><ref bean="contactManager"/></property>
|
||||
<property name="aclManager"><ref bean="aclManager"/></property>
|
||||
<property name="aclService"><ref bean="aclService"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="deletePermissionController" class="sample.contact.DeletePermissionController">
|
||||
<property name="contactManager"><ref bean="contactManager"/></property>
|
||||
<property name="aclManager"><ref bean="aclManager"/></property>
|
||||
<property name="aclService"><ref bean="aclService"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<%@ page import="org.acegisecurity.acl.basic.SimpleAclEntry" %>
|
||||
<%@ include file="/WEB-INF/jsp/include.jsp" %>
|
||||
|
||||
<html>
|
||||
@@ -11,27 +10,17 @@
|
||||
</code>
|
||||
<P>
|
||||
<table cellpadding=3 border=0>
|
||||
<c:forEach var="acl" items="${model.acls}">
|
||||
<c:if test="${acl.class.name eq 'org.acegisecurity.acl.basic.SimpleAclEntry'}">
|
||||
<c:forEach var="acl" items="${model.acl.entries}">
|
||||
<tr>
|
||||
<td>
|
||||
<code>
|
||||
<%
|
||||
SimpleAclEntry simpleAcl = ((SimpleAclEntry) pageContext.getAttribute("acl"));
|
||||
String permissionBlock = simpleAcl.printPermissionsBlock();
|
||||
%>
|
||||
<%= permissionBlock %>
|
||||
[<c:out value="${acl.mask}"/>]
|
||||
<c:out value="${acl.recipient}"/>
|
||||
<c:out value="${acl}"/>
|
||||
</code>
|
||||
</td>
|
||||
<td>
|
||||
<!-- This application doesn't use ACL inheritance, so we can safely use
|
||||
the model's contact and know it was directly assigned the ACL -->
|
||||
<A HREF="<c:url value="deletePermission.htm"><c:param name="contactId" value="${model.contact.id}"/><c:param name="recipient" value="${acl.recipient}"/></c:url>">Del</A>
|
||||
<A HREF="<c:url value="deletePermission.htm"><c:param name="contactId" value="${model.contact.id}"/><c:param name="sid" value="${acl.sid.principal}"/><c:param name="permission" value="${acl.permission.mask}"/></c:url>">Del</A>
|
||||
</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
</c:forEach>
|
||||
</table>
|
||||
<p><a href="<c:url value="addPermission.htm"><c:param name="contactId" value="${model.contact.id}"/></c:url>">Add Permission</a> <a href="<c:url value="index.htm"/>">Manage</a>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<%@ page import="org.acegisecurity.acl.basic.SimpleAclEntry" %>
|
||||
<%@ include file="/WEB-INF/jsp/include.jsp" %>
|
||||
|
||||
<html>
|
||||
@@ -11,8 +10,11 @@
|
||||
</code>
|
||||
<P>
|
||||
<code>
|
||||
<c:out value="${model.recipient}"/>
|
||||
<c:out value="${model.sid}"/>
|
||||
</code>
|
||||
<code>
|
||||
<c:out value="${model.permission}"/>
|
||||
</code>
|
||||
<p><a href="<c:url value="index.htm"/>">Manage</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
<td>
|
||||
<c:out value="${contact.email}"/>
|
||||
</td>
|
||||
<authz:acl domainObject="${contact}" hasPermission="16,1">
|
||||
<authz:accesscontrollist domainObject="${contact}" hasPermission="8,16">
|
||||
<td><A HREF="<c:url value="del.htm"><c:param name="contactId" value="${contact.id}"/></c:url>">Del</A></td>
|
||||
</authz:acl>
|
||||
<authz:acl domainObject="${contact}" hasPermission="1">
|
||||
</authz:accesscontrollist>
|
||||
<authz:accesscontrollist domainObject="${contact}" hasPermission="16">
|
||||
<td><A HREF="<c:url value="adminPermission.htm"><c:param name="contactId" value="${contact.id}"/></c:url>">Admin Permission</A></td>
|
||||
</authz:acl>
|
||||
</authz:accesscontrollist>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package sample.contact;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.acegisecurity.context.SecurityContextImpl;
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.test.AbstractTransactionalSpringContextTests;
|
||||
|
||||
/**
|
||||
* Provides simplified access to the <code>ContactManager</code> bean and
|
||||
* convenience test support methods.
|
||||
*
|
||||
* @author David Leal
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public abstract class AbstractContactsSampleTest extends AbstractTransactionalSpringContextTests {
|
||||
|
||||
protected ContactManager contactManager;
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
|
||||
return new String[] { "applicationContext-common-authorization.xml",
|
||||
"applicationContext-common-business.xml",
|
||||
"applicationContext-contacts-test.xml" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the first <code>Contact</code> of the exact name specified.
|
||||
*
|
||||
* <p>
|
||||
* Uses the {@link ContactManager#getAll()} method.
|
||||
* </p>
|
||||
*
|
||||
* @param id
|
||||
* Identify of the contact to locate (must be an exact match)
|
||||
*
|
||||
* @return the domain or <code>null</code> if not found
|
||||
*/
|
||||
protected Contact getContact(String id) {
|
||||
List contacts = contactManager.getAll();
|
||||
Iterator iter = contacts.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Contact contact = (Contact) iter.next();
|
||||
|
||||
if (contact.getId().equals(id)) {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void assertContainsContact(String id, List contacts) {
|
||||
Iterator iter = contacts.iterator();
|
||||
System.out.println(contacts);
|
||||
while (iter.hasNext()) {
|
||||
Contact contact = (Contact) iter.next();
|
||||
|
||||
if (contact.getId().toString().equals(id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fail("List of contacts should have contained: " + id);
|
||||
}
|
||||
|
||||
protected void assertNotContainsContact(String id, List contacts) {
|
||||
Iterator iter = contacts.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Contact domain = (Contact) iter.next();
|
||||
|
||||
if (domain.getId().toString().equals(id)) {
|
||||
fail("List of contact should NOT (but did) contain: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void makeActiveUser(String username) {
|
||||
String password = "";
|
||||
|
||||
if ("marissa".equals(username)) {
|
||||
password = "koala";
|
||||
} else if ("dianne".equals(username)) {
|
||||
password = "emu";
|
||||
} else if ("scott".equals(username)) {
|
||||
password = "wombat";
|
||||
} else if ("peter".equals(username)) {
|
||||
password = "opal";
|
||||
}
|
||||
|
||||
Authentication authRequest = new UsernamePasswordAuthenticationToken(
|
||||
username, password);
|
||||
SecurityContextImpl secureContext = new SecurityContextImpl();
|
||||
secureContext.setAuthentication(authRequest);
|
||||
SecurityContextHolder.setContext(secureContext);
|
||||
}
|
||||
|
||||
protected void onTearDownInTransaction() {
|
||||
destroySecureContext();
|
||||
}
|
||||
|
||||
private static void destroySecureContext() {
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl());
|
||||
}
|
||||
|
||||
public void setContactManager(ContactManager contactManager) {
|
||||
this.contactManager = contactManager;
|
||||
}
|
||||
}
|
||||
@@ -12,68 +12,174 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.contact;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.acls.domain.BasePermission;
|
||||
import org.acegisecurity.acls.sid.PrincipalSid;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
|
||||
import org.springframework.test.AbstractTransactionalSpringContextTests;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link
|
||||
* com.acegitech.dns.domain.DomainManager#findAllDomainsLike(String)}.
|
||||
* Tests {@link ContactManager}.
|
||||
*
|
||||
* @author David Leal
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class GetAllContactsTests extends AbstractContactsSampleTest {
|
||||
//~ Methods ================================================================
|
||||
public class GetAllContactsTests extends AbstractTransactionalSpringContextTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
public void testFindAllDomainsLikeAsDianne() {
|
||||
protected ContactManager contactManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void assertContainsContact(String id, List contacts) {
|
||||
Iterator iter = contacts.iterator();
|
||||
System.out.println(contacts);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Contact contact = (Contact) iter.next();
|
||||
|
||||
if (contact.getId().toString().equals(id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fail("List of contacts should have contained: " + id);
|
||||
}
|
||||
|
||||
protected void assertNotContainsContact(String id, List contacts) {
|
||||
Iterator iter = contacts.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Contact domain = (Contact) iter.next();
|
||||
|
||||
if (domain.getId().toString().equals(id)) {
|
||||
fail("List of contact should NOT (but did) contain: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void destroySecureContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
|
||||
|
||||
return new String[] {
|
||||
"applicationContext-common-authorization.xml", "applicationContext-common-business.xml",
|
||||
"applicationContext-contacts-test.xml"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the first <code>Contact</code> of the exact name specified.<p>Uses the {@link
|
||||
* ContactManager#getAll()} method.</p>
|
||||
*
|
||||
* @param id Identify of the contact to locate (must be an exact match)
|
||||
*
|
||||
* @return the domain or <code>null</code> if not found
|
||||
*/
|
||||
protected Contact getContact(String id) {
|
||||
List contacts = contactManager.getAll();
|
||||
Iterator iter = contacts.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Contact contact = (Contact) iter.next();
|
||||
|
||||
if (contact.getId().equals(id)) {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void makeActiveUser(String username) {
|
||||
String password = "";
|
||||
|
||||
if ("marissa".equals(username)) {
|
||||
password = "koala";
|
||||
} else if ("dianne".equals(username)) {
|
||||
password = "emu";
|
||||
} else if ("scott".equals(username)) {
|
||||
password = "wombat";
|
||||
} else if ("peter".equals(username)) {
|
||||
password = "opal";
|
||||
}
|
||||
|
||||
Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password);
|
||||
SecurityContextHolder.getContext().setAuthentication(authRequest);
|
||||
}
|
||||
|
||||
protected void onTearDownInTransaction() {
|
||||
destroySecureContext();
|
||||
}
|
||||
|
||||
public void setContactManager(ContactManager contactManager) {
|
||||
this.contactManager = contactManager;
|
||||
}
|
||||
|
||||
public void testDianne() {
|
||||
makeActiveUser("dianne"); // has ROLE_USER
|
||||
|
||||
|
||||
List contacts = contactManager.getAll();
|
||||
assertEquals(4, contacts.size());
|
||||
|
||||
|
||||
assertContainsContact(Long.toString(4), contacts);
|
||||
assertContainsContact(Long.toString(5), contacts);
|
||||
assertContainsContact(Long.toString(6), contacts);
|
||||
assertContainsContact(Long.toString(8), contacts);
|
||||
|
||||
|
||||
assertNotContainsContact(Long.toString(1), contacts);
|
||||
assertNotContainsContact(Long.toString(2), contacts);
|
||||
assertNotContainsContact(Long.toString(3), contacts);
|
||||
|
||||
}
|
||||
|
||||
public void testFindAllDomainsLikeAsMarissa() {
|
||||
public void testMarissa() {
|
||||
makeActiveUser("marissa"); // has ROLE_SUPERVISOR
|
||||
|
||||
List contacts = contactManager.getAll();
|
||||
|
||||
|
||||
List contacts = contactManager.getAll();
|
||||
|
||||
assertEquals(4, contacts.size());
|
||||
|
||||
|
||||
assertContainsContact(Long.toString(1), contacts);
|
||||
assertContainsContact(Long.toString(2), contacts);
|
||||
assertContainsContact(Long.toString(3), contacts);
|
||||
assertContainsContact(Long.toString(4), contacts);
|
||||
|
||||
assertNotContainsContact(Long.toString(5), contacts);
|
||||
|
||||
|
||||
assertNotContainsContact(Long.toString(5), contacts);
|
||||
|
||||
Contact c1 = contactManager.getById(new Long(4));
|
||||
|
||||
contactManager.deletePermission(c1, new PrincipalSid("bob"), BasePermission.ADMINISTRATION);
|
||||
}
|
||||
|
||||
public void testFindAllDomainsLikeAsScott() {
|
||||
public void testScott() {
|
||||
makeActiveUser("scott"); // has ROLE_USER
|
||||
|
||||
|
||||
List contacts = contactManager.getAll();
|
||||
|
||||
assertEquals(5, contacts.size());
|
||||
|
||||
|
||||
assertEquals(5, contacts.size());
|
||||
|
||||
assertContainsContact(Long.toString(4), contacts);
|
||||
assertContainsContact(Long.toString(6), contacts);
|
||||
assertContainsContact(Long.toString(7), contacts);
|
||||
assertContainsContact(Long.toString(8), contacts);
|
||||
assertContainsContact(Long.toString(9), contacts);
|
||||
|
||||
assertNotContainsContact(Long.toString(1), contacts);
|
||||
|
||||
|
||||
assertNotContainsContact(Long.toString(1), contacts);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user