diff --git a/.classpath b/.classpath
index 9047d483ee..b7c436301f 100644
--- a/.classpath
+++ b/.classpath
@@ -26,15 +26,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -43,8 +43,8 @@
-
-
+
+
@@ -52,5 +52,6 @@
+
diff --git a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java
index 47b8d2945c..a371b5bf6d 100644
--- a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java
+++ b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java
@@ -52,9 +52,9 @@ public class MockHttpServletRequest implements HttpServletRequest {
private HttpSession session = new MockHttpSession();
private Map attribMap = new HashMap();
+ private Map cookiesMap = new HashMap();
private Map headersMap = new HashMap();
private Map paramMap = new HashMap();
- private Map cookiesMap = new HashMap();
private Principal principal;
private String contextPath = "";
private String pathInfo; // null for no extra path
@@ -76,12 +76,14 @@ public class MockHttpServletRequest implements HttpServletRequest {
this.queryString = queryString;
}
- public MockHttpServletRequest(Map headers, HttpSession session, String queryString, Cookie[] cookies) {
- this.queryString = queryString;
+ public MockHttpServletRequest(Map headers, HttpSession session,
+ String queryString, Cookie[] cookies) {
+ this.queryString = queryString;
this.headersMap = headers;
this.session = session;
+
for (int i = 0; i < cookies.length; i++) {
- cookiesMap.put(cookies[i].getName(), cookies[i]);
+ cookiesMap.put(cookies[i].getName(), cookies[i]);
}
}
@@ -172,6 +174,18 @@ public class MockHttpServletRequest implements HttpServletRequest {
throw new UnsupportedOperationException("mock method not implemented");
}
+ public String getLocalAddr() {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
+ public String getLocalName() {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
+ public int getLocalPort() {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
public Locale getLocale() {
throw new UnsupportedOperationException("mock method not implemented");
}
@@ -246,6 +260,10 @@ public class MockHttpServletRequest implements HttpServletRequest {
throw new UnsupportedOperationException("mock method not implemented");
}
+ public int getRemotePort() {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
public String getRemoteUser() {
throw new UnsupportedOperationException("mock method not implemented");
}
diff --git a/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java b/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
index d2fe755514..354a98864e 100644
--- a/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
+++ b/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
@@ -53,6 +53,10 @@ public class MockHttpServletResponse implements HttpServletResponse {
throw new UnsupportedOperationException("mock method not implemented");
}
+ public void setCharacterEncoding(String arg0) {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
public String getCharacterEncoding() {
throw new UnsupportedOperationException("mock method not implemented");
}
@@ -73,6 +77,10 @@ public class MockHttpServletResponse implements HttpServletResponse {
throw new UnsupportedOperationException("mock method not implemented");
}
+ public String getContentType() {
+ throw new UnsupportedOperationException("mock method not implemented");
+ }
+
public Cookie getCookieByName(String name) {
return (Cookie) cookiesMap.get(name);
}
diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java
index 06d1f5ae2e..91bdac6956 100644
--- a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java
+++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java
@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -244,6 +244,21 @@ public class FilterInvocationTests extends TestCase {
"mock method not implemented");
}
+ public String getLocalAddr() {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
+ public String getLocalName() {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
+ public int getLocalPort() {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
public Locale getLocale() {
throw new UnsupportedOperationException(
"mock method not implemented");
@@ -299,6 +314,11 @@ public class FilterInvocationTests extends TestCase {
"mock method not implemented");
}
+ public int getRemotePort() {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
public RequestDispatcher getRequestDispatcher(String arg0) {
throw new UnsupportedOperationException(
"mock method not implemented");
@@ -341,6 +361,11 @@ public class FilterInvocationTests extends TestCase {
"mock method not implemented");
}
+ public void setCharacterEncoding(String arg0) {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
public String getCharacterEncoding() {
throw new UnsupportedOperationException(
"mock method not implemented");
@@ -361,6 +386,11 @@ public class FilterInvocationTests extends TestCase {
"mock method not implemented");
}
+ public String getContentType() {
+ throw new UnsupportedOperationException(
+ "mock method not implemented");
+ }
+
public void setLocale(Locale arg0) {
throw new UnsupportedOperationException(
"mock method not implemented");
diff --git a/doc/xdocs/changes.xml b/doc/xdocs/changes.xml
index dce9d17da3..3de5171cfc 100644
--- a/doc/xdocs/changes.xml
+++ b/doc/xdocs/changes.xml
@@ -31,7 +31,7 @@
ContextHolderAwareRequestWrapper methods return null if user is anonymous
AbstractBasicAclEntry improved compatibility with Hibernate
User now provides a more useful toString() method
- Use Spring 1.1.5 JARs
+ Update to match Spring 1.1.5 official JAR dependencies (NB: now using Servlet 2.4 and related JSP/taglib JARs)
SecurityEnforcementFilter caused NullPointerException when anonymous authentication used with BasicProcessingFilterEntryPoint
FilterChainProxy now supports replacement of ServletRequest and ServetResponse by Filter beans
Corrected Authz parsing of whitespace in GrantedAuthoritys
@@ -39,6 +39,9 @@
HttpSessionContextIntegrationFilter now handles HttpSession invalidation without redirection
StringSplitUtils.split() ignored delimiter argument
DigestProcessingFilter now provides userCache getter and setter
+ Contacts Sample made to work with UserDetails-based Principal
+ Documentation improvements
+ Test coverage improvements
Added Digest Authentication support (RFC 2617 and RFC 2069)
diff --git a/project.xml b/project.xml
index 6600fbc0ef..83bc3f6bfa 100644
--- a/project.xml
+++ b/project.xml
@@ -194,7 +194,7 @@
jstl
jstl
- 1.0.2
+ 1.0.6
jar
true
@@ -203,13 +203,14 @@
servletapi
servletapi
- 2.3
+ 2.4
jar
+ http://java.sun.com/products/servlet
oro
oro
- 2.0.7
+ 2.0.8
jar
http://jakarta.apache.org/oro/
@@ -229,7 +230,7 @@
log4j
log4j
- 1.2.8
+ 1.2.9
jar
true
@@ -338,7 +339,7 @@
taglibs
standard
- 1.0.4
+ 1.0.6
jar
http://jakarta.apache.org/taglibs/
@@ -377,6 +378,16 @@
2.5
plugin
+
+ jspapi
+ jsp-api
+ 2.0
+ jar
+ http://java.sun.com/products/jsp
+
+ false
+
+
${basedir}/src/main/java
diff --git a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java
index 79136e25f3..6041d19625 100644
--- a/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java
+++ b/samples/contacts/src/main/java/sample/contact/ContactManagerBackend.java
@@ -15,15 +15,18 @@
package sample.contact;
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.acl.basic.AclObjectIdentity;
import net.sf.acegisecurity.acl.basic.BasicAclExtendedDao;
import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
-import net.sf.acegisecurity.context.ContextHolder;
-import net.sf.acegisecurity.context.security.SecureContext;
+import net.sf.acegisecurity.context.security.SecureContextUtils;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.support.ApplicationObjectSupport;
+
import java.util.List;
import java.util.Random;
@@ -34,7 +37,8 @@ import java.util.Random;
* @author Ben Alex
* @version $Id$
*/
-public class ContactManagerBackend implements ContactManager, InitializingBean {
+public class ContactManagerBackend extends ApplicationObjectSupport
+ implements ContactManager, InitializingBean {
//~ Instance fields ========================================================
private BasicAclExtendedDao basicAclExtendedDao;
@@ -44,10 +48,18 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
//~ Methods ================================================================
public List getAll() {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Returning all contacts");
+ }
+
return contactDao.findAll();
}
public List getAllRecipients() {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Returning all recipients");
+ }
+
List list = contactDao.findAllPrincipals();
list.addAll(contactDao.findAllRoles());
@@ -63,6 +75,10 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
}
public Contact getById(Integer id) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Returning contact with id: " + id);
+ }
+
return contactDao.getById(id);
}
@@ -80,6 +96,10 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
* @return DOCUMENT ME!
*/
public Contact getRandomContact() {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Returning random contact");
+ }
+
Random rnd = new Random();
List contacts = contactDao.findAll();
int getNumber = rnd.nextInt(contacts.size());
@@ -94,6 +114,11 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
simpleAclEntry.setMask(permission.intValue());
simpleAclEntry.setRecipient(recipient);
basicAclExtendedDao.create(simpleAclEntry);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Added permission " + permission + " for recipient "
+ + recipient + " contact " + contact);
+ }
}
public void afterPropertiesSet() throws Exception {
@@ -114,6 +139,11 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
// Grant the current principal access to the contact
addPermission(contact, getUsername(),
new Integer(SimpleAclEntry.ADMINISTRATION));
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Created contact " + contact
+ + " and granted admin permission to recipient " + getUsername());
+ }
}
public void delete(Contact contact) {
@@ -121,19 +151,39 @@ public class ContactManagerBackend implements ContactManager, InitializingBean {
// Delete the ACL information as well
basicAclExtendedDao.delete(makeObjectIdentity(contact));
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Deleted contact " + contact
+ + " including ACL permissions");
+ }
}
public void deletePermission(Contact contact, String recipient) {
basicAclExtendedDao.delete(makeObjectIdentity(contact), recipient);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Deleted contact " + contact
+ + " ACL permissions for recipient " + recipient);
+ }
}
public void update(Contact contact) {
contactDao.update(contact);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Updated contact " + contact);
+ }
}
protected String getUsername() {
- return ((SecureContext) ContextHolder.getContext()).getAuthentication()
- .getPrincipal().toString();
+ Authentication auth = SecureContextUtils.getSecureContext()
+ .getAuthentication();
+
+ if (auth.getPrincipal() instanceof UserDetails) {
+ return ((UserDetails) auth.getPrincipal()).getUsername();
+ } else {
+ return auth.getPrincipal().toString();
+ }
}
private AclObjectIdentity makeObjectIdentity(Contact contact) {
diff --git a/samples/contacts/src/main/resources/log4j.properties b/samples/contacts/src/main/resources/log4j.properties
index 67e53a087e..a16a75a136 100644
--- a/samples/contacts/src/main/resources/log4j.properties
+++ b/samples/contacts/src/main/resources/log4j.properties
@@ -20,6 +20,7 @@ log4j.rootLogger=WARN, stdout, fileout
#log4j.logger.net.sf.acegisecurity.ui.httpinvoker=DEBUG, stdout, fileout
#log4j.logger.net.sf.acegisecurity.util=DEBUG, stdout, fileout
#log4j.logger.net.sf.acegisecurity.providers.dao=DEBUG, stdout, fileout
+log4j.logger.sample.contact=DEBUG, stdout, fileout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
diff --git a/samples/contacts/src/main/resources/messages.properties b/samples/contacts/src/main/resources/messages.properties
new file mode 100644
index 0000000000..d869ef70b5
--- /dev/null
+++ b/samples/contacts/src/main/resources/messages.properties
@@ -0,0 +1,2 @@
+err.name.webContact.name=Name 3-50 characters is required.
+err.name.webContact.email=Email 3-50 characters is required.
diff --git a/samples/contacts/src/main/webapp/common/WEB-INF/contacts-servlet.xml b/samples/contacts/src/main/webapp/common/WEB-INF/contacts-servlet.xml
index 4ca259918d..a796a6b16b 100644
--- a/samples/contacts/src/main/webapp/common/WEB-INF/contacts-servlet.xml
+++ b/samples/contacts/src/main/webapp/common/WEB-INF/contacts-servlet.xml
@@ -11,6 +11,10 @@
+
+ messages
+
+