Refactor Contacts Sample to use new ACL security.

This commit is contained in:
Ben Alex
2004-11-15 03:25:39 +00:00
parent bc9a599bf7
commit 6e687d47d4
39 changed files with 1788 additions and 1044 deletions

View File

@@ -0,0 +1,59 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
/**
* Model object for add permission use case.
*
* @author Ben Alex
* @version $Id$
*/
public class AddPermission {
//~ Instance fields ========================================================
public Contact contact;
public Integer permission = new Integer(SimpleAclEntry.NOTHING);
public String recipient;
//~ Methods ================================================================
public void setContact(Contact contact) {
this.contact = contact;
}
public Contact getContact() {
return contact;
}
public void setPermission(Integer permission) {
this.permission = permission;
}
public Integer getPermission() {
return permission;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getRecipient() {
return recipient;
}
}

View File

@@ -0,0 +1,162 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller for adding an ACL permission.
*
* @author Ben Alex
* @version $Id$
*/
public class AddPermissionController extends SimpleFormController
implements InitializingBean {
//~ Instance fields ========================================================
private ContactManager contactManager;
//~ Methods ================================================================
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException(
"A ContactManager implementation is required");
}
}
protected ModelAndView disallowDuplicateFormSubmission(
HttpServletRequest request, HttpServletResponse response)
throws Exception {
BindException errors = new BindException(formBackingObject(request),
getCommandName());
errors.reject("err.duplicateFormSubmission",
"Duplicate form submission.");
return showForm(request, response, errors);
}
protected Object formBackingObject(HttpServletRequest request)
throws Exception {
int contactId = RequestUtils.getRequiredIntParameter(request,
"contactId");
Contact contact = contactManager.getById(new Integer(contactId));
AddPermission addPermission = new AddPermission();
addPermission.setContact(contact);
return addPermission;
}
protected ModelAndView handleInvalidSubmit(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return disallowDuplicateFormSubmission(request, response);
}
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
AddPermission addPermission = (AddPermission) command;
try {
contactManager.addPermission(addPermission.getContact(),
addPermission.getRecipient(), addPermission.getPermission());
} catch (DataAccessException existingPermission) {
existingPermission.printStackTrace();
errors.rejectValue("recipient", "err.recipientExistsForContact",
"This recipient already has permissions to this contact.");
return showForm(request, response, errors);
}
return new ModelAndView(new RedirectView(getSuccessView()));
}
protected Map referenceData(HttpServletRequest request)
throws Exception {
Map model = new HashMap();
model.put("recipients", listRecipients(request));
model.put("permissions", listPermissions(request));
return model;
}
private Map listPermissions(HttpServletRequest request) {
Map map = new LinkedHashMap();
map.put(new Integer(SimpleAclEntry.NOTHING),
getApplicationContext().getMessage("select.none", null, "None",
request.getLocale()));
map.put(new Integer(SimpleAclEntry.ADMINISTRATION),
getApplicationContext().getMessage("select.administer", null,
"Administer", request.getLocale()));
map.put(new Integer(SimpleAclEntry.READ),
getApplicationContext().getMessage("select.read", null, "Read",
request.getLocale()));
map.put(new Integer(SimpleAclEntry.DELETE),
getApplicationContext().getMessage("select.delete", null, "Delete",
request.getLocale()));
map.put(new Integer(SimpleAclEntry.READ_WRITE_DELETE),
getApplicationContext().getMessage("select.readWriteDelete", null,
"Read+Write+Delete", request.getLocale()));
return map;
}
private Map listRecipients(HttpServletRequest request) {
Map map = new LinkedHashMap();
map.put("",
getApplicationContext().getMessage("select.pleaseSelect", null,
"-- please select --", request.getLocale()));
Iterator recipientsIter = contactManager.getAllRecipients().iterator();
while (recipientsIter.hasNext()) {
String recipient = (String) recipientsIter.next();
map.put(recipient, recipient);
}
return map;
}
}

View File

@@ -0,0 +1,66 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
/**
* Validates {@link AddPermission}.
*
* @author Ben Alex
* @version $Id$
*/
public class AddPermissionValidator implements Validator {
//~ Methods ================================================================
public boolean supports(Class clazz) {
return clazz.equals(AddPermission.class);
}
public void validate(Object obj, Errors errors) {
AddPermission addPermission = (AddPermission) obj;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "permission",
"err.permission", "Permission is required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipient",
"err.recipient", "Recipient is required");
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)) {
errors.rejectValue("permission", "err.permission.invalid",
"The indicated permission is invalid.");
}
}
if (addPermission.getRecipient() != null) {
if (addPermission.getRecipient().length() > 100) {
errors.rejectValue("recipient", "err.recipient.length",
"The recipient is too long (maximum 100 characters).");
}
}
}
}

View File

@@ -0,0 +1,92 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.AclEntry;
import net.sf.acegisecurity.acl.AclManager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller for "administer" index page.
*
* @author Ben Alex
* @version $Id$
*/
public class AdminPermissionController implements Controller, InitializingBean {
//~ Instance fields ========================================================
private AclManager aclManager;
private ContactManager contactManager;
//~ Methods ================================================================
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public AclManager getAclManager() {
return aclManager;
}
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException(
"A ContactManager implementation is required");
}
if (aclManager == null) {
throw new IllegalArgumentException(
"An aclManager implementation is required");
}
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
int id = RequestUtils.getRequiredIntParameter(request, "contactId");
Contact contact = contactManager.getById(new Integer(id));
AclEntry[] acls = aclManager.getAcls(contact);
Map model = new HashMap();
model.put("contact", contact);
model.put("acls", acls);
return new ModelAndView("adminPermission", "model", model);
}
}

View File

@@ -25,12 +25,13 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Demonstrates accessing the {@link ContactManager} via remoting protocols.
*
*
* <P>
* Based on Spring's JPetStore sample, written by Juergen Hoeller.
* </p>
@@ -92,32 +93,34 @@ public class ClientApplication {
System.out.println("Found; Trying to setPassword(String) to "
+ password);
} catch (NoSuchMethodException ignored) {}
catch (IllegalAccessException ignored) {}
catch (InvocationTargetException ignored) {}
catch (IllegalAccessException ignored) {}
catch (InvocationTargetException ignored) {}
stopWatch.start(beanName);
Contact[] contacts = null;
List contacts = null;
for (int i = 0; i < nrOfCalls; i++) {
contacts = remoteContactManager.getAllByOwner(forOwner);
contacts = remoteContactManager.getAll();
}
stopWatch.stop();
if (contacts.length != 0) {
for (int i = 0; i < contacts.length; i++) {
System.out.println("Contact " + i + ": "
+ contacts[i].toString());
if (contacts.size() == 0) {
Iterator listIterator = contacts.iterator();
while (listIterator.hasNext()) {
Contact contact = (Contact) listIterator.next();
System.out.println("Contact: " + contact.toString());
}
} else {
System.out.println("No contacts found belonging to owner");
System.out.println(
"No contacts found which this user has permission to");
}
System.out.println();
System.out.println(stopWatch.prettyPrint());
}
System.out.println(stopWatch.prettyPrint());
}
public static void main(String[] args) {

View File

@@ -17,10 +17,6 @@ package sample.contact;
/**
* Represents a contact.
*
* <P>
* <code>id</code> and <code>owner</code> are immutable.
* </p>
*
* @author Ben Alex
* @version $Id$
@@ -31,20 +27,15 @@ public class Contact {
private Integer id;
private String email;
private String name;
private String owner;
//~ Constructors ===========================================================
public Contact(Integer id, String name, String email, String owner) {
this.id = id;
public Contact(String name, String email) {
this.name = name;
this.email = email;
this.owner = owner;
}
private Contact() {
super();
}
public Contact() {}
//~ Methods ================================================================
@@ -66,6 +57,10 @@ public class Contact {
return email;
}
public void setId(Integer id) {
this.id = id;
}
/**
* DOCUMENT ME!
*
@@ -93,22 +88,12 @@ public class Contact {
return name;
}
/**
* DOCUMENT ME!
*
* @return Returns the owner.
*/
public String getOwner() {
return owner;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString() + ": ");
sb.append("Id: " + this.getId() + "; ");
sb.append("Name: " + this.getName() + "; ");
sb.append("Email: " + this.getEmail() + "; ");
sb.append("Owner: " + this.getOwner());
sb.append("Email: " + this.getEmail());
return sb.toString();
}

View File

@@ -0,0 +1,75 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.util.List;
/**
* Provides access to the application's persistence layer.
*
* @author Ben Alex
* @version $Id$
*/
public interface ContactDao {
//~ Methods ================================================================
public Contact getById(Integer id);
public void create(Contact contact);
/**
* Creates an acl_object_identity for the specified Contact.
*
* @param contact to create an entry for
*
* @return the acl_object_identity identifier
*/
public Integer createAclObjectIdentity(Contact contact);
/**
* Given an acl_object_identitiy identifier, grant the specified recipient
* read access to the object identified.
*
* @param aclObjectIdentity to assign the read permission against
* @param recipient receiving the permission
* @param permission to assign
*/
public void createPermission(Integer aclObjectIdentity, String recipient,
int permission);
public void delete(Integer contactId);
public void deletePermission(Integer aclObjectIdentity, String recipient);
public List findAll();
public List findAllPrincipals();
public List findAllRoles();
/**
* Obtains the acl_object_identity for the specified Contact.
*
* @param contact to locate an acl_object_identity for
*
* @return the acl_object_identity identifier or <code>null</code> if not
* found
*/
public Integer lookupAclObjectIdentity(Contact contact);
public void update(Contact contact);
}

View File

@@ -0,0 +1,309 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import javax.sql.DataSource;
/**
* Base implementation of {@link ContactDao} that uses Spring JDBC services.
*
* @author Ben Alex
* @version $Id$
*/
public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao {
//~ Instance fields ========================================================
private AclObjectIdentityByObjectIdentityQuery aclObjectIdentityByObjectIdentityQuery;
private AclObjectIdentityInsert aclObjectIdentityInsert;
private ContactDelete contactDelete;
private ContactInsert contactInsert;
private ContactUpdate contactUpdate;
private ContactsAllQuery contactsAllQuery;
private ContactsByIdQuery contactsByIdQuery;
private PermissionDelete permissionDelete;
private PermissionInsert permissionInsert;
private PrincipalsAllQuery principalsAllQuery;
private RolesAllQuery rolesAllQuery;
//~ Methods ================================================================
public Contact getById(Integer id) {
List list = contactsByIdQuery.execute(id.intValue());
if (list.size() == 0) {
return null;
} else {
return (Contact) list.get(0);
}
}
public void create(Contact contact) {
contactInsert.insert(contact);
}
public Integer createAclObjectIdentity(Contact contact) {
return new Integer(aclObjectIdentityInsert.insert(makeObjectIdentity(
contact), null, SimpleAclEntry.class.getName()));
}
public void createPermission(Integer aclObjectIdentity, String recipient,
int permission) {
permissionInsert.insert(aclObjectIdentity, recipient,
new Integer(permission));
}
public void delete(Integer contactId) {
contactDelete.delete(contactId);
}
public void deletePermission(Integer aclObjectIdentity, String recipient) {
permissionDelete.delete(aclObjectIdentity, recipient);
}
public List findAll() {
return contactsAllQuery.execute();
}
public List findAllPrincipals() {
return principalsAllQuery.execute();
}
public List findAllRoles() {
return rolesAllQuery.execute();
}
public Integer lookupAclObjectIdentity(Contact contact) {
List list = aclObjectIdentityByObjectIdentityQuery.execute(makeObjectIdentity(
contact));
if (list.size() == 0) {
return null;
} else {
return (Integer) list.get(0);
}
}
public void update(Contact contact) {
contactUpdate.update(contact);
}
protected void initDao() throws Exception {
contactInsert = new ContactInsert(getDataSource());
contactUpdate = new ContactUpdate(getDataSource());
contactDelete = new ContactDelete(getDataSource());
aclObjectIdentityInsert = new AclObjectIdentityInsert(getDataSource());
permissionInsert = new PermissionInsert(getDataSource());
permissionDelete = new PermissionDelete(getDataSource());
contactsAllQuery = new ContactsAllQuery(getDataSource());
principalsAllQuery = new PrincipalsAllQuery(getDataSource());
rolesAllQuery = new RolesAllQuery(getDataSource());
contactsByIdQuery = new ContactsByIdQuery(getDataSource());
aclObjectIdentityByObjectIdentityQuery = new AclObjectIdentityByObjectIdentityQuery(getDataSource());
}
private String makeObjectIdentity(Contact contact) {
return contact.getClass().getName() + ":" + contact.getId();
}
//~ Inner Classes ==========================================================
protected class AclObjectIdentityByObjectIdentityQuery
extends MappingSqlQuery {
protected AclObjectIdentityByObjectIdentityQuery(DataSource ds) {
super(ds,
"SELECT id FROM acl_object_identity WHERE object_identity = ?");
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
return new Integer(rs.getInt("id"));
}
}
protected class AclObjectIdentityInsert extends SqlUpdate {
protected AclObjectIdentityInsert(DataSource ds) {
super(ds, "INSERT INTO acl_object_identity VALUES (?, ?, ?, ?)");
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected int insert(String objectIdentity,
Integer parentAclObjectIdentity, String aclClass) {
Object[] objs = new Object[] {null, objectIdentity, parentAclObjectIdentity, aclClass};
super.update(objs);
return getJdbcTemplate().queryForInt("call identity()");
}
}
protected class ContactDelete extends SqlUpdate {
protected ContactDelete(DataSource ds) {
super(ds, "DELETE FROM contacts WHERE id = ?");
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected void delete(Integer contactId) {
super.update(contactId.intValue());
}
}
protected class ContactInsert extends SqlUpdate {
protected ContactInsert(DataSource ds) {
super(ds, "INSERT INTO contacts VALUES (?, ?, ?)");
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected void insert(Contact contact) {
Object[] objs = new Object[] {contact.getId(), contact.getName(), contact
.getEmail()};
super.update(objs);
}
}
protected class ContactUpdate extends SqlUpdate {
protected ContactUpdate(DataSource ds) {
super(ds,
"UPDATE contacts SET contact_name = ?, address = ? WHERE id = ?");
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected void update(Contact contact) {
Object[] objs = new Object[] {contact.getName(), contact.getEmail(), contact
.getId()};
super.update(objs);
}
}
protected class ContactsAllQuery extends MappingSqlQuery {
protected ContactsAllQuery(DataSource ds) {
super(ds, "SELECT id, contact_name, email FROM contacts ORDER BY id");
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
Contact contact = new Contact();
contact.setId(new Integer(rs.getInt("id")));
contact.setName(rs.getString("contact_name"));
contact.setEmail(rs.getString("email"));
return contact;
}
}
protected class ContactsByIdQuery extends MappingSqlQuery {
protected ContactsByIdQuery(DataSource ds) {
super(ds,
"SELECT id, contact_name, email FROM contacts WHERE id = ? ORDER BY id");
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
Contact contact = new Contact();
contact.setId(new Integer(rs.getInt("id")));
contact.setName(rs.getString("contact_name"));
contact.setEmail(rs.getString("email"));
return contact;
}
}
protected class PermissionDelete extends SqlUpdate {
protected PermissionDelete(DataSource ds) {
super(ds,
"DELETE FROM acl_permission WHERE ACL_OBJECT_IDENTITY = ? AND RECIPIENT = ?");
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected void delete(Integer aclObjectIdentity, String recipient) {
super.update(new Object[] {aclObjectIdentity, recipient});
}
}
protected class PermissionInsert extends SqlUpdate {
protected PermissionInsert(DataSource ds) {
super(ds, "INSERT INTO acl_permission VALUES (?, ?, ?, ?);");
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected int insert(Integer aclObjectIdentity, String recipient,
Integer mask) {
Object[] objs = new Object[] {null, aclObjectIdentity, recipient, mask};
super.update(objs);
return getJdbcTemplate().queryForInt("call identity()");
}
}
protected class PrincipalsAllQuery extends MappingSqlQuery {
protected PrincipalsAllQuery(DataSource ds) {
super(ds, "SELECT username FROM users ORDER BY username");
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
return rs.getString("username");
}
}
protected class RolesAllQuery extends MappingSqlQuery {
protected RolesAllQuery(DataSource ds) {
super(ds,
"SELECT DISTINCT authority FROM authorities ORDER BY authority");
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
return rs.getString("authority");
}
}
}

View File

@@ -15,8 +15,11 @@
package sample.contact;
import java.util.List;
/**
* Iterface for the application's business object.
* Interface for the application's services layer.
*
* @author Ben Alex
* @version $Id$
@@ -24,15 +27,20 @@ package sample.contact;
public interface ContactManager {
//~ Methods ================================================================
public Contact[] getAllByOwner(String owner);
public List getAll();
public List getAllRecipients();
public Contact getById(Integer id);
public Integer getNextId();
public Contact getRandomContact();
public void addPermission(Contact contact, String recipient,
Integer permission);
public void create(Contact contact);
public void delete(Contact contact);
public void save(Contact contact);
public void deletePermission(Contact contact, String recipient);
}

View File

@@ -15,159 +15,105 @@
package sample.contact;
import java.util.HashMap;
import java.util.Iterator;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.beans.factory.InitializingBean;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
/**
* Backend business object that manages the contacts.
*
* <P>
* As a backend, it never faces the public callers. It is always accessed via
* the {@link ContactManagerFacade}.
* </p>
*
* <P>
* This facade approach is not really necessary in this application, and is
* done simply to demonstrate granting additional authorities via the
* <code>RunAsManager</code>.
* </p>
* Concrete implementation of {@link ContactManager}.
*
* @author Ben Alex
* @version $Id$
*/
public class ContactManagerBackend implements ContactManager {
public class ContactManagerBackend implements ContactManager, InitializingBean {
//~ Instance fields ========================================================
private Map contacts;
//~ Constructors ===========================================================
public ContactManagerBackend() {
this.contacts = new HashMap();
save(new Contact(this.getNextId(), "John Smith", "john@somewhere.com",
"marissa"));
save(new Contact(this.getNextId(), "Michael Citizen",
"michael@xyz.com", "marissa"));
save(new Contact(this.getNextId(), "Joe Bloggs", "joe@demo.com",
"marissa"));
save(new Contact(this.getNextId(), "Karen Sutherland",
"karen@sutherland.com", "dianne"));
save(new Contact(this.getNextId(), "Mitchell Howard",
"mitchell@abcdef.com", "dianne"));
save(new Contact(this.getNextId(), "Rose Costas", "rose@xyz.com",
"scott"));
save(new Contact(this.getNextId(), "Amanda Smith", "amanda@abcdef.com",
"scott"));
}
private ContactDao contactDao;
private int counter = 100;
//~ Methods ================================================================
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param owner DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact[] getAllByOwner(String owner) {
List list = new Vector();
Iterator iter = this.contacts.keySet().iterator();
while (iter.hasNext()) {
Integer contactId = (Integer) iter.next();
Contact contact = (Contact) this.contacts.get(contactId);
if (contact.getOwner().equals(owner)) {
list.add(contact);
}
}
if (list.size() == 0) {
return null;
} else {
return (Contact[]) list.toArray(new Contact[list.size()]);
}
public List getAll() {
return contactDao.findAll();
}
public List getAllRecipients() {
List list = contactDao.findAllPrincipals();
list.addAll(contactDao.findAllRoles());
return list;
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param id DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact getById(Integer id) {
return (Contact) this.contacts.get(id);
return contactDao.getById(id);
}
public void setContactDao(ContactDao contactDao) {
this.contactDao = contactDao;
}
public ContactDao getContactDao() {
return contactDao;
}
/**
* Public method
*
* @return DOCUMENT ME!
*/
public Integer getNextId() {
int max = 0;
Iterator iter = this.contacts.keySet().iterator();
while (iter.hasNext()) {
Integer id = (Integer) iter.next();
if (id.intValue() > max) {
max = id.intValue();
}
}
return new Integer(max + 1);
}
/**
* This is a public method, meaning a client could call this method
* directly (ie not via a facade). If this was an issue, the public method
* on the facade should not be public but secure. Quite possibly an
* AnonymousAuthenticationToken and associated provider could be used on a
* secure method, thus allowing a RunAsManager to protect the backend.
* This is a public method.
*
* @return DOCUMENT ME!
*/
public Contact getRandomContact() {
Random rnd = new Random();
int getNumber = rnd.nextInt(this.contacts.size()) + 1;
Iterator iter = this.contacts.keySet().iterator();
int i = 0;
List contacts = contactDao.findAll();
int getNumber = rnd.nextInt(contacts.size());
while (iter.hasNext()) {
i++;
return (Contact) contacts.get(getNumber);
}
Integer id = (Integer) iter.next();
public void addPermission(Contact contact, String recipient,
Integer permission) {
Integer aclObjectIdentity = contactDao.lookupAclObjectIdentity(contact);
contactDao.createPermission(aclObjectIdentity, recipient,
permission.intValue());
}
if (i == getNumber) {
return (Contact) this.contacts.get(id);
}
public void afterPropertiesSet() throws Exception {
if (contactDao == null) {
throw new IllegalArgumentException("contactDao required");
}
return null;
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param contact DOCUMENT ME!
*/
public void create(Contact contact) {
// Create the Contact itself
contact.setId(new Integer(counter++));
contactDao.create(contact);
// Grant the current principal access to the contact
Integer aclObjectIdentity = contactDao.createAclObjectIdentity(contact);
contactDao.createPermission(aclObjectIdentity, getUsername(),
SimpleAclEntry.ADMINISTRATION);
}
public void delete(Contact contact) {
this.contacts.remove(contact.getId());
contactDao.delete(contact.getId());
}
/**
* Security system expects ROLE_RUN_AS_SERVER
*
* @param contact DOCUMENT ME!
*/
public void save(Contact contact) {
this.contacts.put(contact.getId(), contact);
public void deletePermission(Contact contact, String recipient) {
Integer aclObjectIdentity = contactDao.lookupAclObjectIdentity(contact);
contactDao.deletePermission(aclObjectIdentity, recipient);
}
public void update(Contact contact) {
contactDao.update(contact);
}
protected String getUsername() {
return ((SecureContext) ContextHolder.getContext()).getAuthentication()
.getPrincipal().toString();
}
}

View File

@@ -1,149 +0,0 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.beans.factory.InitializingBean;
/**
* This is the public facade to the application's main business object.
*
* <p>
* Used to demonstrate security configuration in a multi-tier application. Most
* methods of this class are secured via standard security definitions in the
* bean context. There is one method that supplements these security checks.
* All methods delegate to a "backend" object. The "backend" object relies on
* the facade's <code>RunAsManager</code> assigning an additional
* <code>GrantedAuthority</code> that is required to call its methods.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ContactManagerFacade implements ContactManager, InitializingBean {
//~ Instance fields ========================================================
private ContactManager backend;
//~ Methods ================================================================
/**
* Security system will ensure the owner parameter equals the currently
* logged in user.
*
* @param owner DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Contact[] getAllByOwner(String owner) {
return backend.getAllByOwner(owner);
}
public void setBackend(ContactManager backend) {
this.backend = backend;
}
public ContactManager getBackend() {
return backend;
}
/**
* Security system will ensure logged in user has ROLE_TELLER.
*
* <p>
* Security system cannot ensure that only the owner can get the contact,
* as doing so would require it to specifically open the contact. Whilst
* possible, this would be expensive as the operation would be performed
* both by the security system as well as the implementation. Instead the
* facade will confirm the contact.getOwner() matches what is on the
* ContextHolder.
* </p>
*
* @param id DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws AccessDeniedException DOCUMENT ME!
*/
public Contact getById(Integer id) {
Contact result = backend.getById(id);
Authentication auth = ((SecureContext) ContextHolder.getContext())
.getAuthentication();
String username = auth.getPrincipal().toString();
if (auth.getPrincipal() instanceof UserDetails) {
username = ((UserDetails) auth.getPrincipal()).getUsername();
}
if (username.equals(result.getOwner())) {
return result;
} else {
throw new AccessDeniedException(
"The requested id is not owned by the currently logged in user");
}
}
/**
* Public method.
*
* @return DOCUMENT ME!
*/
public Integer getNextId() {
return backend.getNextId();
}
/**
* Public method.
*
* @return DOCUMENT ME!
*/
public Contact getRandomContact() {
return backend.getRandomContact();
}
public void afterPropertiesSet() throws Exception {
if (backend == null) {
throw new IllegalArgumentException(
"A backend ContactManager implementation is required");
}
}
/**
* Security system will ensure logged in user has ROLE_SUPERVISOR.
*
* @param contact DOCUMENT ME!
*/
public void delete(Contact contact) {
backend.delete(contact);
}
/**
* Security system will ensure the owner specified via contact.getOwner()
* equals the currently logged in user.
*
* @param contact DOCUMENT ME!
*/
public void save(Contact contact) {
backend.save(contact);
}
}

View File

@@ -1,117 +0,0 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
import org.aopalliance.intercept.MethodInvocation;
import java.util.Iterator;
/**
* Implementation of an {@link AccessDecisionVoter} that provides
* application-specific security for the Contact application.
*
* <p>
* If the {@link ConfigAttribute#getAttribute()} has a value of
* <code>CONTACT_OWNED_BY_CURRENT_USER</code>, the String or the
* Contact.getOwner() associated with the method call is compared with the
* Authentication.getPrincipal().toString() result. If it matches, the voter
* votes to grant access. If they do not match, it votes to deny access.
* </p>
*
* <p>
* All comparisons are case sensitive.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ContactSecurityVoter implements AccessDecisionVoter {
//~ Methods ================================================================
public boolean supports(ConfigAttribute attribute) {
if ("CONTACT_OWNED_BY_CURRENT_USER".equals(attribute.getAttribute())) {
return true;
} else {
return false;
}
}
public boolean supports(Class clazz) {
if (MethodInvocation.class.isAssignableFrom(clazz)) {
return true;
} else {
return false;
}
}
public int vote(Authentication authentication, Object object,
ConfigAttributeDefinition config) {
if ((object == null) || !this.supports(object.getClass())) {
throw new IllegalArgumentException(
"Does not support the presented Object type");
}
MethodInvocation invocation = (MethodInvocation) object;
int result = ACCESS_ABSTAIN;
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (this.supports(attribute)) {
result = ACCESS_DENIED;
// Lookup the account number being passed
String passedOwner = null;
for (int i = 0; i < invocation.getArguments().length; i++) {
Class argClass = invocation.getArguments()[i].getClass();
if (String.class.isAssignableFrom(argClass)) {
passedOwner = (String) invocation.getArguments()[i];
} else if (Contact.class.isAssignableFrom(argClass)) {
passedOwner = ((Contact) invocation.getArguments()[i])
.getOwner();
}
}
if (passedOwner != null) {
String username = authentication.getPrincipal().toString();
if (authentication.getPrincipal() instanceof UserDetails) {
username = ((UserDetails) authentication.getPrincipal())
.getUsername();
}
// Check the authentication principal matches the passed owner
if (passedOwner.equals(username)) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
}

View File

@@ -0,0 +1,153 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* Populates the Contacts in-memory database with contact and ACL information.
*
* @author Ben Alex
* @version $Id$
*/
public class DataSourcePopulator implements InitializingBean {
//~ Instance fields ========================================================
private DataSource dataSource;
//~ Methods ================================================================
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
public void afterPropertiesSet() throws Exception {
if (dataSource == null) {
throw new IllegalArgumentException("dataSource required");
}
JdbcTemplate template = new JdbcTemplate(dataSource);
template.execute(
"CREATE TABLE CONTACTS(ID INTEGER NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)");
template.execute(
"INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');"); // marissa
template.execute(
"INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');"); // marissa
template.execute(
"INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');"); // marissa
template.execute(
"INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');"); // marissa + dianne + scott
template.execute(
"INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');"); // dianne
template.execute(
"INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');"); // dianne + scott
template.execute(
"INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');"); // scott
template.execute(
"INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');"); // dianne + scott
template.execute(
"INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');"); // scott
template.execute(
"CREATE TABLE ACL_OBJECT_IDENTITY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,OBJECT_IDENTITY VARCHAR_IGNORECASE(250) NOT NULL,PARENT_OBJECT INTEGER,ACL_CLASS VARCHAR_IGNORECASE(250) NOT NULL,CONSTRAINT UNIQUE_OBJECT_IDENTITY UNIQUE(OBJECT_IDENTITY),CONSTRAINT SYS_FK_3 FOREIGN KEY(PARENT_OBJECT) REFERENCES ACL_OBJECT_IDENTITY(ID))");
template.execute(
"INSERT INTO acl_object_identity VALUES (1, 'sample.contact.Contact:1', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (2, 'sample.contact.Contact:2', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (3, 'sample.contact.Contact:3', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (4, 'sample.contact.Contact:4', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (5, 'sample.contact.Contact:5', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (6, 'sample.contact.Contact:6', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (7, 'sample.contact.Contact:7', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (8, 'sample.contact.Contact:8', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"INSERT INTO acl_object_identity VALUES (9, 'sample.contact.Contact:9', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');");
template.execute(
"CREATE TABLE ACL_PERMISSION(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,ACL_OBJECT_IDENTITY INTEGER NOT NULL,RECIPIENT VARCHAR_IGNORECASE(100) NOT NULL,MASK INTEGER NOT NULL,CONSTRAINT UNIQUE_RECIPIENT UNIQUE(ACL_OBJECT_IDENTITY,RECIPIENT),CONSTRAINT SYS_FK_7 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID))");
template.execute(
"INSERT INTO acl_permission VALUES (null, 1, 'marissa', 1);"); // administer
template.execute(
"INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 3, 'marissa', 22);"); // read+write+delete
template.execute(
"INSERT INTO acl_permission VALUES (null, 4, 'marissa', 1);"); // administer
template.execute(
"INSERT INTO acl_permission VALUES (null, 4, 'dianne', 1);"); // administer
template.execute(
"INSERT INTO acl_permission VALUES (null, 4, 'scott', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 5, 'dianne', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 6, 'dianne', 22);"); // read+write+delete
template.execute(
"INSERT INTO acl_permission VALUES (null, 6, 'scott', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 7, 'scott', 1);"); // administer
template.execute(
"INSERT INTO acl_permission VALUES (null, 8, 'dianne', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 8, 'scott', 2);"); // read
template.execute(
"INSERT INTO acl_permission VALUES (null, 9, 'scott', 22);"); // read+write+delete
template.execute(
"CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);");
template.execute(
"CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
template.execute(
"CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);");
/*
Passwords encoded using MD5, NOT in Base64 format, with null as salt
Encoded password for marissa is "koala"
Encoded password for dianne is "emu"
Encoded password for scott is "wombat"
Encoded password for peter is "opal" (but user is disabled)
*/
template.execute(
"INSERT INTO USERS VALUES('marissa','a564de63c2d0da68cf47586ee05984d7',TRUE);");
template.execute(
"INSERT INTO USERS VALUES('dianne','65d15fe9156f9c4bbffd98085992a44e',TRUE);");
template.execute(
"INSERT INTO USERS VALUES('scott','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
template.execute(
"INSERT INTO USERS VALUES('peter','22b5c9accc6e1ba628cedc63a72d57f8',FALSE);");
template.execute(
"INSERT INTO AUTHORITIES VALUES('marissa','ROLE_USER');");
template.execute(
"INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR');");
template.execute(
"INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_USER');");
}
}

View File

@@ -17,6 +17,7 @@ package sample.contact;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
@@ -28,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
/**
* Controller to delete a contact page.
* Controller to delete a contact.
*
* @author Ben Alex
* @version $Id$
@@ -57,8 +58,8 @@ public class DeleteController implements Controller, InitializingBean {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
Integer id = new Integer(request.getParameter("id"));
Contact contact = contactManager.getById(id);
int id = RequestUtils.getRequiredIntParameter(request, "contactId");
Contact contact = contactManager.getById(new Integer(id));
contactManager.delete(contact);
return new ModelAndView("deleted", "contact", contact);

View File

@@ -0,0 +1,95 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import net.sf.acegisecurity.acl.AclManager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Controller for deleting an ACL permission.
*
* @author Ben Alex
* @version $Id$
*/
public class DeletePermissionController implements Controller, InitializingBean {
//~ Instance fields ========================================================
private AclManager aclManager;
private ContactManager contactManager;
//~ Methods ================================================================
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public AclManager getAclManager() {
return aclManager;
}
public void setContactManager(ContactManager contact) {
this.contactManager = contact;
}
public ContactManager getContactManager() {
return contactManager;
}
public void afterPropertiesSet() throws Exception {
if (contactManager == null) {
throw new IllegalArgumentException(
"A ContactManager implementation is required");
}
if (aclManager == null) {
throw new IllegalArgumentException(
"An aclManager implementation is required");
}
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
int contactId = RequestUtils.getRequiredIntParameter(request,
"contactId");
String recipient = RequestUtils.getRequiredStringParameter(request,
"recipient");
Contact contact = contactManager.getById(new Integer(contactId));
contactManager.deletePermission(contact, recipient);
Map model = new HashMap();
model.put("contact", contact);
model.put("recipient", recipient);
return new ModelAndView("deletePermission", "model", model);
}
}

View File

@@ -15,13 +15,6 @@
package sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
@@ -30,6 +23,7 @@ import org.springframework.web.servlet.mvc.Controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
@@ -67,38 +61,17 @@ public class SecureIndexController implements Controller, InitializingBean {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
SecureContext secureContext = ((SecureContext) ContextHolder.getContext());
List myContactsList = contactManager.getAll();
Contact[] myContacts;
if (null == secureContext) {
throw new AuthenticationCredentialsNotFoundException(
"Authentication credentials were not found in the "
+ "SecureContext");
if (myContactsList.size() == 0) {
myContacts = null;
} else {
myContacts = (Contact[]) myContactsList.toArray(new Contact[] {});
}
// Lookup username. As we must accommodate DaoAuthenticationProvider,
// CAS and container based authentication, we take care with casting
Authentication auth = secureContext.getAuthentication();
String username = auth.getPrincipal().toString();
if (auth.getPrincipal() instanceof UserDetails) {
username = ((UserDetails) auth.getPrincipal()).getUsername();
}
boolean supervisor = false;
GrantedAuthority[] granted = auth.getAuthorities();
for (int i = 0; i < granted.length; i++) {
if (granted[i].getAuthority().equals("ROLE_SUPERVISOR")) {
supervisor = true;
}
}
Contact[] myContacts = contactManager.getAllByOwner(username);
Map model = new HashMap();
model.put("contacts", myContacts);
model.put("supervisor", new Boolean(supervisor));
model.put("user", username);
return new ModelAndView("index", "model", model);
}

View File

@@ -15,19 +15,10 @@
package sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -57,20 +48,8 @@ public class WebContactAddController extends SimpleFormController {
String name = ((WebContact) command).getName();
String email = ((WebContact) command).getEmail();
Authentication auth = ((SecureContext) ContextHolder.getContext())
.getAuthentication();
String owner = auth.getPrincipal().toString();
if (auth.getPrincipal() instanceof UserDetails) {
owner = ((UserDetails) auth.getPrincipal()).getUsername();
}
Contact contact = new Contact(contactManager.getNextId(), name, email,
owner);
contactManager.save(contact);
Map myModel = new HashMap();
myModel.put("now", new Date());
Contact contact = new Contact(name, email);
contactManager.create(contact);
return new ModelAndView(new RedirectView(getSuccessView()));
}

View File

@@ -35,12 +35,16 @@ public class WebContactValidator implements Validator {
public void validate(Object obj, Errors errors) {
WebContact wc = (WebContact) obj;
if ((wc.getName() == null) || (wc.getName().length() < 3)) {
errors.rejectValue("name", "not-used", null, "Name is required.");
if ((wc.getName() == null) || (wc.getName().length() < 3)
|| (wc.getName().length() > 50)) {
errors.rejectValue("name", "err.name",
"Name 3-50 characters is required.");
}
if ((wc.getEmail() == null) || (wc.getEmail().length() < 3)) {
errors.rejectValue("email", "not-used", null, "Email is required.");
if ((wc.getEmail() == null) || (wc.getEmail().length() < 3)
|| (wc.getEmail().length() > 50)) {
errors.rejectValue("email", "err.email",
"Email 3-50 characters is required.");
}
}
}