Browse Source

Polish gh-10081

Steve Riesenberg 3 years ago
parent
commit
74e3abc992

+ 7 - 8
acl/src/main/java/org/springframework/security/acls/jdbc/BasicLookupStrategy.java

@@ -35,7 +35,6 @@ import org.springframework.core.convert.ConversionException;
 import org.springframework.core.convert.ConversionService;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.ResultSetExtractor;
-import org.springframework.security.acls.domain.*;
 import org.springframework.security.acls.domain.AccessControlEntryImpl;
 import org.springframework.security.acls.domain.AclAuthorizationStrategy;
 import org.springframework.security.acls.domain.AclImpl;
@@ -43,6 +42,7 @@ import org.springframework.security.acls.domain.AuditLogger;
 import org.springframework.security.acls.domain.DefaultPermissionFactory;
 import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy;
 import org.springframework.security.acls.domain.GrantedAuthoritySid;
+import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
 import org.springframework.security.acls.domain.PermissionFactory;
 import org.springframework.security.acls.domain.PrincipalSid;
 import org.springframework.security.acls.model.AccessControlEntry;
@@ -137,7 +137,6 @@ public class BasicLookupStrategy implements LookupStrategy {
 
 	private AclClassIdUtils aclClassIdUtils;
 
-
 	/**
 	 * Constructor accepting mandatory arguments
 	 * @param dataSource to access the database
@@ -156,9 +155,8 @@ public class BasicLookupStrategy implements LookupStrategy {
 	 * @param aclAuthorizationStrategy authorization strategy (required)
 	 * @param grantingStrategy the PermissionGrantingStrategy
 	 */
-	public  BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
-							   AclAuthorizationStrategy aclAuthorizationStrategy, PermissionGrantingStrategy grantingStrategy) {
-
+	public BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
+			AclAuthorizationStrategy aclAuthorizationStrategy, PermissionGrantingStrategy grantingStrategy) {
 		Assert.notNull(dataSource, "DataSource required");
 		Assert.notNull(aclCache, "AclCache required");
 		Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
@@ -494,8 +492,8 @@ public class BasicLookupStrategy implements LookupStrategy {
 		}
 	}
 
-	public void setObjectIdentityGenerator(ObjectIdentityGenerator objectIdentityGenerator) {
-		Assert.notNull(objectIdentityGenerator,"The provided strategy has to be not null!");
+	public final void setObjectIdentityGenerator(ObjectIdentityGenerator objectIdentityGenerator) {
+		Assert.notNull(objectIdentityGenerator, "objectIdentityGenerator cannot be null");
 		this.objectIdentityGenerator = objectIdentityGenerator;
 	}
 
@@ -580,7 +578,8 @@ public class BasicLookupStrategy implements LookupStrategy {
 				// target id type, e.g. UUID.
 				Serializable identifier = (Serializable) rs.getObject("object_id_identity");
 				identifier = BasicLookupStrategy.this.aclClassIdUtils.identifierFrom(identifier, rs);
-				ObjectIdentity objectIdentity = objectIdentityGenerator.createObjectIdentity(identifier,rs.getString("class"));
+				ObjectIdentity objectIdentity = BasicLookupStrategy.this.objectIdentityGenerator
+						.createObjectIdentity(identifier, rs.getString("class"));
 
 				Acl parentAcl = null;
 				long parentAclId = rs.getLong("parent_object");

+ 126 - 125
acl/src/main/java/org/springframework/security/acls/jdbc/JdbcAclService.java

@@ -51,130 +51,131 @@ import org.springframework.util.Assert;
  */
 public class JdbcAclService implements AclService {
 
-    protected static final Log log = LogFactory.getLog(JdbcAclService.class);
-
-    private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS = "class.class as class";
-
-    private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE = DEFAULT_SELECT_ACL_CLASS_COLUMNS
-            + ", class.class_id_type as class_id_type";
-
-    private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, "
-            + DEFAULT_SELECT_ACL_CLASS_COLUMNS
-            + " from acl_object_identity obj, acl_object_identity parent, acl_class class "
-            + "where obj.parent_object = parent.id and obj.object_id_class = class.id "
-            + "and parent.object_id_identity = ? and parent.object_id_class = ("
-            + "select id FROM acl_class where acl_class.class = ?)";
-
-    private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE = "select obj.object_id_identity as obj_id, "
-            + DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE
-            + " from acl_object_identity obj, acl_object_identity parent, acl_class class "
-            + "where obj.parent_object = parent.id and obj.object_id_class = class.id "
-            + "and parent.object_id_identity = ? and parent.object_id_class = ("
-            + "select id FROM acl_class where acl_class.class = ?)";
-
-    protected final JdbcOperations jdbcOperations;
-
-    private final LookupStrategy lookupStrategy;
-
-    private boolean aclClassIdSupported;
-
-    private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
-
-    private AclClassIdUtils aclClassIdUtils;
-    private ObjectIdentityGenerator objectIdentityGenerator;
-
-    public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
-        this(new JdbcTemplate(dataSource), lookupStrategy);
-    }
-
-    public JdbcAclService(JdbcOperations jdbcOperations, LookupStrategy lookupStrategy) {
-        Assert.notNull(jdbcOperations, "JdbcOperations required");
-        Assert.notNull(lookupStrategy, "LookupStrategy required");
-        this.jdbcOperations = jdbcOperations;
-        this.lookupStrategy = lookupStrategy;
-        this.objectIdentityGenerator = new ObjectIdentityRetrievalStrategyImpl();
-        this.aclClassIdUtils = new AclClassIdUtils();
-    }
-
-    @Override
-    public List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {
-        Object[] args = {parentIdentity.getIdentifier().toString(), parentIdentity.getType()};
-        List<ObjectIdentity> objects = this.jdbcOperations.query(this.findChildrenSql, args,
-                (rs, rowNum) -> mapObjectIdentityRow(rs));
-        return (!objects.isEmpty()) ? objects : null;
-    }
-
-    private ObjectIdentity mapObjectIdentityRow(ResultSet rs) throws SQLException {
-        String javaType = rs.getString("class");
-        Serializable identifier = (Serializable) rs.getObject("obj_id");
-        identifier = this.aclClassIdUtils.identifierFrom(identifier, rs);
-        return objectIdentityGenerator.createObjectIdentity(identifier, javaType);
-    }
-
-    @Override
-    public Acl readAclById(ObjectIdentity object, List<Sid> sids) throws NotFoundException {
-        Map<ObjectIdentity, Acl> map = readAclsById(Collections.singletonList(object), sids);
-        Assert.isTrue(map.containsKey(object),
-                () -> "There should have been an Acl entry for ObjectIdentity " + object);
-        return map.get(object);
-    }
-
-    @Override
-    public Acl readAclById(ObjectIdentity object) throws NotFoundException {
-        return readAclById(object, null);
-    }
-
-    @Override
-    public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects) throws NotFoundException {
-        return readAclsById(objects, null);
-    }
-
-    @Override
-    public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
-            throws NotFoundException {
-        Map<ObjectIdentity, Acl> result = this.lookupStrategy.readAclsById(objects, sids);
-        // Check every requested object identity was found (throw NotFoundException if
-        // needed)
-        for (ObjectIdentity oid : objects) {
-            if (!result.containsKey(oid)) {
-                throw new NotFoundException("Unable to find ACL information for object identity '" + oid + "'");
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Allows customization of the SQL query used to find child object identities.
-     *
-     * @param findChildrenSql
-     */
-    public void setFindChildrenQuery(String findChildrenSql) {
-        this.findChildrenSql = findChildrenSql;
-    }
-
-    public void setAclClassIdSupported(boolean aclClassIdSupported) {
-        this.aclClassIdSupported = aclClassIdSupported;
-        if (aclClassIdSupported) {
-            // Change the default children select if it hasn't been overridden
-            if (this.findChildrenSql.equals(DEFAULT_SELECT_ACL_WITH_PARENT_SQL)) {
-                this.findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE;
-            } else {
-                log.debug("Find children statement has already been overridden, so not overridding the default");
-            }
-        }
-    }
-
-    public void setConversionService(ConversionService conversionService) {
-        this.aclClassIdUtils = new AclClassIdUtils(conversionService);
-    }
-
-    public void setObjectIdentityGenerator(ObjectIdentityGenerator objectIdentityGenerator) {
-        Assert.notNull(objectIdentityGenerator,"The provided strategy has to be not null!");
-        this.objectIdentityGenerator = objectIdentityGenerator;
-    }
-
-    protected boolean isAclClassIdSupported() {
-        return this.aclClassIdSupported;
-    }
+	protected static final Log log = LogFactory.getLog(JdbcAclService.class);
+
+	private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS = "class.class as class";
+
+	private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE = DEFAULT_SELECT_ACL_CLASS_COLUMNS
+			+ ", class.class_id_type as class_id_type";
+
+	private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, "
+			+ DEFAULT_SELECT_ACL_CLASS_COLUMNS
+			+ " from acl_object_identity obj, acl_object_identity parent, acl_class class "
+			+ "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+			+ "and parent.object_id_identity = ? and parent.object_id_class = ("
+			+ "select id FROM acl_class where acl_class.class = ?)";
+
+	private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE = "select obj.object_id_identity as obj_id, "
+			+ DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE
+			+ " from acl_object_identity obj, acl_object_identity parent, acl_class class "
+			+ "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+			+ "and parent.object_id_identity = ? and parent.object_id_class = ("
+			+ "select id FROM acl_class where acl_class.class = ?)";
+
+	protected final JdbcOperations jdbcOperations;
+
+	private final LookupStrategy lookupStrategy;
+
+	private boolean aclClassIdSupported;
+
+	private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
+
+	private AclClassIdUtils aclClassIdUtils;
+
+	private ObjectIdentityGenerator objectIdentityGenerator;
+
+	public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
+		this(new JdbcTemplate(dataSource), lookupStrategy);
+	}
+
+	public JdbcAclService(JdbcOperations jdbcOperations, LookupStrategy lookupStrategy) {
+		Assert.notNull(jdbcOperations, "JdbcOperations required");
+		Assert.notNull(lookupStrategy, "LookupStrategy required");
+		this.jdbcOperations = jdbcOperations;
+		this.lookupStrategy = lookupStrategy;
+		this.aclClassIdUtils = new AclClassIdUtils();
+		this.objectIdentityGenerator = new ObjectIdentityRetrievalStrategyImpl();
+	}
+
+	@Override
+	public List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {
+		Object[] args = { parentIdentity.getIdentifier().toString(), parentIdentity.getType() };
+		List<ObjectIdentity> objects = this.jdbcOperations.query(this.findChildrenSql, args,
+				(rs, rowNum) -> mapObjectIdentityRow(rs));
+		return (!objects.isEmpty()) ? objects : null;
+	}
+
+	private ObjectIdentity mapObjectIdentityRow(ResultSet rs) throws SQLException {
+		String javaType = rs.getString("class");
+		Serializable identifier = (Serializable) rs.getObject("obj_id");
+		identifier = this.aclClassIdUtils.identifierFrom(identifier, rs);
+		return this.objectIdentityGenerator.createObjectIdentity(identifier, javaType);
+	}
+
+	@Override
+	public Acl readAclById(ObjectIdentity object, List<Sid> sids) throws NotFoundException {
+		Map<ObjectIdentity, Acl> map = readAclsById(Collections.singletonList(object), sids);
+		Assert.isTrue(map.containsKey(object),
+				() -> "There should have been an Acl entry for ObjectIdentity " + object);
+		return map.get(object);
+	}
+
+	@Override
+	public Acl readAclById(ObjectIdentity object) throws NotFoundException {
+		return readAclById(object, null);
+	}
+
+	@Override
+	public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects) throws NotFoundException {
+		return readAclsById(objects, null);
+	}
+
+	@Override
+	public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
+			throws NotFoundException {
+		Map<ObjectIdentity, Acl> result = this.lookupStrategy.readAclsById(objects, sids);
+		// Check every requested object identity was found (throw NotFoundException if
+		// needed)
+		for (ObjectIdentity oid : objects) {
+			if (!result.containsKey(oid)) {
+				throw new NotFoundException("Unable to find ACL information for object identity '" + oid + "'");
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Allows customization of the SQL query used to find child object identities.
+	 * @param findChildrenSql
+	 */
+	public void setFindChildrenQuery(String findChildrenSql) {
+		this.findChildrenSql = findChildrenSql;
+	}
+
+	public void setAclClassIdSupported(boolean aclClassIdSupported) {
+		this.aclClassIdSupported = aclClassIdSupported;
+		if (aclClassIdSupported) {
+			// Change the default children select if it hasn't been overridden
+			if (this.findChildrenSql.equals(DEFAULT_SELECT_ACL_WITH_PARENT_SQL)) {
+				this.findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE;
+			}
+			else {
+				log.debug("Find children statement has already been overridden, so not overridding the default");
+			}
+		}
+	}
+
+	public void setConversionService(ConversionService conversionService) {
+		this.aclClassIdUtils = new AclClassIdUtils(conversionService);
+	}
+
+	public void setObjectIdentityGenerator(ObjectIdentityGenerator objectIdentityGenerator) {
+		Assert.notNull(objectIdentityGenerator, "objectIdentityGenerator cannot be null");
+		this.objectIdentityGenerator = objectIdentityGenerator;
+	}
+
+	protected boolean isAclClassIdSupported() {
+		return this.aclClassIdSupported;
+	}
 
 }

+ 9 - 0
acl/src/test/java/org/springframework/security/acls/jdbc/AbstractBasicLookupStrategyTests.java

@@ -320,6 +320,15 @@ public abstract class AbstractBasicLookupStrategyTests {
 		assertThat(((GrantedAuthoritySid) result).getGrantedAuthority()).isEqualTo("sid");
 	}
 
+	@Test
+	public void setObjectIdentityGeneratorWhenNullThenThrowsIllegalArgumentException() {
+		// @formatter:off
+		assertThatIllegalArgumentException()
+				.isThrownBy(() -> this.strategy.setObjectIdentityGenerator(null))
+				.withMessage("objectIdentityGenerator cannot be null");
+		// @formatter:on
+	}
+
 	private static final class CacheManagerMock {
 
 		private final List<String> cacheNames;

+ 21 - 0
acl/src/test/java/org/springframework/security/acls/jdbc/JdbcAclServiceTests.java

@@ -45,6 +45,7 @@ import org.springframework.security.acls.model.Sid;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -170,6 +171,26 @@ public class JdbcAclServiceTests {
 				.isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
 	}
 
+	@Test
+	public void setObjectIdentityGeneratorWhenNullThenThrowsIllegalArgumentException() {
+		assertThatIllegalArgumentException()
+				.isThrownBy(() -> this.aclServiceIntegration.setObjectIdentityGenerator(null))
+				.withMessage("objectIdentityGenerator cannot be null");
+	}
+
+	@Test
+	public void findChildrenWhenObjectIdentityGeneratorSetThenUsed() {
+		this.aclServiceIntegration
+				.setObjectIdentityGenerator((id, type) -> new ObjectIdentityImpl(type, "prefix:" + id));
+
+		ObjectIdentity objectIdentity = new ObjectIdentityImpl("location", "US");
+		this.aclServiceIntegration.setAclClassIdSupported(true);
+		List<ObjectIdentity> objectIdentities = this.aclServiceIntegration.findChildren(objectIdentity);
+		assertThat(objectIdentities.size()).isEqualTo(1);
+		assertThat(objectIdentities.get(0).getType()).isEqualTo("location");
+		assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo("prefix:US-PAL");
+	}
+
 	class MockLongIdDomainObject {
 
 		private Object id;