diff --git a/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java b/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java new file mode 100644 index 0000000000..b31276e286 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/taglibs/velocity/Authz.java @@ -0,0 +1,112 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.acegisecurity.taglibs.velocity; + +import org.acegisecurity.Authentication; + +import org.acegisecurity.acl.AclManager; + +import org.acegisecurity.taglibs.authz.AclTag; +import org.acegisecurity.taglibs.authz.AuthenticationTag; +import org.acegisecurity.taglibs.authz.AuthorizeTag; + +import org.acegisecurity.userdetails.UserDetails; + +import org.springframework.context.ApplicationContext; + + +/** + * Wrapper the implementation of Acegi Security for Spring JSP tag includes: + * {@link AuthenticationTag}, {@link AclTag}, {@link AuthorizeTag} + * + * @author Wang Qi + * @version $Id$ + */ +public interface Authz { + //~ Methods ================================================================ + + /** + * all the listed roles must be granted to return true, otherwise fasle; + * + * @param roles - comma separate GrantedAuthoritys + * + * @return granted (true|false) + */ + public boolean allGranted(String roles); + + /** + * any the listed roles must be granted to return true, otherwise fasle; + * + * @param roles - comma separate GrantedAuthoritys + * + * @return granted (true|false) + */ + public boolean anyGranted(String roles); + + /** + * set Spring application context which contains acegi related bean + * + * @return DOCUMENT ME! + */ + public ApplicationContext getAppCtx(); + + /** + * return the principal's name, supports the various type of principals + * that can exist in the {@link Authentication} object, such as a String + * or {@link UserDetails} instance + * + * @return string representation of principal's name + */ + public String getPrincipal(); + + /** + * return true if the principal holds either permission specified for the + * provided domain object + * + *
+ * Only works with permissions that are subclasses of {@link + * net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry}. + *
+ * + *
+ * For this class to operate it must be able to access the application
+ * context via the WebApplicationContextUtils and locate an
+ * {@link AclManager}.
+ *
+ * WebApplicationContextUtils and locate an {@link AclManager}.
+ * WebApplicationContextUtils get application context via ServletContext.
+ * I decided to let the Authz provide the Spring application context.
+ */
+ private class MyAclTag extends AclTag {
+ private static final long serialVersionUID = 6752340622125924108L;
+ ApplicationContext context;
+
+ protected ApplicationContext getContext(PageContext pageContext) {
+ return context;
+ }
+
+ protected void setContext(ApplicationContext context) {
+ this.context = context;
+ }
+ }
+
+ /**
+ * it must output somthing to JSP page, so have to override the
+ * writeMessage method to avoid JSP related operation. Get Idea from Acegi
+ * Test class.
+ */
+ private class MyAuthenticationTag extends AuthenticationTag {
+ private static final long serialVersionUID = -1094246833893599161L;
+ String lastMessage = null;
+
+ public String getLastMessage() {
+ return lastMessage;
+ }
+
+ protected void writeMessage(String msg) throws JspException {
+ lastMessage = msg;
+ }
+ }
+}
diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java
new file mode 100644
index 0000000000..be72697769
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAttributeTest.java
@@ -0,0 +1,98 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.taglibs.velocity;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.GrantedAuthority;
+import org.acegisecurity.GrantedAuthorityImpl;
+
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.context.SecurityContextImpl;
+
+import org.acegisecurity.providers.TestingAuthenticationToken;
+
+import javax.servlet.jsp.JspException;
+
+
+/**
+ * DOCUMENT ME!
+ */
+public class AuthzImplAttributeTest extends TestCase {
+ //~ Instance fields ========================================================
+
+ private final Authz authz = new AuthzImpl();
+ private TestingAuthenticationToken currentUser;
+
+ //~ Methods ================================================================
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ currentUser = new TestingAuthenticationToken("abc", "123",
+ new GrantedAuthority[] {new GrantedAuthorityImpl(
+ "ROLE_SUPERVISOR"), new GrantedAuthorityImpl(
+ "ROLE_RESTRICTED"),});
+
+ SecurityContextHolder.getContext().setAuthentication(currentUser);
+ }
+
+ protected void tearDown() throws Exception {
+ SecurityContextHolder.setContext(new SecurityContextImpl());
+ }
+
+ public void testAssertsIfAllGrantedSecond() {
+ boolean r1 = authz.allGranted("ROLE_SUPERVISOR,ROLE_SUPERTELLER");
+ boolean r2 = authz.anyGranted("ROLE_RESTRICTED");
+
+ //prevents request - principal is missing ROLE_SUPERTELLE
+ assertFalse(r1 && r2);
+ }
+
+ public void testAssertsIfAnyGrantedLast() {
+ boolean r2 = authz.anyGranted("ROLE_BANKER");
+
+ // prevents request - principal is missing ROLE_BANKER
+ assertFalse(r2);
+ }
+
+ public void testAssertsIfNotGrantedFirst() {
+ boolean r1 = authz.allGranted("ROLE_SUPERVISOR,ROLE_RESTRICTED");
+ boolean r2 = authz.noneGranted("ROLE_RESTRICTED");
+ boolean r3 = authz.anyGranted("ROLE_SUPERVISOR");
+
+ //prevents request - principal has ROLE_RESTRICTED
+ assertFalse(r1 && r2 && r3);
+ }
+
+ public void testAssertsIfNotGrantedIgnoresWhitespaceInAttribute() {
+ //allows request - principal has ROLE_SUPERVISOR
+ assertTrue(authz.anyGranted(
+ "\tROLE_SUPERVISOR \t, \r\n\t ROLE_TELLER "));
+ }
+
+ public void testIfAllGrantedIgnoresWhitespaceInAttribute() {
+ //allows request - principal has ROLE_RESTRICTED and ROLE_SUPERVISOR
+ assertTrue(authz.allGranted(
+ "\nROLE_SUPERVISOR\t,ROLE_RESTRICTED\t\n\r "));
+ }
+
+ public void testIfNotGrantedIgnoresWhitespaceInAttribute()
+ throws JspException {
+ //prevents request - principal does not have ROLE_TELLER
+ assertFalse(authz.allGranted(" \t ROLE_TELLER \r"));
+ }
+}
diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java
new file mode 100644
index 0000000000..f9437d06fa
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplAuthorizeTagTest.java
@@ -0,0 +1,105 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.taglibs.velocity;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.GrantedAuthority;
+import org.acegisecurity.GrantedAuthorityImpl;
+
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.context.SecurityContextImpl;
+
+import org.acegisecurity.providers.TestingAuthenticationToken;
+
+
+/**
+ * DOCUMENT ME!
+ */
+public class AuthzImplAuthorizeTagTest extends TestCase {
+ //~ Instance fields ========================================================
+
+ private Authz authz = new AuthzImpl();
+ private TestingAuthenticationToken currentUser;
+
+ //~ Methods ================================================================
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ currentUser = new TestingAuthenticationToken("abc", "123",
+ new GrantedAuthority[] {new GrantedAuthorityImpl(
+ "ROLE_SUPERVISOR"), new GrantedAuthorityImpl(
+ "ROLE_TELLER"),});
+
+ SecurityContextHolder.getContext().setAuthentication(currentUser);
+ }
+
+ protected void tearDown() throws Exception {
+ SecurityContextHolder.setContext(new SecurityContextImpl());
+ }
+
+ public void testAlwaysReturnsUnauthorizedIfNoUserFound() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ //prevents request - no principal in Context
+ assertFalse(authz.allGranted("ROLE_TELLER"));
+ }
+
+ public void testDefaultsToNotOutputtingBodyWhenNoRequiredAuthorities() {
+ //prevents body output - no authorities granted
+ assertFalse(authz.allGranted(""));
+ assertFalse(authz.anyGranted(""));
+ assertFalse(authz.noneGranted(""));
+ }
+
+ public void testOutputsBodyIfOneRolePresent() {
+ //authorized - ROLE_TELLER in both sets
+ assertTrue(authz.anyGranted("ROLE_TELLER"));
+ }
+
+ public void testOutputsBodyWhenAllGranted() {
+ // allows request - all required roles granted on principal
+ assertTrue(authz.allGranted("ROLE_SUPERVISOR,ROLE_TELLER"));
+ }
+
+ public void testOutputsBodyWhenNotGrantedSatisfied() {
+ // allows request - principal doesn't have ROLE_BANKER
+ assertTrue(authz.noneGranted("ROLE_BANKER"));
+ }
+
+ public void testPreventsBodyOutputIfNoSecureContext() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ // prevents output - no context defined
+ assertFalse(authz.anyGranted("ROLE_BANKER"));
+ }
+
+ public void testSkipsBodyIfNoAnyRolePresent() {
+ // unauthorized - ROLE_BANKER not in granted authorities
+ assertFalse(authz.anyGranted("ROLE_BANKER"));
+ }
+
+ public void testSkipsBodyWhenMissingAnAllGranted() {
+ // prevents request - missing ROLE_BANKER on principal
+ assertFalse(authz.allGranted("ROLE_SUPERVISOR,ROLE_TELLER,ROLE_BANKER"));
+ }
+
+ public void testSkipsBodyWhenNotGrantedUnsatisfied() {
+ // prevents request - principal has ROLE_TELLER
+ assertFalse(authz.noneGranted("ROLE_TELLER"));
+ }
+}
diff --git a/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java
new file mode 100644
index 0000000000..7335fdd7a6
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/taglibs/velocity/AuthzImplTest.java
@@ -0,0 +1,247 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.taglibs.velocity;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.Authentication;
+import org.acegisecurity.GrantedAuthority;
+import org.acegisecurity.MockAclManager;
+
+import org.acegisecurity.acl.AclEntry;
+import org.acegisecurity.acl.AclManager;
+import org.acegisecurity.acl.basic.MockAclObjectIdentity;
+import org.acegisecurity.acl.basic.SimpleAclEntry;
+
+import org.acegisecurity.context.SecurityContextHolder;
+
+import org.acegisecurity.providers.TestingAuthenticationToken;
+
+import org.acegisecurity.userdetails.User;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
+
+
+/**
+ * DOCUMENT ME!
+ */
+public class AuthzImplTest extends TestCase {
+ //~ Instance fields ========================================================
+
+ private Authz authz = new AuthzImpl();
+ private ConfigurableApplicationContext ctx;
+
+ //~ Methods ================================================================
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ /*String[] paths = { "applicationEmpty.xml" };
+ ctx = new ClassPathXmlApplicationContext(paths);*/
+ ctx = new StaticApplicationContext();
+
+ // Create an AclManager
+ AclManager aclManager = new MockAclManager("object1", "marissa",
+ new AclEntry[] {new MockAclEntry(), new SimpleAclEntry(
+ "marissa", new MockAclObjectIdentity(), null,
+ SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry(
+ "marissa", new MockAclObjectIdentity(), null,
+ SimpleAclEntry.READ)});
+
+ // Register the AclManager into our ApplicationContext
+ ctx.getBeanFactory().registerSingleton("aclManager", aclManager);
+ }
+
+ public void testIllegalArgumentExceptionThrownIfHasPermissionNotValidFormat() {
+ Authentication auth = new TestingAuthenticationToken("john", "crow",
+ new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ authz.setAppCtx(ctx);
+
+ String permissions = "0,5, 6"; // shouldn't be any space
+
+ try {
+ authz.hasPermission(null, permissions);
+ } catch (IllegalArgumentException iae) {
+ assertTrue(true);
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionDeniedWhenAclManagerUnawareOfObject() {
+ Authentication auth = new TestingAuthenticationToken("marissa",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ authz.setAppCtx(ctx);
+
+ boolean result = authz.hasPermission(new Integer(54),
+ new Long(SimpleAclEntry.ADMINISTRATION).toString());
+
+ assertFalse(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionDeniedWhenNoListOfPermissionsGiven() {
+ Authentication auth = new TestingAuthenticationToken("marissa",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+ authz.setAppCtx(ctx);
+
+ boolean result = authz.hasPermission("object1", null);
+
+ assertFalse(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() {
+ Authentication auth = new TestingAuthenticationToken("john", "crow",
+ new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ authz.setAppCtx(ctx);
+
+ String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + ","
+ + new Integer(SimpleAclEntry.READ);
+
+ boolean result = authz.hasPermission("object1", permissions);
+
+ assertFalse(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() {
+ Authentication auth = new TestingAuthenticationToken("marissa",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+ authz.setAppCtx(ctx);
+
+ String permissions = new Integer(SimpleAclEntry.DELETE).toString();
+
+ boolean result = authz.hasPermission("object1", permissions);
+
+ assertFalse(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionDeniedWhenSecurityContextEmpty() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ authz.setAppCtx(ctx);
+
+ String permissions = new Long(SimpleAclEntry.ADMINISTRATION).toString();
+
+ boolean result = authz.hasPermission("object1", permissions);
+
+ assertFalse(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testInclusionPermittedWhenDomainObjectIsNull() {
+ authz.setAppCtx(ctx);
+
+ String permissions = new Integer(SimpleAclEntry.READ).toString();
+
+ boolean result = authz.hasPermission(null, permissions);
+
+ assertTrue(result);
+ }
+
+ public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() {
+ Authentication auth = new TestingAuthenticationToken("marissa",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ authz.setAppCtx(ctx);
+
+ String permissions = new Integer(SimpleAclEntry.ADMINISTRATION) + ","
+ + new Integer(SimpleAclEntry.READ);
+
+ boolean result = authz.hasPermission("object1", permissions);
+
+ assertTrue(result);
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ public void testOperationWhenPrincipalHoldsPermissionOfSingleList() {
+ Authentication auth = new TestingAuthenticationToken("marissa",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ authz.setAppCtx(ctx);
+
+ String permissions = new Integer(SimpleAclEntry.READ).toString();
+
+ boolean result = authz.hasPermission("object1", permissions);
+
+ assertTrue(result);
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ /*
+ * Test method for 'com.alibaba.exodus2.web.common.security.pulltool.AuthzImpl.getPrincipal()'
+ */
+ public void testOperationWhenPrincipalIsAString() {
+ Authentication auth = new TestingAuthenticationToken("marissaAsString",
+ "koala", new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ assertEquals("marissaAsString", authz.getPrincipal());
+ }
+
+ public void testOperationWhenPrincipalIsAUserDetailsInstance() {
+ Authentication auth = new TestingAuthenticationToken(new User(
+ "marissaUserDetails", "koala", true, true, true, true,
+ new GrantedAuthority[] {}), "koala",
+ new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ assertEquals("marissaUserDetails", authz.getPrincipal());
+ }
+
+ public void testOperationWhenPrincipalIsNull() {
+ Authentication auth = new TestingAuthenticationToken(null, "koala",
+ new GrantedAuthority[] {});
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ assertNull(authz.getPrincipal());
+ }
+
+ public void testOperationWhenSecurityContextIsNull() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ assertEquals(null, authz.getPrincipal());
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ //~ Inner Classes ==========================================================
+
+ private class MockAclEntry implements AclEntry {
+ private static final long serialVersionUID = 1L;
+
+ // just so AclTag iterates some different types of AclEntrys
+ }
+}