Browse Source

SEC-932: Added supplied class and test class.

Luke Taylor 17 years ago
parent
commit
b6dec19e90

+ 167 - 0
core/src/main/java/org/springframework/security/authoritymapping/MapBasedAttributes2GrantedAuthoritiesMapper.java

@@ -0,0 +1,167 @@
+package org.springframework.security.authoritymapping;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+
+/**
+ * <p>
+ * This class implements the Attributes2GrantedAuthoritiesMapper and
+ * MappableAttributesRetriever interfaces based on the supplied Map.
+ * It supports both one-to-one and one-to-many mappings. The granted
+ * authorities to map to can be supplied either as a String or as a
+ * GrantedAuthority object.
+ * </p>
+ * @author Ruud Senden
+ */
+public class MapBasedAttributes2GrantedAuthoritiesMapper implements Attributes2GrantedAuthoritiesMapper, MappableAttributesRetriever, InitializingBean {
+	private Map attributes2grantedAuthoritiesMap = null;
+	private String stringSeparator = ",";
+	private String[] mappableAttributes = null;
+
+	/**
+	 * Check whether all properties have been set to correct values, and do some preprocessing.
+	 */
+	public void afterPropertiesSet() {
+		Assert.notEmpty(attributes2grantedAuthoritiesMap,"A non-empty attributes2grantedAuthoritiesMap must be supplied");
+		attributes2grantedAuthoritiesMap = preProcessMap(attributes2grantedAuthoritiesMap);
+		try {
+			mappableAttributes = (String[])attributes2grantedAuthoritiesMap.keySet().toArray(new String[]{});
+		} catch ( ArrayStoreException ase ) {
+			throw new IllegalArgumentException("attributes2grantedAuthoritiesMap contains non-String objects as keys");
+		}
+	}
+
+	/**
+	 * Preprocess the given map
+	 * @param orgMap The map to process
+	 * @return the processed Map
+	 */
+	private Map preProcessMap(Map orgMap) {
+		Map result = new HashMap(orgMap.size());
+		Iterator it = orgMap.entrySet().iterator();
+		while ( it.hasNext() ) {
+			Map.Entry entry = (Map.Entry)it.next();
+			result.put(entry.getKey(),getGrantedAuthorityCollection(entry.getValue()));
+		}
+		return result;
+	}
+
+	/**
+	 * Convert the given value to a collection of Granted Authorities
+	 *
+	 * @param value
+	 *            The value to convert to a GrantedAuthority Collection
+	 * @return Collection containing the GrantedAuthority Collection
+	 */
+	private Collection getGrantedAuthorityCollection(Object value) {
+		Collection result = new ArrayList();
+		addGrantedAuthorityCollection(result,value);
+		return result;
+	}
+
+	/**
+	 * Convert the given value to a collection of Granted Authorities,
+	 * adding the result to the given result collection.
+	 *
+	 * @param value
+	 *            The value to convert to a GrantedAuthority Collection
+	 * @return Collection containing the GrantedAuthority Collection
+	 */
+	private void addGrantedAuthorityCollection(Collection result, Object value) {
+		if ( value != null ) {
+			if ( value instanceof Collection ) {
+				addGrantedAuthorityCollection(result,(Collection)value);
+			} else if ( value instanceof Object[] ) {
+				addGrantedAuthorityCollection(result,(Object[])value);
+			} else if ( value instanceof String ) {
+				addGrantedAuthorityCollection(result,(String)value);
+			} else if ( value instanceof GrantedAuthority ) {
+				result.add(value);
+			} else {
+				throw new IllegalArgumentException("Invalid object type: "+value.getClass().getName());
+			}
+		}
+	}
+
+	private void addGrantedAuthorityCollection(Collection result, Collection value) {
+		Iterator it = value.iterator();
+		while ( it.hasNext() ) {
+			addGrantedAuthorityCollection(result,it.next());
+		}
+	}
+
+	private void addGrantedAuthorityCollection(Collection result, Object[] value) {
+		for ( int i = 0 ; i < value.length ; i++ ) {
+			addGrantedAuthorityCollection(result,value[i]);
+		}
+	}
+
+	private void addGrantedAuthorityCollection(Collection result, String value) {
+		StringTokenizer st = new StringTokenizer(value,stringSeparator,false);
+		while ( st.hasMoreTokens() ) {
+			String nextToken = st.nextToken();
+			if ( StringUtils.hasText(nextToken) ) {
+				result.add(new GrantedAuthorityImpl(nextToken));
+			}
+		}
+	}
+
+	/**
+	 * Map the given array of attributes to Spring Security GrantedAuthorities.
+	 */
+	public GrantedAuthority[] getGrantedAuthorities(String[] attributes) {
+		List gaList = new ArrayList();
+		for (int i = 0; i < attributes.length; i++) {
+			Collection c = (Collection)attributes2grantedAuthoritiesMap.get(attributes[i]);
+			if ( c != null ) { gaList.addAll(c); }
+		}
+		GrantedAuthority[] result = new GrantedAuthority[gaList.size()];
+		result = (GrantedAuthority[])gaList.toArray(result);
+		return result;
+	}
+
+	/**
+	 * @return Returns the attributes2grantedAuthoritiesMap.
+	 */
+	public Map getAttributes2grantedAuthoritiesMap() {
+		return attributes2grantedAuthoritiesMap;
+	}
+	/**
+	 * @param attributes2grantedAuthoritiesMap The attributes2grantedAuthoritiesMap to set.
+	 */
+	public void setAttributes2grantedAuthoritiesMap(Map attributes2grantedAuthoritiesMap) {
+		this.attributes2grantedAuthoritiesMap = attributes2grantedAuthoritiesMap;
+	}
+
+	/**
+	 *
+	 * @see org.springframework.security.authoritymapping.MappableAttributesRetriever#getMappableAttributes()
+	 */
+	public String[] getMappableAttributes() {
+		return mappableAttributes;
+	}
+	/**
+	 * @return Returns the stringSeparator.
+	 */
+	public String getStringSeparator() {
+		return stringSeparator;
+	}
+	/**
+	 * @param stringSeparator The stringSeparator to set.
+	 */
+	public void setStringSeparator(String stringSeparator) {
+		this.stringSeparator = stringSeparator;
+	}
+}

+ 232 - 0
core/src/test/java/org/springframework/security/authoritymapping/MapBasedAttributes2GrantedAuthoritiesMapperTest.java

@@ -0,0 +1,232 @@
+package org.springframework.security.authoritymapping;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+
+/**
+ * 
+ * @author Ruud Senden
+ */
+public class MapBasedAttributes2GrantedAuthoritiesMapperTest extends TestCase {
+
+	protected void setUp() throws Exception {
+		// Set Log4j loglevel to debug to include all logstatements in tests
+		Logger.getRootLogger().setLevel(Level.DEBUG);
+	}
+
+	public final void testAfterPropertiesSetNoMap() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		try {
+			mapper.afterPropertiesSet();
+			fail("Expected exception not thrown");
+		} catch (IllegalArgumentException expected) {
+			// Expected exception
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+	
+	public final void testAfterPropertiesSetEmptyMap() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		mapper.setAttributes2grantedAuthoritiesMap(new HashMap());
+		try {
+			mapper.afterPropertiesSet();
+			fail("Expected exception not thrown");
+		} catch (IllegalArgumentException expected) {
+			// Expected exception
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+	
+	public final void testAfterPropertiesSetInvalidKeyTypeMap() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		HashMap m = new HashMap();
+		m.put(new Object(),"ga1");
+		mapper.setAttributes2grantedAuthoritiesMap(m);
+		try {
+			mapper.afterPropertiesSet();
+			fail("Expected exception not thrown");
+		} catch (IllegalArgumentException expected) {
+			// Expected exception
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+	
+	public final void testAfterPropertiesSetInvalidValueTypeMap1() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		HashMap m = new HashMap();
+		m.put("role1",new Object());
+		mapper.setAttributes2grantedAuthoritiesMap(m);
+		try {
+			mapper.afterPropertiesSet();
+			fail("Expected exception not thrown");
+		} catch (IllegalArgumentException expected) {
+			// Expected exception
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+	
+	public final void testAfterPropertiesSetInvalidValueTypeMap2() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		HashMap m = new HashMap();
+		m.put("role1",new Object[]{new String[]{"ga1","ga2"}, new Object()});
+		mapper.setAttributes2grantedAuthoritiesMap(m);
+		try {
+			mapper.afterPropertiesSet();
+			fail("Expected exception not thrown");
+		} catch (IllegalArgumentException expected) {
+			// Expected exception
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+
+	public final void testAfterPropertiesSetValidMap() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		HashMap m = getValidAttributes2GrantedAuthoritiesMap();
+		mapper.setAttributes2grantedAuthoritiesMap(m);
+		try {
+			mapper.afterPropertiesSet();
+		} catch (Exception unexpected) {
+			fail("Unexpected exception: " + unexpected);
+		}
+	}
+	
+	public final void testMapping1() {
+		String[] roles = { "role1" };
+		String[] expectedGas = { "ga1" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping2() {
+		String[] roles = { "role2" };
+		String[] expectedGas = { "ga2" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping3() {
+		String[] roles = { "role3" };
+		String[] expectedGas = { "ga3", "ga4" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping4() {
+		String[] roles = { "role4" };
+		String[] expectedGas = { "ga5", "ga6" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping5() {
+		String[] roles = { "role5" };
+		String[] expectedGas = { "ga7", "ga8", "ga9" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping6() {
+		String[] roles = { "role6" };
+		String[] expectedGas = { "ga10", "ga11", "ga12" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping7() {
+		String[] roles = { "role7" };
+		String[] expectedGas = { "ga13", "ga14" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping8() {
+		String[] roles = { "role8" };
+		String[] expectedGas = { "ga13", "ga14" };
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping9() {
+		String[] roles = { "role9" };
+		String[] expectedGas = {};
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping10() {
+		String[] roles = { "role10" };
+		String[] expectedGas = {};
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMapping11() {
+		String[] roles = { "role11" };
+		String[] expectedGas = {};
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testNonExistingMapping() {
+		String[] roles = { "nonExisting" };
+		String[] expectedGas = {};
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+	
+	public final void testMappingCombination() {
+		String[] roles = { "role1", "role2", "role3", "role4", "role5", "role6", "role7", "role8", "role9", "role10", "role11" };
+		String[] expectedGas = { "ga1", "ga2", "ga3", "ga4", "ga5", "ga6", "ga7", "ga8", "ga9", "ga10", "ga11", "ga12", "ga13", "ga14"};
+		Attributes2GrantedAuthoritiesMapper mapper = getDefaultMapper();
+		testGetGrantedAuthorities(mapper, roles, expectedGas);
+	}
+
+	private HashMap getValidAttributes2GrantedAuthoritiesMap() {
+		HashMap m = new HashMap();
+		m.put("role1","ga1");
+		m.put("role2",new GrantedAuthorityImpl("ga2"));
+		m.put("role3",Arrays.asList(new Object[]{"ga3",new GrantedAuthorityImpl("ga4")}));
+		m.put("role4","ga5,ga6");
+		m.put("role5",Arrays.asList(new Object[]{"ga7","ga8",new Object[]{new GrantedAuthorityImpl("ga9")}}));
+		m.put("role6",new Object[]{"ga10","ga11",new Object[]{new GrantedAuthorityImpl("ga12")}});
+		m.put("role7",new String[]{"ga13","ga14"});
+		m.put("role8",new String[]{"ga13","ga14",null});
+		m.put("role9",null);
+		m.put("role10",new Object[]{});
+		m.put("role11",Arrays.asList(new Object[]{null}));
+		return m;
+	}
+
+	private MapBasedAttributes2GrantedAuthoritiesMapper getDefaultMapper() {
+		MapBasedAttributes2GrantedAuthoritiesMapper mapper = new MapBasedAttributes2GrantedAuthoritiesMapper();
+		mapper.setAttributes2grantedAuthoritiesMap(getValidAttributes2GrantedAuthoritiesMap());
+		mapper.afterPropertiesSet();
+		return mapper;
+	}
+
+	private void testGetGrantedAuthorities(Attributes2GrantedAuthoritiesMapper mapper, String[] roles, String[] expectedGas) {
+		GrantedAuthority[] result = mapper.getGrantedAuthorities(roles);
+		Collection resultColl = new ArrayList(result.length);
+		for (int i = 0; i < result.length; i++) {
+			resultColl.add(result[i].getAuthority());
+		}
+		Collection expectedColl = Arrays.asList(expectedGas);
+		assertTrue("Role collections do not match; result: " + resultColl + ", expected: " + expectedColl, expectedColl
+				.containsAll(resultColl)
+				&& resultColl.containsAll(expectedColl));
+	}
+}