2
0
Ben Alex 21 жил өмнө
parent
commit
ab01d829c5

+ 157 - 0
core/src/test/java/org/acegisecurity/vote/AbstractAccessDecisionManagerTests.java

@@ -0,0 +1,157 @@
+/* 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 net.sf.acegisecurity.vote;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.AccessDeniedException;
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.ConfigAttribute;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.SecurityConfig;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.util.List;
+import java.util.Vector;
+
+
+/**
+ * Tests {@link AbstractAccessDecisionManager}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class AbstractAccessDecisionManagerTests extends TestCase {
+    //~ Constructors ===========================================================
+
+    public AbstractAccessDecisionManagerTests() {
+        super();
+    }
+
+    public AbstractAccessDecisionManagerTests(String arg0) {
+        super(arg0);
+    }
+
+    //~ Methods ================================================================
+
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(AbstractAccessDecisionManagerTests.class);
+    }
+
+    public void testAllowIfAccessDecisionManagerDefaults()
+        throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+        assertTrue(!mock.isAllowIfAllAbstainDecisions()); // default
+        mock.setAllowIfAllAbstainDecisions(true);
+        assertTrue(mock.isAllowIfAllAbstainDecisions()); // changed
+    }
+
+    public void testDelegatesSupportsRequests() throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+        List list = new Vector();
+        DenyVoter voter = new DenyVoter();
+        DenyAgainVoter denyVoter = new DenyAgainVoter();
+        list.add(voter);
+        list.add(denyVoter);
+        mock.setDecisionVoters(list);
+
+        ConfigAttribute attr = new SecurityConfig("DENY_AGAIN_FOR_SURE");
+        assertTrue(mock.supports(attr));
+
+        ConfigAttribute badAttr = new SecurityConfig("WE_DONT_SUPPORT_THIS");
+        assertTrue(!mock.supports(badAttr));
+    }
+
+    public void testProperlyStoresListOfVoters() throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+        List list = new Vector();
+        DenyVoter voter = new DenyVoter();
+        DenyAgainVoter denyVoter = new DenyAgainVoter();
+        list.add(voter);
+        list.add(denyVoter);
+        mock.setDecisionVoters(list);
+        assertEquals(list.size(), mock.getDecisionVoters().size());
+    }
+
+    public void testRejectsEmptyList() throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+        List list = new Vector();
+
+        try {
+            mock.setDecisionVoters(list);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testRejectsListContainingInvalidObjectTypes()
+        throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+        List list = new Vector();
+        DenyVoter voter = new DenyVoter();
+        DenyAgainVoter denyVoter = new DenyAgainVoter();
+        String notAVoter = "NOT_A_VOTER";
+        list.add(voter);
+        list.add(notAVoter);
+        list.add(denyVoter);
+
+        try {
+            mock.setDecisionVoters(list);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testRejectsNullVotersList() throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+
+        try {
+            mock.setDecisionVoters(null);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testWillNotStartIfDecisionVotersNotSet()
+        throws Exception {
+        MockDecisionManagerImpl mock = new MockDecisionManagerImpl();
+
+        try {
+            mock.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+    }
+
+    //~ Inner Classes ==========================================================
+
+    private class MockDecisionManagerImpl extends AbstractAccessDecisionManager {
+        public void decide(Authentication authentication,
+            MethodInvocation invocation, ConfigAttributeDefinition config)
+            throws AccessDeniedException {
+            return;
+        }
+    }
+}

+ 163 - 0
core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java

@@ -0,0 +1,163 @@
+/* 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 net.sf.acegisecurity.vote;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.AccessDeniedException;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.GrantedAuthority;
+import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.SecurityConfig;
+import net.sf.acegisecurity.providers.TestingAuthenticationToken;
+
+import java.util.List;
+import java.util.Vector;
+
+
+/**
+ * Tests {@link AffirmativeBased}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class AffirmativeBasedTests extends TestCase {
+    //~ Constructors ===========================================================
+
+    public AffirmativeBasedTests() {
+        super();
+    }
+
+    public AffirmativeBasedTests(String arg0) {
+        super(arg0);
+    }
+
+    //~ Methods ================================================================
+
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(AffirmativeBasedTests.class);
+    }
+
+    public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("DENY_FOR_SURE")); // deny
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testOneAffirmativeVoteTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testOneDenyVoteTwoAbstainVotesDeniesAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesDeniesAccessWithDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+
+        assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesGrantsAccessWithoutDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+        mgr.setAllowIfAllAbstainDecisions(true);
+        assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testTwoAffirmativeVotesTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        AffirmativeBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    private AffirmativeBased makeDecisionManager() {
+        AffirmativeBased decisionManager = new AffirmativeBased();
+        RoleVoter roleVoter = new RoleVoter();
+        DenyVoter denyForSureVoter = new DenyVoter();
+        DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
+        List voters = new Vector();
+        voters.add(roleVoter);
+        voters.add(denyForSureVoter);
+        voters.add(denyAgainForSureVoter);
+        decisionManager.setDecisionVoters(voters);
+
+        return decisionManager;
+    }
+
+    private TestingAuthenticationToken makeTestToken() {
+        return new TestingAuthenticationToken("somebody", "password",
+            new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
+                    "ROLE_2")});
+    }
+}

+ 184 - 0
core/src/test/java/org/acegisecurity/vote/ConsensusBasedTests.java

@@ -0,0 +1,184 @@
+/* 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 net.sf.acegisecurity.vote;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.AccessDeniedException;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.GrantedAuthority;
+import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.SecurityConfig;
+import net.sf.acegisecurity.providers.TestingAuthenticationToken;
+
+import java.util.List;
+import java.util.Vector;
+
+
+/**
+ * Tests {@link ConsensusBased}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class ConsensusBasedTests extends TestCase {
+    //~ Constructors ===========================================================
+
+    public ConsensusBasedTests() {
+        super();
+    }
+
+    public ConsensusBasedTests(String arg0) {
+        super(arg0);
+    }
+
+    //~ Methods ================================================================
+
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(ConsensusBasedTests.class);
+    }
+
+    public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteDeniesAccessWithoutDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+        mgr.setAllowIfEqualGrantedDeniedDecisions(false);
+        assertTrue(!mgr.isAllowIfEqualGrantedDeniedDecisions()); // check changed
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("DENY_FOR_SURE")); // deny
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteGrantsAccessWithDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+
+        assertTrue(mgr.isAllowIfEqualGrantedDeniedDecisions()); // check default
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("DENY_FOR_SURE")); // deny
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testOneAffirmativeVoteTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testOneDenyVoteTwoAbstainVotesDeniesAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesDeniesAccessWithDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+
+        assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesGrantsAccessWithoutDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+        mgr.setAllowIfAllAbstainDecisions(true);
+        assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testTwoAffirmativeVotesTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        ConsensusBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    private ConsensusBased makeDecisionManager() {
+        ConsensusBased decisionManager = new ConsensusBased();
+        RoleVoter roleVoter = new RoleVoter();
+        DenyVoter denyForSureVoter = new DenyVoter();
+        DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
+        List voters = new Vector();
+        voters.add(roleVoter);
+        voters.add(denyForSureVoter);
+        voters.add(denyAgainForSureVoter);
+        decisionManager.setDecisionVoters(voters);
+
+        return decisionManager;
+    }
+
+    private TestingAuthenticationToken makeTestToken() {
+        return new TestingAuthenticationToken("somebody", "password",
+            new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
+                    "ROLE_2")});
+    }
+}

+ 67 - 0
core/src/test/java/org/acegisecurity/vote/DenyAgainVoter.java

@@ -0,0 +1,67 @@
+/* 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 net.sf.acegisecurity.vote;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.ConfigAttribute;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.util.Iterator;
+
+
+/**
+ * Implementation of an {@link AccessDecisionVoter} for unit testing.
+ * 
+ * <p>
+ * If the {@link ConfigAttribute#getAttribute()} has a value of
+ * <code>DENY_AGAIN_FOR_SURE</code>, the voter will vote to deny access.
+ * </p>
+ * 
+ * <p>
+ * All comparisons are case sensitive.
+ * </p>
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class DenyAgainVoter implements AccessDecisionVoter {
+    //~ Methods ================================================================
+
+    public boolean supports(ConfigAttribute attribute) {
+        if ("DENY_AGAIN_FOR_SURE".equals(attribute.getAttribute())) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public int vote(Authentication authentication, MethodInvocation invocation,
+        ConfigAttributeDefinition config) {
+        Iterator iter = config.getConfigAttributes();
+
+        while (iter.hasNext()) {
+            ConfigAttribute attribute = (ConfigAttribute) iter.next();
+
+            if (this.supports(attribute)) {
+                return ACCESS_DENIED;
+            }
+        }
+
+        return ACCESS_ABSTAIN;
+    }
+}

+ 167 - 0
core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java

@@ -0,0 +1,167 @@
+/* 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 net.sf.acegisecurity.vote;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.AccessDeniedException;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.GrantedAuthority;
+import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.SecurityConfig;
+import net.sf.acegisecurity.providers.TestingAuthenticationToken;
+
+import java.util.List;
+import java.util.Vector;
+
+
+/**
+ * Tests {@link UnanimousBased}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class UnanimousBasedTests extends TestCase {
+    //~ Constructors ===========================================================
+
+    public UnanimousBasedTests() {
+        super();
+    }
+
+    public UnanimousBasedTests(String arg0) {
+        super(arg0);
+    }
+
+    //~ Methods ================================================================
+
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(UnanimousBasedTests.class);
+    }
+
+    public void testOneAffirmativeVoteOneDenyVoteOneAbstainVoteDeniesAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("DENY_FOR_SURE")); // deny
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testOneAffirmativeVoteTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testOneDenyVoteTwoAbstainVotesDeniesAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesDeniesAccessWithDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+
+        assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        try {
+            mgr.decide(auth, null, config);
+            fail("Should have thrown AccessDeniedException");
+        } catch (AccessDeniedException expected) {
+            assertTrue(true);
+        }
+    }
+
+    public void testThreeAbstainVotesGrantsAccessWithoutDefault()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+        mgr.setAllowIfAllAbstainDecisions(true);
+        assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("IGNORED_BY_ALL")); // abstain
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    public void testTwoAffirmativeVotesTwoAbstainVotesGrantsAccess()
+        throws Exception {
+        TestingAuthenticationToken auth = makeTestToken();
+        UnanimousBased mgr = makeDecisionManager();
+
+        ConfigAttributeDefinition config = new ConfigAttributeDefinition();
+        config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
+        config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
+
+        mgr.decide(auth, null, config);
+        assertTrue(true);
+    }
+
+    private UnanimousBased makeDecisionManager() {
+        UnanimousBased decisionManager = new UnanimousBased();
+        RoleVoter roleVoter = new RoleVoter();
+        DenyVoter denyForSureVoter = new DenyVoter();
+        DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
+        List voters = new Vector();
+        voters.add(roleVoter);
+        voters.add(denyForSureVoter);
+        voters.add(denyAgainForSureVoter);
+        decisionManager.setDecisionVoters(voters);
+
+        return decisionManager;
+    }
+
+    private TestingAuthenticationToken makeTestToken() {
+        return new TestingAuthenticationToken("somebody", "password",
+            new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_1"), new GrantedAuthorityImpl(
+                    "ROLE_2")});
+    }
+}