diff --git a/samples/contacts/src/main/java/sample/contact/AddDeleteContactController.java b/samples/contacts/src/main/java/sample/contact/AddDeleteContactController.java new file mode 100644 index 0000000000..bf634b9e62 --- /dev/null +++ b/samples/contacts/src/main/java/sample/contact/AddDeleteContactController.java @@ -0,0 +1,64 @@ +package sample.contact; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.validation.Validator; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + +/** + * + * @author Luke Taylor + * @version $Id$ + * @since 3.0 + */ +@Controller +public class AddDeleteContactController { + @Autowired + private ContactManager contactManager; + private Validator validator = new WebContactValidator(); + + /** + * Displays the "add contact" form. + */ + @RequestMapping(value="/secure/add.htm", method=RequestMethod.GET) + public ModelAndView addContactDisplay() { + return new ModelAndView("add", "webContact", new WebContact()); + } + + @InitBinder + public void initBinder(WebDataBinder binder) { + System.out.println("A binder for object: " + binder.getObjectName()); + } + + /** + * Handles the submission of the contact form, creating a new instance if + * the username and email are valid. + */ + @RequestMapping(value="/secure/add.htm", method=RequestMethod.POST) + public String addContact(WebContact form, BindingResult result) { + validator.validate(form, result); + + if (result.hasErrors()) { + return "add"; + } + + Contact contact = new Contact(form.getName(), form.getEmail()); + contactManager.create(contact); + + return "redirect:/secure/index.htm"; + } + + @RequestMapping(value="/secure/del.htm", method=RequestMethod.GET) + public ModelAndView handleRequest(@RequestParam("contactId") int contactId) { + Contact contact = contactManager.getById(Long.valueOf(contactId)); + contactManager.delete(contact); + + return new ModelAndView("deleted", "contact", contact); + } +} diff --git a/samples/contacts/src/main/java/sample/contact/AddPermissionController.java b/samples/contacts/src/main/java/sample/contact/AddPermissionController.java deleted file mode 100644 index af0f89c992..0000000000 --- a/samples/contacts/src/main/java/sample/contact/AddPermissionController.java +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.security.acls.Permission; -import org.springframework.security.acls.domain.BasePermission; -import org.springframework.security.acls.sid.PrincipalSid; -import org.springframework.util.Assert; -import org.springframework.validation.BindException; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.SimpleFormController; -import org.springframework.web.servlet.view.RedirectView; - - -/** - * 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 afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "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 = ServletRequestUtils.getRequiredIntParameter(request, "contactId"); - - Contact contact = contactManager.getById(new Long(contactId)); - - AddPermission addPermission = new AddPermission(); - addPermission.setContact(contact); - - return addPermission; - } - - protected ModelAndView handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response) throws Exception { - return disallowDuplicateFormSubmission(request, response); - } - - private Map listPermissions(HttpServletRequest request) { - Map map = new LinkedHashMap(); - map.put(new Integer(BasePermission.ADMINISTRATION.getMask()), - getApplicationContext().getMessage("select.administer", null, "Administer", request.getLocale())); - map.put(new Integer(BasePermission.READ.getMask()), - getApplicationContext().getMessage("select.read", null, "Read", request.getLocale())); - map.put(new Integer(BasePermission.DELETE.getMask()), - getApplicationContext().getMessage("select.delete", null, "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())); - - for (String recipient : contactManager.getAllRecipients()) { - map.put(recipient, recipient); - } - - return map; - } - - protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, - 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(), sid, permission); - } catch (DataAccessException existingPermission) { - existingPermission.printStackTrace(); - errors.rejectValue("recipient", "err.recipientExistsForContact", "Addition failure."); - - return showForm(request, response, errors); - } - - return new ModelAndView(new RedirectView(getSuccessView())); - } - - @Override - @SuppressWarnings("unchecked") - protected Map referenceData(HttpServletRequest request) throws Exception { - Map model = new HashMap(2); - model.put("recipients", listRecipients(request)); - model.put("permissions", listPermissions(request)); - - return model; - } - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } -} diff --git a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java index 16ff9d7da9..e1815ec044 100644 --- a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java +++ b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java @@ -1,75 +1,165 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.io.IOException; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.dao.DataAccessException; import org.springframework.security.acls.Acl; import org.springframework.security.acls.AclService; +import org.springframework.security.acls.Permission; +import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.objectidentity.ObjectIdentityImpl; -import org.springframework.util.Assert; -import org.springframework.web.bind.ServletRequestUtils; +import org.springframework.security.acls.sid.PrincipalSid; +import org.springframework.security.acls.sid.Sid; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.BindingResult; +import org.springframework.validation.Validator; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.Controller; - /** - * Controller for "administer" index page. + * Web controller to handle Permission administration functions - adding and deleting + * permissions for contacts. * - * @author Ben Alex + * @author Luke Taylor * @version $Id$ + * @since 3.0 */ -public class AdminPermissionController implements Controller, InitializingBean { - //~ Instance fields ================================================================================================ - +@Controller +@SessionAttributes("addPermission") +public final class AdminPermissionController implements MessageSourceAware{ + @Autowired private AclService aclService; + @Autowired private ContactManager contactManager; + private MessageSourceAccessor messages; + private Validator addPermissionValidator = new AddPermissionValidator(); - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - Assert.notNull(aclService, "An aclService implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - int id = ServletRequestUtils.getRequiredIntParameter(request, "contactId"); - - Contact contact = contactManager.getById(new Long(id)); + /** + * Displays the permission admin page for a particular contact. + */ + @RequestMapping(value="/secure/adminPermission.htm", method=RequestMethod.GET) + public ModelAndView displayAdminPage(@RequestParam("contactId") int contactId) { + Contact contact = contactManager.getById(Long.valueOf(contactId)); Acl acl = aclService.readAclById(new ObjectIdentityImpl(contact)); - Map model = new HashMap(2); + Map model = new HashMap(); model.put("contact", contact); model.put("acl", acl); return new ModelAndView("adminPermission", "model", model); } - public void setAclService(AclService aclService) { - this.aclService = aclService; + /** + * Displays the "add permission" page for a contact. + */ + @RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.GET) + public ModelAndView displayAddPermissionPageForContact(@RequestParam("contactId") int contactId) { + Contact contact = contactManager.getById(new Long(contactId)); + + AddPermission addPermission = new AddPermission(); + addPermission.setContact(contact); + + Map model = new HashMap(); + model.put("addPermission", addPermission); + model.put("recipients", listRecipients()); + model.put("permissions", listPermissions()); + + return new ModelAndView("addPermission", model); } - public void setContactManager(ContactManager contact) { - this.contactManager = contact; + @InitBinder("addPermission") + public void initBinder(WebDataBinder binder) { + binder.setAllowedFields(new String[] {"recipient", "permission"}); + } + + /** + * Handles submission of the "add permission" form. + */ + @RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.POST) + public String addPermission(AddPermission addPermission, BindingResult result, ModelMap model) { + addPermissionValidator.validate(addPermission, result); + + if (result.hasErrors()) { + model.put("recipients", listRecipients()); + model.put("permissions", listPermissions()); + + return "addPermission"; + } + + PrincipalSid sid = new PrincipalSid(addPermission.getRecipient()); + Permission permission = BasePermission.buildFromMask(addPermission.getPermission().intValue()); + + try { + contactManager.addPermission(addPermission.getContact(), sid, permission); + } catch (DataAccessException existingPermission) { + existingPermission.printStackTrace(); + result.rejectValue("recipient", "err.recipientExistsForContact", "Addition failure."); + + model.put("recipients", listRecipients()); + model.put("permissions", listPermissions()); + return "addPermission"; + } + + return "redirect:/secure/index.htm"; + } + + /** + * Deletes a permission + */ + @RequestMapping(value="/secure/deletePermission.htm") + public ModelAndView deletePermission( + @RequestParam("contactId") int contactId, + @RequestParam("sid") String sid, + @RequestParam("permission") int mask) { + + Contact contact = contactManager.getById(new Long(contactId)); + + 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("sid", sidObject); + model.put("permission", permission); + + return new ModelAndView("deletePermission", "model", model); + } + + private Map listPermissions() { + Map map = new LinkedHashMap(); + map.put(Integer.valueOf(BasePermission.ADMINISTRATION.getMask()), messages.getMessage("select.administer", "Administer")); + map.put(Integer.valueOf(BasePermission.READ.getMask()), messages.getMessage("select.read", "Read")); + map.put(Integer.valueOf(BasePermission.DELETE.getMask()), messages.getMessage("select.delete", "Delete")); + + return map; + } + + private Map listRecipients() { + Map map = new LinkedHashMap(); + map.put("", messages.getMessage("select.pleaseSelect", "-- please select --")); + + for (String recipient : contactManager.getAllRecipients()) { + map.put(recipient, recipient); + } + + return map; + } + + public void setMessageSource(MessageSource messageSource) { + this.messages = new MessageSourceAccessor(messageSource); } } diff --git a/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java b/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java index 7aea84d4ee..0122f3323b 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java +++ b/samples/contacts/src/main/java/sample/contact/ContactDaoSpring.java @@ -49,7 +49,6 @@ public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao { //~ Methods ======================================================================================================== public void create(Contact contact) { - System.out.println("creating contact w/ id " + contact.getId() + " " + contact.getEmail()); contactInsert.insert(contact); } diff --git a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java index f36fa305a8..c82940a8db 100644 --- a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java +++ b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java @@ -58,6 +58,11 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C //~ Methods ======================================================================================================== + public void afterPropertiesSet() throws Exception { + Assert.notNull(contactDao, "contactDao required"); + Assert.notNull(mutableAclService, "mutableAclService required"); + } + public void addPermission(Contact contact, Sid recipient, Permission permission) { MutableAcl acl; ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId()); @@ -71,14 +76,7 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C acl.insertAce(acl.getEntries().size(), permission, recipient, true); mutableAclService.updateAcl(acl); - if (logger.isDebugEnabled()) { - logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact); - } - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactDao, "contactDao required"); - Assert.notNull(mutableAclService, "mutableAclService required"); + logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact); } public void create(Contact contact) { @@ -128,18 +126,14 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C @Transactional(readOnly=true) public List getAll() { - if (logger.isDebugEnabled()) { - logger.debug("Returning all contacts"); - } + logger.debug("Returning all contacts"); return contactDao.findAll(); } @Transactional(readOnly=true) public List getAllRecipients() { - if (logger.isDebugEnabled()) { - logger.debug("Returning all recipients"); - } + logger.debug("Returning all recipients"); List list = contactDao.findAllPrincipals(); @@ -160,15 +154,13 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C */ @Transactional(readOnly=true) public Contact getRandomContact() { - if (logger.isDebugEnabled()) { - logger.debug("Returning random contact"); - } + logger.debug("Returning random contact"); Random rnd = new Random(); List contacts = contactDao.findAll(); int getNumber = rnd.nextInt(contacts.size()); - return (Contact) contacts.get(getNumber); + return contacts.get(getNumber); } protected String getUsername() { @@ -192,8 +184,6 @@ public class ContactManagerBackend extends ApplicationObjectSupport implements C public void update(Contact contact) { contactDao.update(contact); - if (logger.isDebugEnabled()) { - logger.debug("Updated contact " + contact); - } + logger.debug("Updated contact " + contact); } } diff --git a/samples/contacts/src/main/java/sample/contact/DeleteController.java b/samples/contacts/src/main/java/sample/contact/DeleteController.java deleted file mode 100644 index 2b3da26a90..0000000000 --- a/samples/contacts/src/main/java/sample/contact/DeleteController.java +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.util.Assert; - -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.Controller; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -/** - * Controller to delete a contact. - * - * @author Ben Alex - * @version $Id$ - */ -public class DeleteController implements Controller, InitializingBean { - //~ Instance fields ================================================================================================ - - private ContactManager contactManager; - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - int id = ServletRequestUtils.getRequiredIntParameter(request, "contactId"); - Contact contact = contactManager.getById(new Long(id)); - contactManager.delete(contact); - - return new ModelAndView("deleted", "contact", contact); - } - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } -} diff --git a/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java b/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java deleted file mode 100644 index d196bbb0d6..0000000000 --- a/samples/contacts/src/main/java/sample/contact/DeletePermissionController.java +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.acls.AclService; -import org.springframework.security.acls.Permission; -import org.springframework.security.acls.domain.BasePermission; -import org.springframework.security.acls.sid.PrincipalSid; -import org.springframework.security.acls.sid.Sid; -import org.springframework.util.Assert; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.Controller; - - -/** - * Controller for deleting an ACL permission. - * - * @author Ben Alex - * @version $Id$ - */ -public class DeletePermissionController implements Controller, InitializingBean { - //~ Instance fields ================================================================================================ - - private AclService aclService; - private ContactManager contactManager; - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - Assert.notNull(aclService, "An aclService implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - // ">Del - int contactId = ServletRequestUtils.getRequiredIntParameter(request, "contactId"); - String sid = ServletRequestUtils.getRequiredStringParameter(request, "sid"); - int mask = ServletRequestUtils.getRequiredIntParameter(request, "permission"); - - Contact contact = contactManager.getById(new Long(contactId)); - - 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("sid", sidObject); - model.put("permission", permission); - - return new ModelAndView("deletePermission", "model", model); - } - - public void setAclService(AclService aclService) { - this.aclService = aclService; - } - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } -} diff --git a/samples/contacts/src/main/java/sample/contact/IndexController.java b/samples/contacts/src/main/java/sample/contact/IndexController.java new file mode 100644 index 0000000000..d6dde2eb23 --- /dev/null +++ b/samples/contacts/src/main/java/sample/contact/IndexController.java @@ -0,0 +1,83 @@ +package sample.contact; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.expression.PermissionEvaluator; +import org.springframework.security.acls.Permission; +import org.springframework.security.acls.domain.BasePermission; +import org.springframework.security.acls.expression.AclPermissionEvaluator; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +/** + * Controller which handles simple, single request use cases such as index pages and contact deletion. + * + * @author Luke Taylor + * @version $Id$ + * @since 3.0 + */ +@Controller +public class IndexController { + private final static Permission[] HAS_DELETE = new Permission[] {BasePermission.DELETE, BasePermission.ADMINISTRATION}; + private final static Permission[] HAS_ADMIN = new Permission[] {BasePermission.ADMINISTRATION}; + + //~ Instance fields ================================================================================================ + + @Autowired + private ContactManager contactManager; + @Autowired + private PermissionEvaluator permissionEvaluator; + + //~ Methods ======================================================================================================== + + /** + * The public index page, used for unauthenticated users. + */ + @RequestMapping(value="/hello.htm", method=RequestMethod.GET) + public ModelAndView displayPublicIndex() { + Contact rnd = contactManager.getRandomContact(); + + return new ModelAndView("hello", "contact", rnd); + } + + /** + * The index page for an authenticated user. + *

+ * This controller displays a list of all the contacts for which the current user has read or admin permissions. + * It makes a call to {@link ContactManager#getAll()} which automatically filters the returned list using Spring + * Security's ACL mechanism (see the expression annotations on this interface for the details). + *

+ * In addition to rendering the list of contacts, the view will also include a "Del" or "Admin" link beside the + * contact, depending on whether the user has the corresponding permissions (admin permission is assumed to imply + * delete here). This information is stored in the model using the injected {@link PermissionEvaluator} instance. + * The implementation should be an instance of {@link AclPermissionEvaluator} or one which is compatible with Spring + * Security's ACL module. + */ + @RequestMapping(value="/secure/index.htm", method=RequestMethod.GET) + public ModelAndView displayUserContacts() { + List myContactsList = contactManager.getAll(); + Map hasDelete = new HashMap(myContactsList.size()); + Map hasAdmin = new HashMap(myContactsList.size()); + + Authentication user = SecurityContextHolder.getContext().getAuthentication(); + + for (Contact contact : myContactsList) { + hasDelete.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_DELETE))); + hasAdmin.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_ADMIN))); + } + + Map model = new HashMap(); + model.put("contacts", myContactsList); + model.put("hasDeletePermission", hasDelete); + model.put("hasAdminPermission", hasAdmin); + + return new ModelAndView("index", "model", model); + } +} diff --git a/samples/contacts/src/main/java/sample/contact/PublicIndexController.java b/samples/contacts/src/main/java/sample/contact/PublicIndexController.java deleted file mode 100644 index f1ad324af6..0000000000 --- a/samples/contacts/src/main/java/sample/contact/PublicIndexController.java +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.util.Assert; - -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.Controller; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -/** - * Controller for public index page (default web app home page). - * - * @author Ben Alex - * @version $Id$ - */ -public class PublicIndexController implements Controller, InitializingBean { - //~ Instance fields ================================================================================================ - - private ContactManager contactManager; - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - } - - public ContactManager getContactManager() { - return contactManager; - } - - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - Contact rnd = contactManager.getRandomContact(); - - return new ModelAndView("hello", "contact", rnd); - } - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } -} diff --git a/samples/contacts/src/main/java/sample/contact/SecureIndexController.java b/samples/contacts/src/main/java/sample/contact/SecureIndexController.java deleted file mode 100644 index 1c5e9f035a..0000000000 --- a/samples/contacts/src/main/java/sample/contact/SecureIndexController.java +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.security.access.expression.PermissionEvaluator; -import org.springframework.security.acls.Permission; -import org.springframework.security.acls.domain.BasePermission; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.Assert; - -import org.springframework.web.servlet.ModelAndView; -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; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -/** - * Controller for secure index page. - *

- * This controller displays a list of all the contacts for which the current user has read or admin permissions. - * It makes a call to {@link ContactManager#getAll()} which automatically filters the returned list using Spring - * Security's ACL mechanism (see the expression annotations on this interface for the details). - *

- * In addition to rendering the list of contacts, the view will also include a "Del" or "Admin" link beside the - * contact, depending on whether the user has the corresponding permissions (admin permission is assumed to imply - * delete here). This information is stored in the model using the injected {@link PermissionEvaluator} instance. - * The implementation should be an instance of {@link AclPermissionEvaluator} or one which is compatible with Spring - * Security's ACL module. - * - * @author Ben Alex - * @version $Id$ - */ -public class SecureIndexController implements Controller, InitializingBean { - private final static Permission[] HAS_DELETE = new Permission[] {BasePermission.DELETE, BasePermission.ADMINISTRATION}; - private final static Permission[] HAS_ADMIN = new Permission[] {BasePermission.ADMINISTRATION}; - - //~ Instance fields ================================================================================================ - - private ContactManager contactManager; - private PermissionEvaluator permissionEvaluator; - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(contactManager, "A ContactManager implementation is required"); - Assert.notNull(permissionEvaluator, "A PermissionEvaluator implementation is required"); - } - - public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - List myContactsList = contactManager.getAll(); - Map hasDelete = new HashMap(myContactsList.size()); - Map hasAdmin = new HashMap(myContactsList.size()); - - Authentication user = SecurityContextHolder.getContext().getAuthentication(); - - for (Contact contact : myContactsList) { - hasDelete.put(contact, - permissionEvaluator.hasPermission(user, contact, HAS_DELETE) ? Boolean.TRUE : Boolean.FALSE); - hasAdmin.put(contact, - permissionEvaluator.hasPermission(user, contact, HAS_ADMIN) ? Boolean.TRUE : Boolean.FALSE); - } - - Map model = new HashMap(); - model.put("contacts", myContactsList); - model.put("hasDeletePermission", hasDelete); - model.put("hasAdminPermission", hasAdmin); - - return new ModelAndView("index", "model", model); - } - - public void setContactManager(ContactManager contact) { - this.contactManager = contact; - } - - public void setPermissionEvaluator(PermissionEvaluator pe) { - this.permissionEvaluator = pe; - } -} diff --git a/samples/contacts/src/main/java/sample/contact/WebContactAddController.java b/samples/contacts/src/main/java/sample/contact/WebContactAddController.java deleted file mode 100644 index f8281f5427..0000000000 --- a/samples/contacts/src/main/java/sample/contact/WebContactAddController.java +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2004, 2005, 2006 Acegi Technology 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.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.SimpleFormController; -import org.springframework.web.servlet.view.RedirectView; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; - - -/** - * Controller for adding a new contact. - * - * @author Ben Alex - * @version $Id$ - */ -public class WebContactAddController extends SimpleFormController { - //~ Instance fields ================================================================================================ - - private ContactManager contactManager; - - //~ Methods ======================================================================================================== - - protected Object formBackingObject(HttpServletRequest request) - throws ServletException { - WebContact wc = new WebContact(); - - return wc; - } - - public ContactManager getContactManager() { - return contactManager; - } - - public ModelAndView onSubmit(Object command) throws ServletException { - String name = ((WebContact) command).getName(); - String email = ((WebContact) command).getEmail(); - - Contact contact = new Contact(name, email); - contactManager.create(contact); - - return new ModelAndView(new RedirectView(getSuccessView())); - } - - public void setContactManager(ContactManager contactManager) { - this.contactManager = contactManager; - } -} diff --git a/samples/contacts/src/main/webapp/WEB-INF/classes/log4j.properties b/samples/contacts/src/main/webapp/WEB-INF/classes/log4j.properties index d4f6cf26a3..e7e926d3e7 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/classes/log4j.properties +++ b/samples/contacts/src/main/webapp/WEB-INF/classes/log4j.properties @@ -1,28 +1,9 @@ # Global logging configuration -log4j.rootLogger=WARN, stdout, fileout +log4j.rootLogger=DEBUG, stdout, fileout -#log4j.logger.org.springframework.aop.framework.autoproxy=DEBUG, stdout, fileout -#log4j.logger.org.springframework.aop.framework.autoproxy.metadata=DEBUG, stdout, fileout -#log4j.logger.org.springframework.aop.framework.autoproxy.target=DEBUG, stdout, fileout -#log4j.logger.org.springframework.transaction.interceptor=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.intercept=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.intercept.method=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.intercept.web=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.afterinvocation=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.acl=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.acl.basic=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.taglibs.authz=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.ui.basicauth=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.ui.rememberme=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.ui=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.afterinvocation=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.ui.rmi=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.ui.httpinvoker=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.util=DEBUG, stdout, fileout -#log4j.logger.org.springframework.security.providers.dao=DEBUG, stdout, fileout -log4j.logger.sample.contact=DEBUG, stdout, fileout - -log4j.logger.org.springframework.security=DEBUG, stdout, fileout +log4j.logger.sample.contact=DEBUG +log4j.logger.org.springframework.web.*=DEBUG +log4j.logger.org.springframework.security=DEBUG # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender diff --git a/samples/contacts/src/main/webapp/WEB-INF/contacts-servlet.xml b/samples/contacts/src/main/webapp/WEB-INF/contacts-servlet.xml index 73a2338cd9..958cb4adc7 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/contacts-servlet.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/contacts-servlet.xml @@ -1,20 +1,17 @@ - - - - - - + - - - + + + + + + diff --git a/samples/contacts/src/main/webapp/WEB-INF/jsp/adminPermission.jsp b/samples/contacts/src/main/webapp/WEB-INF/jsp/adminPermission.jsp index 9f799b0ee2..809495b8a1 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/jsp/adminPermission.jsp +++ b/samples/contacts/src/main/webapp/WEB-INF/jsp/adminPermission.jsp @@ -4,12 +4,13 @@ Administer Permissions

Administer Permissions

-

+

-

- +

+

+

@@ -18,11 +19,14 @@ - ">Del + ">Del
-

">Add Permission ">Manage +

+

+">Add Permission ">Manage +

diff --git a/samples/contacts/src/test/java/sample/contact/GetAllContactsTests.java b/samples/contacts/src/test/java/sample/contact/ContactManagerTests.java similarity index 71% rename from samples/contacts/src/test/java/sample/contact/GetAllContactsTests.java rename to samples/contacts/src/test/java/sample/contact/ContactManagerTests.java index 498a44e880..7ab83be829 100644 --- a/samples/contacts/src/test/java/sample/contact/GetAllContactsTests.java +++ b/samples/contacts/src/test/java/sample/contact/ContactManagerTests.java @@ -37,13 +37,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * * @author David Leal * @author Ben Alex + * @Author Luke Taylor */ @ContextConfiguration(locations={ "/applicationContext-common-authorization.xml", "/applicationContext-common-business.xml", "/applicationContext-contacts-test.xml"}) @RunWith(SpringJUnit4ClassRunner.class) -public class GetAllContactsTests { +public class ContactManagerTests { //~ Instance fields ================================================================================================ @Autowired @@ -51,9 +52,9 @@ public class GetAllContactsTests { //~ Methods ======================================================================================================== - protected void assertContainsContact(String id, List contacts) { + void assertContainsContact(long id, List contacts) { for(Contact contact : contacts) { - if (contact.getId().toString().equals(id)) { + if (contact.getId().equals(Long.valueOf(id))) { return; } } @@ -61,23 +62,24 @@ public class GetAllContactsTests { fail("List of contacts should have contained: " + id); } - void assertDoestNotContainContact(String id, List contacts) { + void assertDoestNotContainContact(long id, List contacts) { for(Contact contact : contacts) { - if (contact.getId().toString().equals(id)) { + if (contact.getId().equals(Long.valueOf(id))) { fail("List of contact should NOT (but did) contain: " + id); } } } /** - * Locates the first Contact of the exact name specified.

Uses the {@link - * ContactManager#getAll()} method.

+ * Locates the first Contact of the exact name specified. + *

+ * Uses the {@link ContactManager#getAll()} method. * * @param id Identify of the contact to locate (must be an exact match) * * @return the domain or null if not found */ - protected Contact getContact(String id) { + Contact getContact(String id) { for(Contact contact : contactManager.getAll()) { if (contact.getId().equals(id)) { return contact; @@ -87,7 +89,7 @@ public class GetAllContactsTests { return null; } - protected void makeActiveUser(String username) { + private void makeActiveUser(String username) { String password = ""; if ("rod".equals(username)) { @@ -105,7 +107,7 @@ public class GetAllContactsTests { } @After - public void onTearDownInTransaction() { + public void clearContext() { SecurityContextHolder.clearContext(); } @@ -116,14 +118,14 @@ public class GetAllContactsTests { 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); + assertContainsContact(4, contacts); + assertContainsContact(5, contacts); + assertContainsContact(6, contacts); + assertContainsContact(8, contacts); - assertDoestNotContainContact(Long.toString(1), contacts); - assertDoestNotContainContact(Long.toString(2), contacts); - assertDoestNotContainContact(Long.toString(3), contacts); + assertDoestNotContainContact(1, contacts); + assertDoestNotContainContact(2, contacts); + assertDoestNotContainContact(3, contacts); } @Test @@ -134,16 +136,17 @@ public class GetAllContactsTests { assertEquals(4, contacts.size()); - assertContainsContact(Long.toString(1), contacts); - assertContainsContact(Long.toString(2), contacts); - assertContainsContact(Long.toString(3), contacts); - assertContainsContact(Long.toString(4), contacts); + assertContainsContact(1, contacts); + assertContainsContact(2, contacts); + assertContainsContact(3, contacts); + assertContainsContact(4, contacts); - assertDoestNotContainContact(Long.toString(5), contacts); + assertDoestNotContainContact(5, contacts); Contact c1 = contactManager.getById(new Long(4)); contactManager.deletePermission(c1, new PrincipalSid("bob"), BasePermission.ADMINISTRATION); + contactManager.addPermission(c1, new PrincipalSid("bob"), BasePermission.ADMINISTRATION); } @Test @@ -154,12 +157,12 @@ public class GetAllContactsTests { 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); + assertContainsContact(4, contacts); + assertContainsContact(6, contacts); + assertContainsContact(7, contacts); + assertContainsContact(8, contacts); + assertContainsContact(9, contacts); - assertDoestNotContainContact(Long.toString(1), contacts); + assertDoestNotContainContact(1, contacts); } }