Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48cd912607 |
-21
@@ -1,21 +0,0 @@
|
||||
target/
|
||||
*/src/*/java/META-INF
|
||||
*/src/META-INF/
|
||||
*/src/*/java/META-INF/
|
||||
.classpath
|
||||
.springBeans
|
||||
.project
|
||||
.DS_Store
|
||||
.settings/
|
||||
.idea/
|
||||
out/
|
||||
bin/
|
||||
intellij/
|
||||
build/
|
||||
*.log
|
||||
*.log.*
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.gradle/
|
||||
atlassian-ide-plugin.xml
|
||||
-186
@@ -1,186 +0,0 @@
|
||||
_Have something you'd like to contribute to the framework? We welcome pull requests, but ask that you carefully read this document first to understand how best to submit them; what kind of changes are likely to be accepted; and what to expect from the Spring Security team when evaluating your submission._
|
||||
|
||||
_Please refer back to this document as a checklist before issuing any pull request; this will save time for everyone!_
|
||||
|
||||
# Similar but different
|
||||
|
||||
Each Spring module is slightly different than another in terms of team size, number of issues, etc. Therefore each project is managed slightly different. You will notice that this document is very similar to the [Spring Framework Contributor guidelines](https://github.com/SpringSource/spring-framework/wiki/Contributor-guidelines). However, there are some subtle differences between the two documents, so please be sure to read this document thoroughly.
|
||||
|
||||
# Understand the basics
|
||||
Not sure what a pull request is, or how to submit one? Take a look at GitHub's excellent [help documentation first](https://help.github.com/articles/using-pull-requests).
|
||||
|
||||
# Search JIRA first; create an issue if necessary
|
||||
Is there already an issue that addresses your concern? Do a bit of searching in our [JIRA issue tracker](https://jira.springsource.org/browse/SEC) to see if you can find something similar. If not, please create a new issue before submitting a pull request unless the change is not a user facing issue.
|
||||
|
||||
# Discuss non-trivial contribution ideas with committers
|
||||
If you're considering anything more than correcting a typo or fixing a minor bug , please discuss it on the [Spring Security forums](http://forum.springsource.org/forumdisplay.php?33-Security) before submitting a pull request. We're happy to provide guidance but please spend an hour or two researching the subject on your own including searching the forums for prior discussions.
|
||||
|
||||
# Sign the Contributor License Agreement
|
||||
If you have not previously done so, please fill out and submit the [SpringSource CLA form](https://support.springsource.com/spring_committer_signup). You'll receive a token when this process is complete. Keep track of this, you may be asked for it later!
|
||||
|
||||
* For **Project** select _Spring Security_
|
||||
* For **Project Lead** enter _Rob Winch_
|
||||
* Note that emailing/postal mailing a signed copy is not necessary. Submission of the web form is all that is required.
|
||||
|
||||
When you've completed the web form, simply add the following in a comment on your pull request:
|
||||
|
||||
> I have signed and agree to the terms of the SpringSource Individual Contributor License Agreement.
|
||||
|
||||
You do not need to include your token/id. Please add the statement above to all future pull requests as well, simply so the Spring Security team knows immediately that this process is complete.
|
||||
|
||||
# Create your branch from master
|
||||
Create your topic branch to be submitted as a pull request from master. The Spring team will consider your pull request for backporting on a case-by-case basis; you don't need to worry about submitting anything for backporting.
|
||||
|
||||
# Use short branch names
|
||||
Branches used when submitting pull requests should preferably be named according to JIRA issues, e.g. 'SEC-1234'. Otherwise, use succinct, lower-case, dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. This is important, because branch names show up in the merge commits that result from accepting pull requests, and should be as expressive and concise as possible.
|
||||
|
||||
#Keep commits focused
|
||||
|
||||
Remember each JIRA should be focused on a single item of interest since the JIRA tickets are used to produce the changelog. Since each commit should be tied to a JIRA, ensure that your commits are focused. For example, do not include an update to a transitive library in your commit unless the JIRA is to update the library. Reviewing your commits is essential before sending a pull request.
|
||||
|
||||
# Mind the whitespace
|
||||
Please carefully follow the whitespace and formatting conventions already present in the framework.
|
||||
|
||||
1. Spaces, not tabs
|
||||
1. Unix (LF), not dos (CRLF) line endings
|
||||
1. Eliminate all trailing whitespace
|
||||
1. Aim to wrap code at 120 characters, but favor readability over wrapping
|
||||
1. Preserve existing formatting; i.e. do not reformat code for its own sake
|
||||
1. Search the codebase using git grep and other tools to discover common naming conventions, etc.
|
||||
1. Latin-1 (ISO-8859-1) encoding for Java sources; use native2ascii to convert if necessary
|
||||
|
||||
Whitespace management tips
|
||||
|
||||
1. You can use the [AnyEdit Eclipse plugin](http://marketplace.eclipse.org/content/anyedit-tools) to ensure spaces are used and to clean up trailing whitespaces.
|
||||
1. Use git's pre-commit.sample hook to prevent invalid whitespace from being pushed out. You can enable it by moving ~/spring-security/.git/hooks/pre-commit.sample to ~/spring-security/.git/hooks/pre-commit and ensuring it is executable. For more information on hooks refer to [Pro Git's Pre-Commit Hook's section](http://git-scm.com/book/cs/ch7-3.html)
|
||||
|
||||
# Add Apache license header to all new classes
|
||||
|
||||
<pre>
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* 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 ...;
|
||||
</pre>
|
||||
# Update Apache license header to modified files as necessary
|
||||
Always check the date range in the license header. For example, if you've modified a file in 2012 whose header still reads
|
||||
<pre>
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
</pre>
|
||||
then be sure to update it to 2012 appropriately
|
||||
<pre>
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
</pre>
|
||||
# Use @since tags for newly-added public API types and methods
|
||||
e.g.
|
||||
<pre>
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @author First Last
|
||||
* @since 3.2
|
||||
* @see ...
|
||||
*/
|
||||
</pre>
|
||||
|
||||
#Submit JUnit test cases for all behavior changes
|
||||
Search the codebase to find related unit tests and add additional `@Test` methods within.
|
||||
|
||||
1. Any new tests should end in the name Tests (note this is plural). For example, a valid name would be `FilterChainProxyTests`. An invalid name would be `FilterChainProxyTest`.
|
||||
2. New test methods should not start with test. This is an old JUnit3 convention and is not necessary since the method is annotated with @Test.
|
||||
|
||||
# Squash commits
|
||||
Use git rebase --interactive, git add --patch and other tools to "squash" multiple commits into atomic changes. In addition to the man pages for git, there are many resources online to help you understand how these tools work. Here is one: http://book.git-scm.com/4_interactive_rebasing.html.
|
||||
|
||||
# Use real name in git commits
|
||||
Please configure git to use your real first and last name for any commits you intend to submit as pull requests. For example, this is not acceptable:
|
||||
|
||||
<pre>
|
||||
Author: Nickname <user@mail.com>
|
||||
</pre>
|
||||
Rather, please include your first and last name, properly capitalized, as submitted against the SpringSource contributor license agreement:
|
||||
<pre>
|
||||
Author: First Last <user@mail.com>
|
||||
</pre>
|
||||
This helps ensure traceability against the CLA, and also goes a long way to ensuring useful output from tools like git shortlog and others.
|
||||
|
||||
You can configure this globally via the account admin area GitHub (useful for fork-and-edit cases); globally with
|
||||
|
||||
<pre>
|
||||
git config --global user.name "First Last"
|
||||
git config --global user.email user@mail.com
|
||||
</pre>
|
||||
|
||||
or locally for the spring-security repository only by omitting the '--global' flag:
|
||||
<pre>
|
||||
cd spring-security
|
||||
git config user.name "First Last"
|
||||
git config user.email user@mail.com
|
||||
</pre>
|
||||
|
||||
# Format commit messages
|
||||
|
||||
<pre>
|
||||
SEC-1234: Short (50 chars or less) summary of changes
|
||||
|
||||
More detailed explanatory text, if necessary. Wrap it to about 72
|
||||
characters or so. In some contexts, the first line is treated as the
|
||||
subject of an email and the rest of the text as the body. The blank
|
||||
line separating the summary from the body is critical (unless you omit
|
||||
the body entirely); tools like rebase can get confused if you run the
|
||||
two together.
|
||||
|
||||
Further paragraphs come after blank lines.
|
||||
|
||||
- Bullet points are okay, too
|
||||
|
||||
- Typically a hyphen or asterisk is used for the bullet, preceded by a
|
||||
single space, with blank lines in between, but conventions vary here
|
||||
</pre>
|
||||
|
||||
|
||||
1. The commit subject should start with the associated jira issue followed by a : as shown in the example above
|
||||
2. Keep the subject line to 50 characters or less if possible
|
||||
3. Do not end the subject line with a period
|
||||
4. In the body of the commit message, explain how things worked before this commit, what has changed, and how things work now
|
||||
|
||||
# Run all tests prior to submission
|
||||
|
||||
<pre>
|
||||
cd spring-security
|
||||
./gradlew clean build integrationTest
|
||||
</pre>
|
||||
|
||||
# Submit your pull request
|
||||
Subject line:
|
||||
|
||||
Follow the same conventions for pull request subject lines as mentioned above for commit message subject lines.
|
||||
|
||||
In the body:
|
||||
|
||||
1. Explain your use case. What led you to submit this change? Why were existing mechanisms in the framework insufficient? Make a case that this is a general-purpose problem and that yours is a general-purpose solution, etc
|
||||
2. Add any additional information and ask questions; start a conversation, or continue one from JIRA
|
||||
3. Mention the JIRA issue ID
|
||||
4. Also mention that you have submitted the CLA as described above
|
||||
Note that for pull requests containing a single commit, GitHub will default the subject line and body of the pull request to match the subject line and body of the commit message. This is fine, but please also include the items above in the body of the request.
|
||||
|
||||
# Mention your pull request on the associated JIRA issue
|
||||
Add a comment to the associated JIRA issue(s) linking to your new pull request.
|
||||
|
||||
# Expect discussion and rework
|
||||
The Spring team takes a very conservative approach to accepting contributions to the framework. This is to keep code quality and stability as high as possible, and to keep complexity at a minimum. Your changes, if accepted, may be heavily modified prior to merging. You will retain "Author:" attribution for your Git commits granted that the bulk of your changes remain intact. You may be asked to rework the submission for style (as explained above) and/or substance. Again, we strongly recommend discussing any serious submissions with the Spring Framework team prior to engaging in serious development work.
|
||||
|
||||
Note that you can always force push (git push -f) reworked / rebased commits against the branch used to submit your pull request. i.e. you do not need to issue a new pull request when asked to make changes.
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
= Spring Security
|
||||
|
||||
Spring Security provides security services for the http://docs.spring.io[Spring IO Platform]. Spring Security 3.1 requires Spring 3.0.3 as
|
||||
a minimum and also requires Java 5.
|
||||
|
||||
For a detailed list of features and access to the latest release, please visit http://spring.io/projects[Spring projects].
|
||||
|
||||
== Downloading Artifacts
|
||||
See https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts[downloading Spring artifacts] for Maven repository information.
|
||||
|
||||
== Documentation
|
||||
Be sure to read the http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/[Spring Security Reference].
|
||||
Extensive JavaDoc for the Spring Security code is also available in the http://docs.spring.io/spring-security/site/docs/current/apidocs/[Spring Security API Documentation].
|
||||
|
||||
== Quick Start
|
||||
We recommend you visit http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/[Spring Security Reference] and read the "Getting Started" page.
|
||||
|
||||
== Building from Source
|
||||
Spring Security uses a http://gradle.org[Gradle]-based build system.
|
||||
In the instructions below, http://vimeo.com/34436402[`./gradlew`] is invoked from the root of the source tree and serves as
|
||||
a cross-platform, self-contained bootstrap mechanism for the build.
|
||||
|
||||
=== Prerequisites
|
||||
http://help.github.com/set-up-git-redirect[Git] and the http://www.oracle.com/technetwork/java/javase/downloads[JDK7 build].
|
||||
|
||||
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.7.0` folder extracted from the JDK download.
|
||||
|
||||
=== Check out sources
|
||||
[indent=0]
|
||||
----
|
||||
git clone git@github.com:spring-projects/spring-security.git
|
||||
----
|
||||
|
||||
=== Install all spring-\* jars into your local Maven cache
|
||||
[indent=0]
|
||||
----
|
||||
./gradlew install
|
||||
----
|
||||
|
||||
=== Compile and test; build all jars, distribution zips, and docs
|
||||
[indent=0]
|
||||
----
|
||||
./gradlew build
|
||||
----
|
||||
|
||||
Discover more commands with `./gradlew tasks`.
|
||||
See also the https://github.com/spring-projects/spring-framework/wiki/Gradle-build-and-release-FAQ[Gradle build and release FAQ].
|
||||
|
||||
== Getting Support
|
||||
Check out the http://stackoverflow.com/questions/tagged/spring-security[Spring Security tags on Stack Overflow].
|
||||
http://spring.io/services[Commercial support] is available too.
|
||||
|
||||
== Contributing
|
||||
http://help.github.com/send-pull-requests[Pull requests] are welcome; see the https://github.com/spring-projects/spring-security/blob/master/CONTRIBUTING.md[contributor guidelines] for details.
|
||||
|
||||
== License
|
||||
Spring Security is Open Source software released under the
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
|
||||
@@ -1,19 +0,0 @@
|
||||
// Acl Module build file
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
springCoreDependency,
|
||||
'aopalliance:aopalliance:1.0',
|
||||
"org.springframework:spring-aop:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion"
|
||||
|
||||
optional "net.sf.ehcache:ehcache-core:$ehcacheVersion"
|
||||
|
||||
testCompile "org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-context-support:$springVersion",
|
||||
"org.springframework:spring-test:$springVersion"
|
||||
|
||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
||||
}
|
||||
+67
-162
@@ -1,163 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
<version>3.2.6.RELEASE</version>
|
||||
<name>spring-security-acl</name>
|
||||
<description>spring-security-acl</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
<organization>
|
||||
<name>spring.io</name>
|
||||
<url>http://spring.io/</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>rwinch</id>
|
||||
<name>Rob Winch</name>
|
||||
<email>rwinch@gopivotal.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/spring-projects/spring-security</connection>
|
||||
<developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>
|
||||
<url>https://github.com/spring-projects/spring-security</url>
|
||||
</scm>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
<artifactId>aopalliance</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>3.2.6.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>0.9.29</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easytesting</groupId>
|
||||
<artifactId>fest-assert</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<version>3.0.0.RC1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
<name>Spring Security - ACL module</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>8.3-603.jdbc3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.security.access.AuthorizationServiceException;
|
||||
@@ -81,6 +80,7 @@ import org.springframework.util.StringUtils;
|
||||
* <p>All comparisons and prefixes are case sensitive.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclEntryVoter extends AbstractAclVoter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -146,10 +146,14 @@ public class AclEntryVoter extends AbstractAclVoter {
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
return (attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute());
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
|
||||
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
|
||||
|
||||
for(ConfigAttribute attr : attributes) {
|
||||
|
||||
@@ -174,7 +178,7 @@ public class AclEntryVoter extends AbstractAclVoter {
|
||||
try {
|
||||
Class<?> clazz = domainObject.getClass();
|
||||
Method method = clazz.getMethod(internalMethod, new Class[0]);
|
||||
domainObject = method.invoke(domainObject);
|
||||
domainObject = method.invoke(domainObject, new Object[0]);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new AuthorizationServiceException("Object of class '" + domainObject.getClass()
|
||||
+ "' does not provide the requested internalMethod: " + internalMethod);
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.security.access.PermissionCacheOptimizer;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.AclService;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
* Batch loads ACLs for collections of objects to allow optimised filtering.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @since 3.1
|
||||
*/
|
||||
public class AclPermissionCacheOptimizer implements PermissionCacheOptimizer {
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
private final AclService aclService;
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
private ObjectIdentityRetrievalStrategy oidRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
public AclPermissionCacheOptimizer(AclService aclService) {
|
||||
this.aclService = aclService;
|
||||
}
|
||||
|
||||
public void cachePermissionsFor(Authentication authentication, Collection<?> objects) {
|
||||
if (objects.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ObjectIdentity> oidsToCache = new ArrayList<ObjectIdentity>(objects.size());
|
||||
|
||||
for (Object domainObject : objects) {
|
||||
if (domainObject == null) {
|
||||
continue;
|
||||
}
|
||||
ObjectIdentity oid = oidRetrievalStrategy.getObjectIdentity(domainObject);
|
||||
oidsToCache.add(oid);
|
||||
}
|
||||
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Eagerly loading Acls for " + oidsToCache.size() + " objects");
|
||||
}
|
||||
|
||||
aclService.readAclsById(oidsToCache, sids);
|
||||
}
|
||||
|
||||
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
this.oidRetrievalStrategy = objectIdentityRetrievalStrategy;
|
||||
}
|
||||
|
||||
public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
|
||||
this.sidRetrievalStrategy = sidRetrievalStrategy;
|
||||
}
|
||||
}
|
||||
@@ -28,13 +28,14 @@ import org.springframework.security.core.Authentication;
|
||||
* {@link org.springframework.security.acls.AclEntryVoter AclEntryVoter}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AclPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final AclService aclService;
|
||||
private AclService aclService;
|
||||
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
private ObjectIdentityGenerator objectIdentityGenerator = new ObjectIdentityRetrievalStrategyImpl();
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
@@ -70,30 +71,24 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
List<Permission> requiredPermission = resolvePermission(permission);
|
||||
|
||||
final boolean debug = logger.isDebugEnabled();
|
||||
|
||||
if (debug) {
|
||||
logger.debug("Checking permission '" + permission + "' for object '" + oid + "'");
|
||||
}
|
||||
|
||||
try {
|
||||
// Lookup only ACLs for SIDs we're interested in
|
||||
Acl acl = aclService.readAclById(oid, sids);
|
||||
|
||||
if (acl.isGranted(requiredPermission, sids, false)) {
|
||||
if (debug) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Access is granted");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Returning false - ACLs returned, but insufficient permissions for this principal");
|
||||
}
|
||||
|
||||
} catch (NotFoundException nfe) {
|
||||
if (debug) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Returning false - no ACLs apply for this principal");
|
||||
}
|
||||
}
|
||||
@@ -117,7 +112,7 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
if (permission instanceof String) {
|
||||
String permString = (String)permission;
|
||||
Permission p;
|
||||
Permission p = null;
|
||||
|
||||
try {
|
||||
p = permissionFactory.buildFromName(permString);
|
||||
|
||||
+6
-3
@@ -39,16 +39,17 @@ import org.springframework.util.Assert;
|
||||
* Abstract {@link AfterInvocationProvider} which provides commonly-used ACL-related services.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected final AclService aclService;
|
||||
protected AclService aclService;
|
||||
protected Class<?> processDomainObjectClass = Object.class;
|
||||
protected ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
protected SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
protected String processConfigAttribute;
|
||||
protected final List<Permission> requirePermission;
|
||||
protected List<Permission> requirePermission = Arrays.asList(BasePermission.READ);
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -78,9 +79,11 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
||||
// Obtain the SIDs applicable to the principal
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
|
||||
Acl acl = null;
|
||||
|
||||
try {
|
||||
// Lookup only ACLs for SIDs we're interested in
|
||||
Acl acl = aclService.readAclById(objectIdentity, sids);
|
||||
acl = aclService.readAclById(objectIdentity, sids);
|
||||
|
||||
return acl.isGranted(requirePermission, sids, false);
|
||||
} catch (NotFoundException ignore) {
|
||||
|
||||
+6
-2
@@ -38,7 +38,8 @@ import org.springframework.security.core.Authentication;
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclService</code> and ensure the
|
||||
* principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean) Acl.isGranted()}
|
||||
* principal is {@link org.springframework.security.acls.Acl#isGranted(List,
|
||||
* List, boolean) Acl.isGranted(Permission[], Sid[], boolean)}
|
||||
* when presenting the {@link #requirePermission} array to that method.
|
||||
* <p>
|
||||
* If the principal does not have permission, that element will not be included in the returned
|
||||
@@ -56,6 +57,7 @@ import org.springframework.security.core.Authentication;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclEntryAfterInvocationCollectionFilteringProvider extends AbstractAclProvider {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -75,7 +77,9 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends Abstract
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
|
||||
if (returnedObject == null) {
|
||||
logger.debug("Return object is null, skipping");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Return object is null, skipping");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
+12
-7
@@ -39,10 +39,11 @@ import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <tt>AclService</tt> and ensure the
|
||||
* principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean)
|
||||
* Acl.isGranted(List, List, boolean)} when presenting the {@link #requirePermission} array to that method.
|
||||
* principal is {@link org.springframework.security.acls.Acl#isGranted(List,
|
||||
List, boolean) Acl.isGranted(Permission[], Sid[], boolean)}
|
||||
* when presenting the {@link #requirePermission} array to that method.
|
||||
* <p>
|
||||
* Often users will set up an <code>AclEntryAfterInvocationProvider</code> with a {@link
|
||||
* Often users will setup an <code>AclEntryAfterInvocationProvider</code> with a {@link
|
||||
* #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a {@link #requirePermission} of
|
||||
* <code>BasePermission.READ</code>. These are also the defaults.
|
||||
* <p>
|
||||
@@ -65,7 +66,7 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AclEntryAfterInvocationProvider(AclService aclService, List<Permission> requirePermission) {
|
||||
this(aclService, "AFTER_ACL_READ", requirePermission);
|
||||
super(aclService, "AFTER_ACL_READ", requirePermission);
|
||||
}
|
||||
|
||||
public AclEntryAfterInvocationProvider(AclService aclService, String processConfigAttribute,
|
||||
@@ -81,13 +82,17 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
||||
if (returnedObject == null) {
|
||||
// AclManager interface contract prohibits nulls
|
||||
// As they have permission to null/nothing, grant access
|
||||
logger.debug("Return object is null, skipping");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Return object is null, skipping");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!getProcessDomainObjectClass().isAssignableFrom(returnedObject.getClass())) {
|
||||
logger.debug("Return object is not applicable for this provider, skipping");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Return object is not applicable for this provider, skipping");
|
||||
}
|
||||
|
||||
return returnedObject;
|
||||
}
|
||||
@@ -104,7 +109,7 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
||||
|
||||
logger.debug("Denying access");
|
||||
|
||||
throw new AccessDeniedException(messages.getMessage("AclEntryAfterInvocationProvider.noPermission",
|
||||
throw new AccessDeniedException(messages.getMessage("BasicAclEntryAfterInvocationProvider.noPermission",
|
||||
new Object[] {authentication.getName(), returnedObject},
|
||||
"Authentication {0} has NO permissions to the domain object {1}"));
|
||||
}
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
class ArrayFilterer<T> implements Filterer<T> {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -95,7 +96,7 @@ class ArrayFilterer<T> implements Filterer<T> {
|
||||
}
|
||||
|
||||
public T next() {
|
||||
if (!hasNext()) {
|
||||
if (hasNext() == false) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return list[index++];
|
||||
|
||||
+9
-3
@@ -29,6 +29,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
class CollectionFilterer<T> implements Filterer<T> {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -37,9 +38,12 @@ class CollectionFilterer<T> implements Filterer<T> {
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Collection<T> collection;
|
||||
private Collection<T> collection;
|
||||
|
||||
private final Set<T> removeList;
|
||||
// collectionIter offers significant performance optimisations (as
|
||||
// per security-developer mailing list conversation 19/5/05)
|
||||
private Iterator<T> collectionIter;
|
||||
private Set<T> removeList;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -85,7 +89,9 @@ class CollectionFilterer<T> implements Filterer<T> {
|
||||
* @see org.springframework.security.acls.afterinvocation.Filterer#iterator()
|
||||
*/
|
||||
public Iterator<T> iterator() {
|
||||
return collection.iterator();
|
||||
collectionIter = collection.iterator();
|
||||
|
||||
return collectionIter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Iterator;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
interface Filterer<T> extends Iterable<T> {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* After-invocation providers for collection and array filtering. Consider using a {@code PostFilter} annotation in
|
||||
* preference.
|
||||
*/
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
@@ -12,7 +12,7 @@ public abstract class AbstractPermission implements Permission {
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected final char code;
|
||||
protected char code;
|
||||
protected int mask;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+9
-8
@@ -29,17 +29,18 @@ import java.io.Serializable;
|
||||
* An immutable default implementation of <code>AccessControlEntry</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccessControlEntryImpl implements AccessControlEntry, AuditableAccessControlEntry {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Acl acl;
|
||||
private Acl acl;
|
||||
private Permission permission;
|
||||
private final Serializable id;
|
||||
private final Sid sid;
|
||||
private Serializable id;
|
||||
private Sid sid;
|
||||
private boolean auditFailure = false;
|
||||
private boolean auditSuccess = false;
|
||||
private final boolean granting;
|
||||
private boolean granting;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -76,7 +77,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
if (rhs.getAcl() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Both this.acl and rhs.acl are non-null, so do a comparison
|
||||
if (this.acl.getObjectIdentity() == null) {
|
||||
if (rhs.acl.getObjectIdentity() != null) {
|
||||
@@ -90,7 +91,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.id == null) {
|
||||
if (rhs.id != null) {
|
||||
return false;
|
||||
@@ -107,7 +108,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((this.auditFailure != rhs.isAuditFailure()) || (this.auditSuccess != rhs.isAuditSuccess())
|
||||
|| (this.granting != rhs.isGranting())
|
||||
|| !this.permission.equals(rhs.getPermission()) || !this.sid.equals(rhs.getSid())) {
|
||||
@@ -159,7 +160,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("AccessControlEntryImpl[");
|
||||
sb.append("id: ").append(this.id).append("; ");
|
||||
sb.append("granting: ").append(this.granting).append("; ");
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ import org.springframework.security.acls.model.Acl;
|
||||
* adminstrative methods on the <code>AclImpl</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclAuthorizationStrategy {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
+15
-25
@@ -31,23 +31,20 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Default implementation of {@link AclAuthorizationStrategy}.
|
||||
* <p>
|
||||
* Permission will be granted if at least one of the following conditions is true for the current
|
||||
* principal.
|
||||
* <ul>
|
||||
* <li> is the owner (as defined by the ACL). </li>
|
||||
* <li> holds the relevant system-wide {@link GrantedAuthority} injected into the
|
||||
* constructor. </li>
|
||||
* <li> has {@link BasePermission#ADMINISTRATION} permission (as defined by the ACL). </li>
|
||||
* </ul>
|
||||
* Permission will be granted provided the current principal is either the owner (as defined by the ACL), has
|
||||
* {@link BasePermission#ADMINISTRATION} (as defined by the ACL and via a {@link Sid} retrieved for the current
|
||||
* principal via {@link #sidRetrievalStrategy}), or if the current principal holds the relevant system-wide
|
||||
* {@link GrantedAuthority} and injected into the constructor.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final GrantedAuthority gaGeneralChanges;
|
||||
private final GrantedAuthority gaModifyAuditing;
|
||||
private final GrantedAuthority gaTakeOwnership;
|
||||
private GrantedAuthority gaGeneralChanges;
|
||||
private GrantedAuthority gaModifyAuditing;
|
||||
private GrantedAuthority gaTakeOwnership;
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
@@ -56,23 +53,16 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
* Constructor. The only mandatory parameter relates to the system-wide {@link GrantedAuthority} instances that
|
||||
* can be held to always permit ACL changes.
|
||||
*
|
||||
* @param auths the <code>GrantedAuthority</code>s that have
|
||||
* @param auths an array of <code>GrantedAuthority</code>s that have
|
||||
* special permissions (index 0 is the authority needed to change
|
||||
* ownership, index 1 is the authority needed to modify auditing details,
|
||||
* index 2 is the authority needed to change other ACL and ACE details) (required)
|
||||
* <p>
|
||||
* Alternatively, a single value can be supplied for all three permissions.
|
||||
*/
|
||||
public AclAuthorizationStrategyImpl(GrantedAuthority... auths) {
|
||||
Assert.isTrue(auths != null && (auths.length == 3 || auths.length == 1),
|
||||
"One or three GrantedAuthority instances required");
|
||||
if (auths.length == 3) {
|
||||
gaTakeOwnership = auths[0];
|
||||
gaModifyAuditing = auths[1];
|
||||
gaGeneralChanges = auths[2];
|
||||
} else {
|
||||
gaTakeOwnership = gaModifyAuditing = gaGeneralChanges = auths[0];
|
||||
}
|
||||
public AclAuthorizationStrategyImpl(GrantedAuthority[] auths) {
|
||||
Assert.isTrue(auths != null && auths.length == 3, "GrantedAuthority[] with three elements required");
|
||||
this.gaTakeOwnership = auths[0];
|
||||
this.gaModifyAuditing = auths[1];
|
||||
this.gaGeneralChanges = auths[2];
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -95,7 +85,7 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
}
|
||||
|
||||
// Not authorized by ACL ownership; try via adminstrative permissions
|
||||
GrantedAuthority requiredAuthority;
|
||||
GrantedAuthority requiredAuthority = null;
|
||||
|
||||
if (changeType == CHANGE_AUDITING) {
|
||||
requiredAuthority = this.gaModifyAuditing;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.util.Assert;
|
||||
* Utility methods for displaying ACL information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AclFormattingUtils {
|
||||
|
||||
@@ -98,7 +99,7 @@ public abstract class AclFormattingUtils {
|
||||
}
|
||||
|
||||
private static String printBinary(int i, char on, char off) {
|
||||
String s = Integer.toBinaryString(i);
|
||||
String s = Integer.toString(i, 2);
|
||||
String pattern = Permission.THIRTY_TWO_RESERVED_OFF;
|
||||
String temp2 = pattern.substring(0, pattern.length() - s.length()) + s;
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.OwnershipAcl;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.UnloadedSidException;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -36,14 +35,15 @@ import org.springframework.util.Assert;
|
||||
* Base implementation of <code>Acl</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Acl parentAcl;
|
||||
private transient AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
private transient PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
private final List<AccessControlEntry> aces = new ArrayList<AccessControlEntry>();
|
||||
private transient AuditLogger auditLogger;
|
||||
private List<AccessControlEntry> aces = new ArrayList<AccessControlEntry>();
|
||||
private ObjectIdentity objectIdentity;
|
||||
private Serializable id;
|
||||
private Sid owner; // OwnershipAcl
|
||||
@@ -70,48 +70,39 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
this.objectIdentity = objectIdentity;
|
||||
this.id = id;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
this.permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use the version which takes a {@code PermissionGrantingStrategy} argument instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
|
||||
AuditLogger auditLogger, Acl parentAcl, List<Sid> loadedSids, boolean entriesInheriting, Sid owner) {
|
||||
this(objectIdentity, id, aclAuthorizationStrategy, new DefaultPermissionGrantingStrategy(auditLogger),
|
||||
parentAcl, loadedSids, entriesInheriting, owner);
|
||||
this.auditLogger = auditLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full constructor, which should be used by persistence tools that do not
|
||||
* provide field-level access features.
|
||||
*
|
||||
* @param objectIdentity the object identity this ACL relates to
|
||||
* @param id the primary key assigned to this ACL
|
||||
* @param aclAuthorizationStrategy authorization strategy
|
||||
* @param grantingStrategy the {@code PermissionGrantingStrategy} which will be used by the {@code isGranted()} method
|
||||
* @param parentAcl the parent (may be may be {@code null})
|
||||
* @param loadedSids the loaded SIDs if only a subset were loaded (may be {@code null})
|
||||
* @param objectIdentity the object identity this ACL relates to (required)
|
||||
* @param id the primary key assigned to this ACL (required)
|
||||
* @param aclAuthorizationStrategy authorization strategy (required)
|
||||
* @param auditLogger audit logger (required)
|
||||
* @param parentAcl the parent (may be <code>null</code>)
|
||||
* @param loadedSids the loaded SIDs if only a subset were loaded (may be
|
||||
* <code>null</code>)
|
||||
* @param entriesInheriting if ACEs from the parent should inherit into
|
||||
* this ACL
|
||||
* @param owner the owner (required)
|
||||
*/
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
|
||||
PermissionGrantingStrategy grantingStrategy, Acl parentAcl, List<Sid> loadedSids, boolean entriesInheriting, Sid owner) {
|
||||
AuditLogger auditLogger, Acl parentAcl, List<Sid> loadedSids, boolean entriesInheriting, Sid owner) {
|
||||
Assert.notNull(objectIdentity, "Object Identity required");
|
||||
Assert.notNull(id, "Id required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
Assert.notNull(owner, "Owner required");
|
||||
|
||||
Assert.notNull(auditLogger, "AuditLogger required");
|
||||
this.objectIdentity = objectIdentity;
|
||||
this.id = id;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
this.auditLogger = auditLogger;
|
||||
this.parentAcl = parentAcl; // may be null
|
||||
this.loadedSids = loadedSids; // may be null
|
||||
this.entriesInheriting = entriesInheriting;
|
||||
this.owner = owner;
|
||||
this.permissionGrantingStrategy = grantingStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,11 +169,35 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the {@link PermissionGrantingStrategy}.
|
||||
* Determines authorization. The order of the <code>permission</code> and <code>sid</code> arguments is
|
||||
* <em>extremely important</em>! The method will iterate through each of the <code>permission</code>s in the order
|
||||
* specified. For each iteration, all of the <code>sid</code>s will be considered, again in the order they are
|
||||
* presented. A search will then be performed for the first {@link AccessControlEntry} object that directly
|
||||
* matches that <code>permission:sid</code> combination. When the <em>first full match</em> is found (ie an ACE
|
||||
* that has the SID currently being searched for and the exact permission bit mask being search for), the grant or
|
||||
* deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return
|
||||
* <code>true</code>. If the ACE specifies to deny access, the loop will stop and the next <code>permission</code>
|
||||
* iteration will be performed. If each permission indicates to deny access, the first deny ACE found will be
|
||||
* considered the reason for the failure (as it was the first match found, and is therefore the one most logically
|
||||
* requiring changes - although not always). If absolutely no matching ACE was found at all for any permission,
|
||||
* the parent ACL will be tried (provided that there is a parent and {@link #isEntriesInheriting()} is
|
||||
* <code>true</code>. The parent ACL will also scan its parent and so on. If ultimately no matching ACE is found,
|
||||
* a <code>NotFoundException</code> will be thrown and the caller will need to decide how to handle the permission
|
||||
* check. Similarly, if any of the SID arguments presented to the method were not loaded by the ACL,
|
||||
* <code>UnloadedSidException</code> will be thrown.
|
||||
*
|
||||
* @param permission the exact permissions to scan for (order is important)
|
||||
* @param sids the exact SIDs to scan for (order is important)
|
||||
* @param administrativeMode if <code>true</code> denotes the query is for administrative purposes and no auditing
|
||||
* will be undertaken
|
||||
*
|
||||
* @return <code>true</code> if one of the permissions has been granted, <code>false</code> if one of the
|
||||
* permissions has been specifically revoked
|
||||
*
|
||||
* @throws NotFoundException if an exact ACE for one of the permission bit masks and SID combination could not be
|
||||
* found
|
||||
* @throws UnloadedSidException if the passed SIDs are unknown to this ACL because the ACL was only loaded for a
|
||||
* subset of SIDs
|
||||
* @see DefaultPermissionGrantingStrategy
|
||||
*/
|
||||
public boolean isGranted(List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException, UnloadedSidException {
|
||||
@@ -193,7 +208,64 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
throw new UnloadedSidException("ACL was not loaded for one or more SID");
|
||||
}
|
||||
|
||||
return permissionGrantingStrategy.isGranted(this, permission, sids, administrativeMode);
|
||||
AccessControlEntry firstRejection = null;
|
||||
|
||||
for (Permission p : permission) {
|
||||
for (Sid sid: sids) {
|
||||
// Attempt to find exact match for this permission mask and SID
|
||||
boolean scanNextSid = true;
|
||||
|
||||
for (AccessControlEntry ace : aces ) {
|
||||
|
||||
if ((ace.getPermission().getMask() == p.getMask()) && ace.getSid().equals(sid)) {
|
||||
// Found a matching ACE, so its authorization decision will prevail
|
||||
if (ace.isGranting()) {
|
||||
// Success
|
||||
if (!administrativeMode) {
|
||||
auditLogger.logIfNeeded(true, ace);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failure for this permission, so stop search
|
||||
// We will see if they have a different permission
|
||||
// (this permission is 100% rejected for this SID)
|
||||
if (firstRejection == null) {
|
||||
// Store first rejection for auditing reasons
|
||||
firstRejection = ace;
|
||||
}
|
||||
|
||||
scanNextSid = false; // helps break the loop
|
||||
|
||||
break; // exit aces loop
|
||||
}
|
||||
}
|
||||
|
||||
if (!scanNextSid) {
|
||||
break; // exit SID for loop (now try next permission)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRejection != null) {
|
||||
// We found an ACE to reject the request at this point, as no
|
||||
// other ACEs were found that granted a different permission
|
||||
if (!administrativeMode) {
|
||||
auditLogger.logIfNeeded(false, firstRejection);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// No matches have been found so far
|
||||
if (isEntriesInheriting() && (parentAcl != null)) {
|
||||
// We have a parent, so let them try to find a matching ACE
|
||||
return parentAcl.isGranted(permission, sids, false);
|
||||
} else {
|
||||
// We either have no parent, or we're the uppermost parent
|
||||
throw new NotFoundException("Unable to locate a matching ACE for passed permissions and SIDs");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSidLoaded(List<Sid> sids) {
|
||||
@@ -249,6 +321,38 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
return parentAcl;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("AclImpl[");
|
||||
sb.append("id: ").append(this.id).append("; ");
|
||||
sb.append("objectIdentity: ").append(this.objectIdentity).append("; ");
|
||||
sb.append("owner: ").append(this.owner).append("; ");
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (AccessControlEntry ace : aces) {
|
||||
count++;
|
||||
|
||||
if (count == 1) {
|
||||
sb.append("\r\n");
|
||||
}
|
||||
|
||||
sb.append(ace).append("\r\n");
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
sb.append("no ACEs; ");
|
||||
}
|
||||
|
||||
sb.append("inheriting: ").append(this.entriesInheriting).append("; ");
|
||||
sb.append("parent: ").append((this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity().toString());
|
||||
sb.append("aclAuthorizationStrategy: ").append(this.aclAuthorizationStrategy).append("; ");
|
||||
sb.append("auditLogger: ").append(this.auditLogger);
|
||||
sb.append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void updateAce(int aceIndex, Permission permission)
|
||||
throws NotFoundException {
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
@@ -275,15 +379,15 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
if (obj instanceof AclImpl) {
|
||||
AclImpl rhs = (AclImpl) obj;
|
||||
if (this.aces.equals(rhs.aces)) {
|
||||
if ((this.parentAcl == null && rhs.parentAcl == null) || (this.parentAcl !=null && this.parentAcl.equals(rhs.parentAcl))) {
|
||||
if ((this.objectIdentity == null && rhs.objectIdentity == null) || (this.objectIdentity != null && this.objectIdentity.equals(rhs.objectIdentity))) {
|
||||
if ((this.id == null && rhs.id == null) || (this.id != null && this.id.equals(rhs.id))) {
|
||||
if ((this.owner == null && rhs.owner == null) || (this.owner != null && this.owner.equals(rhs.owner))) {
|
||||
if ((this.parentAcl == null && rhs.parentAcl == null) || (this.parentAcl.equals(rhs.parentAcl))) {
|
||||
if ((this.objectIdentity == null && rhs.objectIdentity == null) || (this.objectIdentity.equals(rhs.objectIdentity))) {
|
||||
if ((this.id == null && rhs.id == null) || (this.id.equals(rhs.id))) {
|
||||
if ((this.owner == null && rhs.owner == null) || this.owner.equals(rhs.owner)) {
|
||||
if (this.entriesInheriting == rhs.entriesInheriting) {
|
||||
if ((this.loadedSids == null && rhs.loadedSids == null)) {
|
||||
return true;
|
||||
}
|
||||
if (this.loadedSids != null && (this.loadedSids.size() == rhs.loadedSids.size())) {
|
||||
if (this.loadedSids.size() == rhs.loadedSids.size()) {
|
||||
for (int i = 0; i < this.loadedSids.size(); i++) {
|
||||
if (!this.loadedSids.get(i).equals(rhs.loadedSids.get(i))) {
|
||||
return false;
|
||||
@@ -301,37 +405,4 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("AclImpl[");
|
||||
sb.append("id: ").append(this.id).append("; ");
|
||||
sb.append("objectIdentity: ").append(this.objectIdentity).append("; ");
|
||||
sb.append("owner: ").append(this.owner).append("; ");
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (AccessControlEntry ace : aces) {
|
||||
count++;
|
||||
|
||||
if (count == 1) {
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
sb.append(ace).append("\n");
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
sb.append("no ACEs; ");
|
||||
}
|
||||
|
||||
sb.append("inheriting: ").append(this.entriesInheriting).append("; ");
|
||||
sb.append("parent: ").append((this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity().toString());
|
||||
sb.append("; ");
|
||||
sb.append("aclAuthorizationStrategy: ").append(this.aclAuthorizationStrategy).append("; ");
|
||||
sb.append("permissionGrantingStrategy: ").append(this.permissionGrantingStrategy);
|
||||
sb.append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.security.acls.model.AccessControlEntry;
|
||||
* Used by <code>AclImpl</code> to log audit events.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditLogger {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BasePermission extends AbstractPermission {
|
||||
public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
|
||||
|
||||
@@ -21,9 +21,10 @@ import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* A basic implementation of {@link AuditLogger}.
|
||||
* A bsaic implementation of {@link AuditLogger}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConsoleAuditLogger implements AuditLogger {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
+5
-4
@@ -19,10 +19,11 @@ import org.springframework.security.acls.model.Permission;
|
||||
|
||||
/**
|
||||
* Represents a <code>Permission</code> that is constructed at runtime from other permissions.
|
||||
*
|
||||
*
|
||||
* <p>Methods return <code>this</code>, in order to facilitate method chaining.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CumulativePermission extends AbstractPermission {
|
||||
|
||||
@@ -31,7 +32,7 @@ public class CumulativePermission extends AbstractPermission {
|
||||
public CumulativePermission() {
|
||||
super(0, ' ');
|
||||
}
|
||||
|
||||
|
||||
public CumulativePermission clear(Permission permission) {
|
||||
this.mask &= ~permission.getMask();
|
||||
this.pattern = AclFormattingUtils.demergePatterns(this.pattern, permission.getPattern());
|
||||
@@ -45,14 +46,14 @@ public class CumulativePermission extends AbstractPermission {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CumulativePermission set(Permission permission) {
|
||||
this.mask |= permission.getMask();
|
||||
this.pattern = AclFormattingUtils.mergePatterns(this.pattern, permission.getPattern());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
+6
-7
@@ -64,19 +64,18 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
||||
|
||||
Field[] fields = clazz.getFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
try {
|
||||
Object fieldValue = field.get(null);
|
||||
Object fieldValue = fields[i].get(null);
|
||||
|
||||
if (Permission.class.isAssignableFrom(fieldValue.getClass())) {
|
||||
// Found a Permission static field
|
||||
Permission perm = (Permission) fieldValue;
|
||||
String permissionName = field.getName();
|
||||
String permissionName = fields[i].getName();
|
||||
|
||||
registerPermission(perm, permissionName);
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
||||
Assert.notNull(perm, "Permission required");
|
||||
Assert.hasText(permissionName, "Permission name required");
|
||||
|
||||
Integer mask = Integer.valueOf(perm.getMask());
|
||||
Integer mask = new Integer(perm.getMask());
|
||||
|
||||
// Ensure no existing Permission uses this integer or code
|
||||
Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask), "An existing Permission already provides mask " + mask);
|
||||
@@ -98,7 +97,7 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
||||
public Permission buildFromMask(int mask) {
|
||||
if (registeredPermissionsByInteger.containsKey(Integer.valueOf(mask))) {
|
||||
// The requested mask has an exact match against a statically-defined Permission, so return it
|
||||
return registeredPermissionsByInteger.get(Integer.valueOf(mask));
|
||||
return registeredPermissionsByInteger.get(new Integer(mask));
|
||||
}
|
||||
|
||||
// To get this far, we have to use a CumulativePermission
|
||||
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class DefaultPermissionGrantingStrategy implements PermissionGrantingStrategy {
|
||||
|
||||
private final transient AuditLogger auditLogger;
|
||||
|
||||
/**
|
||||
* Creates an instance with the logger which will be used to record granting and denial of requested permissions.
|
||||
*/
|
||||
public DefaultPermissionGrantingStrategy(AuditLogger auditLogger) {
|
||||
Assert.notNull(auditLogger, "auditLogger cannot be null");
|
||||
this.auditLogger = auditLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines authorization. The order of the <code>permission</code> and <code>sid</code> arguments is
|
||||
* <em>extremely important</em>! The method will iterate through each of the <code>permission</code>s in the order
|
||||
* specified. For each iteration, all of the <code>sid</code>s will be considered, again in the order they are
|
||||
* presented. A search will then be performed for the first {@link AccessControlEntry} object that directly
|
||||
* matches that <code>permission:sid</code> combination. When the <em>first full match</em> is found (ie an ACE
|
||||
* that has the SID currently being searched for and the exact permission bit mask being search for), the grant or
|
||||
* deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return
|
||||
* <code>true</code>. If the ACE specifies to deny access, the loop will stop and the next <code>permission</code>
|
||||
* iteration will be performed. If each permission indicates to deny access, the first deny ACE found will be
|
||||
* considered the reason for the failure (as it was the first match found, and is therefore the one most logically
|
||||
* requiring changes - although not always). If absolutely no matching ACE was found at all for any permission,
|
||||
* the parent ACL will be tried (provided that there is a parent and {@link Acl#isEntriesInheriting()} is
|
||||
* <code>true</code>. The parent ACL will also scan its parent and so on. If ultimately no matching ACE is found,
|
||||
* a <code>NotFoundException</code> will be thrown and the caller will need to decide how to handle the permission
|
||||
* check. Similarly, if any of the SID arguments presented to the method were not loaded by the ACL,
|
||||
* <code>UnloadedSidException</code> will be thrown.
|
||||
*
|
||||
* @param permission the exact permissions to scan for (order is important)
|
||||
* @param sids the exact SIDs to scan for (order is important)
|
||||
* @param administrativeMode if <code>true</code> denotes the query is for administrative purposes and no auditing
|
||||
* will be undertaken
|
||||
*
|
||||
* @return <code>true</code> if one of the permissions has been granted, <code>false</code> if one of the
|
||||
* permissions has been specifically revoked
|
||||
*
|
||||
* @throws NotFoundException if an exact ACE for one of the permission bit masks and SID combination could not be
|
||||
* found
|
||||
*/
|
||||
public boolean isGranted(Acl acl, List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException {
|
||||
|
||||
final List<AccessControlEntry> aces = acl.getEntries();
|
||||
|
||||
AccessControlEntry firstRejection = null;
|
||||
|
||||
for (Permission p : permission) {
|
||||
for (Sid sid: sids) {
|
||||
// Attempt to find exact match for this permission mask and SID
|
||||
boolean scanNextSid = true;
|
||||
|
||||
for (AccessControlEntry ace : aces ) {
|
||||
|
||||
if ((ace.getPermission().getMask() == p.getMask()) && ace.getSid().equals(sid)) {
|
||||
// Found a matching ACE, so its authorization decision will prevail
|
||||
if (ace.isGranting()) {
|
||||
// Success
|
||||
if (!administrativeMode) {
|
||||
auditLogger.logIfNeeded(true, ace);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failure for this permission, so stop search
|
||||
// We will see if they have a different permission
|
||||
// (this permission is 100% rejected for this SID)
|
||||
if (firstRejection == null) {
|
||||
// Store first rejection for auditing reasons
|
||||
firstRejection = ace;
|
||||
}
|
||||
|
||||
scanNextSid = false; // helps break the loop
|
||||
|
||||
break; // exit aces loop
|
||||
}
|
||||
}
|
||||
|
||||
if (!scanNextSid) {
|
||||
break; // exit SID for loop (now try next permission)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRejection != null) {
|
||||
// We found an ACE to reject the request at this point, as no
|
||||
// other ACEs were found that granted a different permission
|
||||
if (!administrativeMode) {
|
||||
auditLogger.logIfNeeded(false, firstRejection);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// No matches have been found so far
|
||||
if (acl.isEntriesInheriting() && (acl.getParentAcl() != null)) {
|
||||
// We have a parent, so let them try to find a matching ACE
|
||||
return acl.getParentAcl().isGranted(permission, sids, false);
|
||||
} else {
|
||||
// We either have no parent, or we're the uppermost parent
|
||||
throw new NotFoundException("Unable to locate a matching ACE for passed permissions and SIDs");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+8
-21
@@ -23,48 +23,35 @@ import net.sf.ehcache.Element;
|
||||
import org.springframework.security.acls.model.AclCache;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link AclCache} that delegates to EH-CACHE.
|
||||
*
|
||||
* <p>
|
||||
* Designed to handle the transient fields in {@link AclImpl}. Note that this implementation assumes all
|
||||
* {@link AclImpl} instances share the same {@link PermissionGrantingStrategy} and {@link AclAuthorizationStrategy}
|
||||
* instances.
|
||||
* {@link AclImpl} instances share the same {@link AuditLogger} and {@link AclAuthorizationStrategy} instance.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedAclCache implements AclCache {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Ehcache cache;
|
||||
private PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
private Ehcache cache;
|
||||
private AuditLogger auditLogger;
|
||||
private AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* @deprecated use the second constructor which injects the strategy objects. See SEC-1498.
|
||||
*/
|
||||
@Deprecated
|
||||
public EhCacheBasedAclCache(Ehcache cache) {
|
||||
Assert.notNull(cache, "Cache required");
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public EhCacheBasedAclCache(Ehcache cache, PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy) {
|
||||
Assert.notNull(cache, "Cache required");
|
||||
Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
this.cache = cache;
|
||||
this.permissionGrantingStrategy = permissionGrantingStrategy;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void evictFromCache(Serializable pk) {
|
||||
@@ -129,7 +116,7 @@ public class EhCacheBasedAclCache implements AclCache {
|
||||
if (this.aclAuthorizationStrategy == null) {
|
||||
if (acl instanceof AclImpl) {
|
||||
this.aclAuthorizationStrategy = (AclAuthorizationStrategy) FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", acl);
|
||||
this.permissionGrantingStrategy = (PermissionGrantingStrategy) FieldUtils.getProtectedFieldValue("permissionGrantingStrategy", acl);
|
||||
this.auditLogger = (AuditLogger) FieldUtils.getProtectedFieldValue("auditLogger", acl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +131,7 @@ public class EhCacheBasedAclCache implements AclCache {
|
||||
private MutableAcl initializeTransientFields(MutableAcl value) {
|
||||
if (value instanceof AclImpl) {
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
|
||||
FieldUtils.setProtectedFieldValue("auditLogger", value, this.auditLogger);
|
||||
}
|
||||
|
||||
if (value.getParentAcl() != null) {
|
||||
|
||||
@@ -26,11 +26,12 @@ import org.springframework.util.Assert;
|
||||
* wish to provide an alternative <code>Sid</code> implementation that uses some other identifier.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class GrantedAuthoritySid implements Sid {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String grantedAuthority;
|
||||
private String grantedAuthority;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ package org.springframework.security.acls.domain;
|
||||
* Thrown if an ACL identity could not be extracted from an object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class IdentityUnavailableException extends RuntimeException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.util.ClassUtils;
|
||||
* reflection to build the identity information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ObjectIdentityImpl implements ObjectIdentity {
|
||||
//~ Instance fields ================================================================================================
|
||||
@@ -78,7 +79,7 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
||||
|
||||
try {
|
||||
Method method = typeClass.getMethod("getId", new Class[] {});
|
||||
result = method.invoke(object);
|
||||
result = method.invoke(object, new Object[] {});
|
||||
} catch (Exception e) {
|
||||
throw new IdentityUnavailableException("Could not extract identity from object " + object, e);
|
||||
}
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
* that uses the constructors of {@link ObjectIdentityImpl} to create the {@link ObjectIdentity}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImpl implements ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -28,11 +28,12 @@ import org.springframework.util.Assert;
|
||||
* objects may wish to provide an alternative <code>Sid</code> implementation that uses some other identifier.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PrincipalSid implements Sid {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String principal;
|
||||
private String principal;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* The returned array will always contain the {@link PrincipalSid} before any {@link GrantedAuthoritySid} elements.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
|
||||
|
||||
@@ -51,7 +52,7 @@ public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public List<Sid> getSids(Authentication authentication) {
|
||||
Collection<? extends GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
|
||||
Collection<GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
|
||||
List<Sid> sids = new ArrayList<Sid>(authorities.size() + 1);
|
||||
|
||||
sids.add(new PrincipalSid(authentication));
|
||||
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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.springframework.security.acls.domain;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.security.acls.model.AclCache;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link org.springframework.security.acls.model.AclCache} that delegates to {@link Cache} implementation.
|
||||
* <p>
|
||||
* Designed to handle the transient fields in {@link org.springframework.security.acls.domain.AclImpl}. Note that this implementation assumes all
|
||||
* {@link org.springframework.security.acls.domain.AclImpl} instances share the same {@link org.springframework.security.acls.model.PermissionGrantingStrategy} and {@link org.springframework.security.acls.domain.AclAuthorizationStrategy}
|
||||
* instances.
|
||||
*
|
||||
* @author Marten Deinum
|
||||
* @since 3.2
|
||||
*/
|
||||
public class SpringCacheBasedAclCache implements AclCache {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Cache cache;
|
||||
private PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
private AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public SpringCacheBasedAclCache(Cache cache, PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy) {
|
||||
Assert.notNull(cache, "Cache required");
|
||||
Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
this.cache = cache;
|
||||
this.permissionGrantingStrategy = permissionGrantingStrategy;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void evictFromCache(Serializable pk) {
|
||||
Assert.notNull(pk, "Primary key (identifier) required");
|
||||
|
||||
MutableAcl acl = getFromCache(pk);
|
||||
|
||||
if (acl != null) {
|
||||
cache.evict(acl.getId());
|
||||
cache.evict(acl.getObjectIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
public void evictFromCache(ObjectIdentity objectIdentity) {
|
||||
Assert.notNull(objectIdentity, "ObjectIdentity required");
|
||||
|
||||
MutableAcl acl = getFromCache(objectIdentity);
|
||||
|
||||
if (acl != null) {
|
||||
cache.evict(acl.getId());
|
||||
cache.evict(acl.getObjectIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
|
||||
Assert.notNull(objectIdentity, "ObjectIdentity required");
|
||||
return getFromCache((Object)objectIdentity);
|
||||
}
|
||||
|
||||
public MutableAcl getFromCache(Serializable pk) {
|
||||
Assert.notNull(pk, "Primary key (identifier) required");
|
||||
return getFromCache((Object)pk);
|
||||
}
|
||||
|
||||
public void putInCache(MutableAcl acl) {
|
||||
Assert.notNull(acl, "Acl required");
|
||||
Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required");
|
||||
Assert.notNull(acl.getId(), "ID required");
|
||||
|
||||
if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
|
||||
putInCache((MutableAcl) acl.getParentAcl());
|
||||
}
|
||||
|
||||
cache.put(acl.getObjectIdentity(), acl);
|
||||
cache.put(acl.getId(), acl);
|
||||
}
|
||||
|
||||
private MutableAcl getFromCache(Object key) {
|
||||
Cache.ValueWrapper element = cache.get(key);
|
||||
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return initializeTransientFields((MutableAcl) element.get());
|
||||
}
|
||||
|
||||
private MutableAcl initializeTransientFields(MutableAcl value) {
|
||||
if (value instanceof AclImpl) {
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
|
||||
}
|
||||
|
||||
if (value.getParentAcl() != null) {
|
||||
initializeTransientFields((MutableAcl) value.getParentAcl());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* Basic implementation of access control lists (ACLs) interfaces.
|
||||
*/
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Basic implementation of access control lists (ACLs) interfaces.
|
||||
</body>
|
||||
</html>
|
||||
+88
-104
@@ -20,15 +20,16 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.PreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
@@ -37,7 +38,6 @@ import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
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.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PermissionFactory;
|
||||
@@ -49,7 +49,6 @@ import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.UnloadedSidException;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
@@ -73,6 +72,7 @@ import org.springframework.util.Assert;
|
||||
* generated by the the default values.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
@@ -107,11 +107,11 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
private AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
private PermissionFactory permissionFactory = new DefaultPermissionFactory();
|
||||
private final AclCache aclCache;
|
||||
private final PermissionGrantingStrategy grantingStrategy;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private AclCache aclCache;
|
||||
private AuditLogger auditLogger;
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
private int batchSize = 50;
|
||||
|
||||
private final Field fieldAces = FieldUtils.getField(AclImpl.class, "aces");
|
||||
@@ -131,28 +131,19 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
* @param dataSource to access the database
|
||||
* @param aclCache the cache where fully-loaded elements can be stored
|
||||
* @param aclAuthorizationStrategy authorization strategy (required)
|
||||
*
|
||||
* @deprecated Use the version which takes a {@code PermissionGrantingStrategy} argument instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy, AuditLogger auditLogger) {
|
||||
this(dataSource, aclCache, aclAuthorizationStrategy, new DefaultPermissionGrantingStrategy(auditLogger));
|
||||
}
|
||||
|
||||
public BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy, PermissionGrantingStrategy grantingStrategy) {
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy, AuditLogger auditLogger) {
|
||||
Assert.notNull(dataSource, "DataSource required");
|
||||
Assert.notNull(aclCache, "AclCache required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
Assert.notNull(grantingStrategy, "grantingStrategy required");
|
||||
Assert.notNull(auditLogger, "AuditLogger required");
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.aclCache = aclCache;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
this.grantingStrategy = grantingStrategy;
|
||||
this.auditLogger = auditLogger;
|
||||
fieldAces.setAccessible(true);
|
||||
fieldAcl.setAccessible(true);
|
||||
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -181,6 +172,57 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
return sqlStringBldr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The final phase of converting the <code>Map</code> of <code>AclImpl</code> instances which contain
|
||||
* <code>StubAclParent</code>s into proper, valid <code>AclImpl</code>s with correct ACL parents.
|
||||
*
|
||||
* @param inputMap the unconverted <code>AclImpl</code>s
|
||||
* @param currentIdentity the current<code>Acl</code> that we wish to convert (this may be
|
||||
*
|
||||
*/
|
||||
private AclImpl convert(Map<Long,AclImpl> inputMap, Long currentIdentity) {
|
||||
Assert.notEmpty(inputMap, "InputMap required");
|
||||
Assert.notNull(currentIdentity, "CurrentIdentity required");
|
||||
|
||||
// Retrieve this Acl from the InputMap
|
||||
Acl uncastAcl = (Acl) inputMap.get(currentIdentity);
|
||||
Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl");
|
||||
|
||||
AclImpl inputAcl = (AclImpl) uncastAcl;
|
||||
|
||||
Acl parent = inputAcl.getParentAcl();
|
||||
|
||||
if ((parent != null) && parent instanceof StubAclParent) {
|
||||
// Lookup the parent
|
||||
StubAclParent stubAclParent = (StubAclParent) parent;
|
||||
parent = convert(inputMap, stubAclParent.getId());
|
||||
}
|
||||
|
||||
// Now we have the parent (if there is one), create the true AclImpl
|
||||
AclImpl result = new AclImpl(inputAcl.getObjectIdentity(), (Long) inputAcl.getId(), aclAuthorizationStrategy,
|
||||
auditLogger, parent, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner());
|
||||
|
||||
// Copy the "aces" from the input to the destination
|
||||
|
||||
// Obtain the "aces" from the input ACL
|
||||
List<AccessControlEntryImpl> aces = readAces(inputAcl);
|
||||
|
||||
// Create a list in which to store the "aces" for the "result" AclImpl instance
|
||||
List<AccessControlEntryImpl> acesNew = new ArrayList<AccessControlEntryImpl>();
|
||||
|
||||
// Iterate over the "aces" input and replace each nested AccessControlEntryImpl.getAcl() with the new "result" AclImpl instance
|
||||
// This ensures StubAclParent instances are removed, as per SEC-951
|
||||
for (AccessControlEntryImpl ace : aces) {
|
||||
setAclOnAce(ace, result);
|
||||
acesNew.add(ace);
|
||||
}
|
||||
|
||||
// Finally, now that the "aces" have been converted to have the "result" AclImpl instance, modify the "result" AclImpl instance
|
||||
setAces(result, acesNew);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<AccessControlEntryImpl> readAces(AclImpl acl) {
|
||||
try {
|
||||
@@ -263,20 +305,19 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
// Map<ObjectIdentity,Acl>
|
||||
Map<ObjectIdentity, Acl> result = new HashMap<ObjectIdentity, Acl>(); // contains FULLY loaded Acl objects
|
||||
|
||||
Set<ObjectIdentity> currentBatchToLoad = new HashSet<ObjectIdentity>();
|
||||
Set<ObjectIdentity> currentBatchToLoad = new HashSet<ObjectIdentity>(); // contains ObjectIdentitys
|
||||
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
final ObjectIdentity oid = objects.get(i);
|
||||
boolean aclFound = false;
|
||||
|
||||
// Check we don't already have this ACL in the results
|
||||
if (result.containsKey(oid)) {
|
||||
if (result.containsKey(objects.get(i))) {
|
||||
aclFound = true;
|
||||
}
|
||||
|
||||
// Check cache for the present ACL entry
|
||||
if (!aclFound) {
|
||||
Acl acl = aclCache.getFromCache(oid);
|
||||
Acl acl = aclCache.getFromCache(objects.get(i));
|
||||
|
||||
// Ensure any cached element supports all the requested SIDs
|
||||
// (they should always, as our base impl doesn't filter on SID)
|
||||
@@ -294,21 +335,22 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
// Load the ACL from the database
|
||||
if (!aclFound) {
|
||||
currentBatchToLoad.add(oid);
|
||||
currentBatchToLoad.add(objects.get(i));
|
||||
}
|
||||
|
||||
// Is it time to load from JDBC the currentBatchToLoad?
|
||||
if ((currentBatchToLoad.size() == this.batchSize) || ((i + 1) == objects.size())) {
|
||||
if (currentBatchToLoad.size() > 0) {
|
||||
Map<ObjectIdentity, Acl> loadedBatch = lookupObjectIdentities(currentBatchToLoad, sids);
|
||||
Map<ObjectIdentity, Acl> loadedBatch = lookupObjectIdentities(currentBatchToLoad.toArray(new ObjectIdentity[] {}), sids);
|
||||
|
||||
// Add loaded batch (all elements 100% initialized) to results
|
||||
result.putAll(loadedBatch);
|
||||
|
||||
// Add the loaded batch to the cache
|
||||
Iterator<Acl> loadedAclIterator = loadedBatch.values().iterator();
|
||||
|
||||
for (Acl loadedAcl : loadedBatch.values()) {
|
||||
aclCache.putInCache((AclImpl) loadedAcl);
|
||||
while (loadedAclIterator.hasNext()) {
|
||||
aclCache.putInCache((AclImpl) loadedAclIterator.next());
|
||||
}
|
||||
|
||||
currentBatchToLoad.clear();
|
||||
@@ -329,31 +371,31 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
* parent ACLs.
|
||||
*
|
||||
*/
|
||||
private Map<ObjectIdentity, Acl> lookupObjectIdentities(final Collection<ObjectIdentity> objectIdentities, List<Sid> sids) {
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<ObjectIdentity, Acl> lookupObjectIdentities(final ObjectIdentity[] objectIdentities, List<Sid> sids) {
|
||||
Assert.notEmpty(objectIdentities, "Must provide identities to lookup");
|
||||
|
||||
final Map<Serializable, Acl> acls = new HashMap<Serializable, Acl>(); // contains Acls with StubAclParents
|
||||
final Map acls = new HashMap(); // contains Acls with StubAclParents
|
||||
|
||||
// Make the "acls" map contain all requested objectIdentities
|
||||
// (including markers to each parent in the hierarchy)
|
||||
String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause, objectIdentities.size());
|
||||
String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause ,
|
||||
objectIdentities.length);
|
||||
|
||||
Set<Long> parentsToLookup = jdbcTemplate.query(sql,
|
||||
Set parentsToLookup = (Set) jdbcTemplate.query(sql,
|
||||
new PreparedStatementSetter() {
|
||||
public void setValues(PreparedStatement ps) throws SQLException {
|
||||
int i = 0;
|
||||
for (ObjectIdentity oid : objectIdentities) {
|
||||
for (int i = 0; i < objectIdentities.length; i++) {
|
||||
// Determine prepared statement values for this iteration
|
||||
String type = oid.getType();
|
||||
String javaType = objectIdentities[i].getType();
|
||||
|
||||
// No need to check for nulls, as guaranteed non-null by ObjectIdentity.getIdentifier() interface contract
|
||||
String identifier = oid.getIdentifier().toString();
|
||||
String identifier = objectIdentities[i].getIdentifier().toString();
|
||||
long id = (Long.valueOf(identifier)).longValue();
|
||||
|
||||
// Inject values
|
||||
ps.setLong((2 * i) + 1, id);
|
||||
ps.setString((2 * i) + 2, type);
|
||||
i++;
|
||||
ps.setString((2 * i) + 2, javaType);
|
||||
}
|
||||
}
|
||||
}, new ProcessResultSet(acls, sids));
|
||||
@@ -365,8 +407,10 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
// Finally, convert our "acls" containing StubAclParents into true Acls
|
||||
Map<ObjectIdentity, Acl> resultMap = new HashMap<ObjectIdentity, Acl>();
|
||||
Iterator iter = acls.values().iterator();
|
||||
|
||||
for (Acl inputAcl : acls.values()) {
|
||||
while (iter.hasNext()) {
|
||||
Acl inputAcl = (Acl) iter.next();
|
||||
Assert.isInstanceOf(AclImpl.class, inputAcl, "Map should have contained an AclImpl");
|
||||
Assert.isInstanceOf(Long.class, ((AclImpl) inputAcl).getId(), "Acl.getId() must be Long");
|
||||
|
||||
@@ -377,67 +421,6 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* The final phase of converting the <code>Map</code> of <code>AclImpl</code> instances which contain
|
||||
* <code>StubAclParent</code>s into proper, valid <code>AclImpl</code>s with correct ACL parents.
|
||||
*
|
||||
* @param inputMap the unconverted <code>AclImpl</code>s
|
||||
* @param currentIdentity the current<code>Acl</code> that we wish to convert (this may be
|
||||
*
|
||||
*/
|
||||
private AclImpl convert(Map<Serializable, Acl> inputMap, Long currentIdentity) {
|
||||
Assert.notEmpty(inputMap, "InputMap required");
|
||||
Assert.notNull(currentIdentity, "CurrentIdentity required");
|
||||
|
||||
// Retrieve this Acl from the InputMap
|
||||
Acl uncastAcl = inputMap.get(currentIdentity);
|
||||
Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl");
|
||||
|
||||
AclImpl inputAcl = (AclImpl) uncastAcl;
|
||||
|
||||
Acl parent = inputAcl.getParentAcl();
|
||||
|
||||
if ((parent != null) && parent instanceof StubAclParent) {
|
||||
// Lookup the parent
|
||||
StubAclParent stubAclParent = (StubAclParent) parent;
|
||||
parent = convert(inputMap, stubAclParent.getId());
|
||||
}
|
||||
|
||||
// Now we have the parent (if there is one), create the true AclImpl
|
||||
AclImpl result = new AclImpl(inputAcl.getObjectIdentity(), (Long) inputAcl.getId(), aclAuthorizationStrategy,
|
||||
grantingStrategy, parent, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner());
|
||||
|
||||
// Copy the "aces" from the input to the destination
|
||||
|
||||
// Obtain the "aces" from the input ACL
|
||||
List<AccessControlEntryImpl> aces = readAces(inputAcl);
|
||||
|
||||
// Create a list in which to store the "aces" for the "result" AclImpl instance
|
||||
List<AccessControlEntryImpl> acesNew = new ArrayList<AccessControlEntryImpl>();
|
||||
|
||||
// Iterate over the "aces" input and replace each nested AccessControlEntryImpl.getAcl() with the new "result" AclImpl instance
|
||||
// This ensures StubAclParent instances are removed, as per SEC-951
|
||||
for (AccessControlEntryImpl ace : aces) {
|
||||
setAclOnAce(ace, result);
|
||||
acesNew.add(ace);
|
||||
}
|
||||
|
||||
// Finally, now that the "aces" have been converted to have the "result" AclImpl instance, modify the "result" AclImpl instance
|
||||
setAces(result, acesNew);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code PermissionFactory} instance which will be used to convert loaded permission
|
||||
* data values to {@code Permission}s. A {@code DefaultPermissionFactory} will be used by default.
|
||||
*
|
||||
* @param permissionFactory
|
||||
*/
|
||||
public void setPermissionFactory(PermissionFactory permissionFactory) {
|
||||
this.permissionFactory = permissionFactory;
|
||||
}
|
||||
|
||||
public void setBatchSize(int batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
@@ -476,8 +459,8 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class ProcessResultSet implements ResultSetExtractor<Set<Long>> {
|
||||
private final Map<Serializable, Acl> acls;
|
||||
private final List<Sid> sids;
|
||||
private Map<Serializable, Acl> acls;
|
||||
private List<Sid> sids;
|
||||
|
||||
public ProcessResultSet(Map<Serializable, Acl> acls, List<Sid> sids) {
|
||||
Assert.notNull(acls, "ACLs cannot be null");
|
||||
@@ -494,8 +477,9 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
* @param rs The {@link ResultSet} to be processed
|
||||
* @return a list of parent IDs remaining to be looked up (may be empty, but never <tt>null</tt>)
|
||||
* @throws SQLException
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
public Set<Long> extractData(ResultSet rs) throws SQLException {
|
||||
public Set<Long> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
Set<Long> parentIdsToLookup = new HashSet<Long>(); // Set of parent_id Longs
|
||||
|
||||
while (rs.next()) {
|
||||
@@ -564,7 +548,7 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
owner = new GrantedAuthoritySid(rs.getString("acl_sid"));
|
||||
}
|
||||
|
||||
acl = new AclImpl(objectIdentity, id, aclAuthorizationStrategy, grantingStrategy, parentAcl, null,
|
||||
acl = new AclImpl(objectIdentity, id, aclAuthorizationStrategy, auditLogger, parentAcl, null,
|
||||
entriesInheriting, owner);
|
||||
|
||||
acls.put(id, acl);
|
||||
@@ -603,7 +587,7 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
||||
}
|
||||
|
||||
private class StubAclParent implements Acl {
|
||||
private final Long id;
|
||||
private Long id;
|
||||
|
||||
public StubAclParent(Long id) {
|
||||
this.id = id;
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.util.Assert;
|
||||
* detect changed parameters easily.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JdbcAclService implements AclService {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -56,8 +57,8 @@ public class JdbcAclService implements AclService {
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected final JdbcTemplate jdbcTemplate;
|
||||
private final LookupStrategy lookupStrategy;
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
private LookupStrategy lookupStrategy;
|
||||
private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
@@ -109,9 +110,10 @@ public class JdbcAclService implements AclService {
|
||||
Map<ObjectIdentity, Acl> result = 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 + "'");
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
if (!result.containsKey(objects.get(i))) {
|
||||
throw new NotFoundException("Unable to find ACL information for object identity '"
|
||||
+ objects.get(i) + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-17
@@ -56,12 +56,13 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Johannes Zlattinger
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean foreignKeysInDatabase = true;
|
||||
private final AclCache aclCache;
|
||||
private AclCache aclCache;
|
||||
private String deleteEntryByObjectIdentityForeignKey = "delete from acl_entry where acl_object_identity=?";
|
||||
private String deleteObjectIdentityByPrimaryKey = "delete from acl_object_identity where id=?";
|
||||
private String classIdentityQuery = "call identity()";
|
||||
@@ -119,9 +120,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
* @param acl containing the ACEs to insert
|
||||
*/
|
||||
protected void createEntries(final MutableAcl acl) {
|
||||
if(acl.getEntries().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
jdbcTemplate.batchUpdate(insertEntry,
|
||||
new BatchPreparedStatementSetter() {
|
||||
public int getBatchSize() {
|
||||
@@ -158,10 +156,10 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the primary key from {@code acl_class}, creating a new row if needed and the
|
||||
* {@code allowCreate} property is {@code true}.
|
||||
* Retrieves the primary key from acl_class, creating a new row if needed and the allowCreate property is
|
||||
* true.
|
||||
*
|
||||
* @param type to find or create an entry for (often the fully-qualified class name)
|
||||
* @param clazz to find or create an entry for (this implementation uses the fully-qualified class name String)
|
||||
* @param allowCreate true if creation is permitted if not found
|
||||
*
|
||||
* @return the primary key or null if not found
|
||||
@@ -197,7 +195,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
protected Long createOrRetrieveSidPrimaryKey(Sid sid, boolean allowCreate) {
|
||||
Assert.notNull(sid, "Sid required");
|
||||
|
||||
String sidName;
|
||||
String sidName = null;
|
||||
boolean sidIsPrincipal = true;
|
||||
|
||||
if (sid instanceof PrincipalSid) {
|
||||
@@ -217,7 +215,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
}
|
||||
|
||||
if (allowCreate) {
|
||||
jdbcTemplate.update(insertSid, Boolean.valueOf(sidIsPrincipal), sidName);
|
||||
jdbcTemplate.update(insertSid, new Object[] {Boolean.valueOf(sidIsPrincipal), sidName});
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(), "Transaction must be running");
|
||||
return new Long(jdbcTemplate.queryForLong(sidIdentityQuery));
|
||||
}
|
||||
@@ -232,8 +230,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
if (deleteChildren) {
|
||||
List<ObjectIdentity> children = findChildren(objectIdentity);
|
||||
if (children != null) {
|
||||
for (ObjectIdentity child : children) {
|
||||
deleteAcl(child, true);
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
deleteAcl(children.get(i), true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -266,7 +264,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
* @param oidPrimaryKey the rows in acl_entry to delete
|
||||
*/
|
||||
protected void deleteEntries(Long oidPrimaryKey) {
|
||||
jdbcTemplate.update(deleteEntryByObjectIdentityForeignKey, oidPrimaryKey);
|
||||
jdbcTemplate.update(deleteEntryByObjectIdentityForeignKey,
|
||||
new Object[] {oidPrimaryKey});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +278,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
*/
|
||||
protected void deleteObjectIdentity(Long oidPrimaryKey) {
|
||||
// Delete the acl_object_identity row
|
||||
jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, oidPrimaryKey);
|
||||
jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, new Object[] {oidPrimaryKey});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,7 +292,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
*/
|
||||
protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
|
||||
try {
|
||||
return new Long(jdbcTemplate.queryForLong(selectObjectIdentityPrimaryKey, oid.getType(), oid.getIdentifier()));
|
||||
return new Long(jdbcTemplate.queryForLong(selectObjectIdentityPrimaryKey,
|
||||
new Object[] {oid.getType(), oid.getIdentifier()}));
|
||||
} catch (DataAccessException notFound) {
|
||||
return null;
|
||||
}
|
||||
@@ -327,8 +327,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
Assert.notNull(objectIdentity, "ObjectIdentity required");
|
||||
List<ObjectIdentity> children = findChildren(objectIdentity);
|
||||
if (children != null) {
|
||||
for (ObjectIdentity child : children) {
|
||||
clearCacheIncludingChildren(child);
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
clearCacheIncludingChildren(children.get(i));
|
||||
}
|
||||
}
|
||||
aclCache.evictFromCache(objectIdentity);
|
||||
@@ -357,7 +357,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
|
||||
Long ownerSid = createOrRetrieveSidPrimaryKey(acl.getOwner(), true);
|
||||
int count = jdbcTemplate.update(updateObjectIdentity,
|
||||
parentId, ownerSid, Boolean.valueOf(acl.isEntriesInheriting()), acl.getId());
|
||||
new Object[] {parentId, ownerSid, new Boolean(acl.isEntriesInheriting()), acl.getId()});
|
||||
|
||||
if (count != 1) {
|
||||
throw new NotFoundException("Unable to locate ACL to update");
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Map;
|
||||
* Performs lookups for {@link org.springframework.security.acls.model.AclService}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface LookupStrategy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* JDBC-based persistence of ACL information
|
||||
*/
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
JDBC-based persistence of ACL information.
|
||||
</body>
|
||||
</html>
|
||||
@@ -27,6 +27,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AccessControlEntry extends Serializable {
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Implementing classes may elect to return instances that represent
|
||||
* Implementing classes may elect to return instances that represent
|
||||
* {@link org.springframework.security.acls.model.Permission} information for either
|
||||
* some OR all {@link org.springframework.security.acls.model.Sid}
|
||||
* instances. Therefore, an instance may NOT necessarily contain ALL <tt>Sid</tt>s
|
||||
@@ -39,22 +39,23 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Acl extends Serializable {
|
||||
|
||||
/**
|
||||
* Returns all of the entries represented by the present <tt>Acl</tt>. Entries associated with
|
||||
* the <tt>Acl</tt> parents are not returned.
|
||||
*
|
||||
*
|
||||
* <p>This method is typically used for administrative purposes.</p>
|
||||
*
|
||||
*
|
||||
* <p>The order that entries appear in the array is important for methods declared in the
|
||||
* {@link MutableAcl} interface. Furthermore, some implementations MAY use ordering as
|
||||
* part of advanced permission checking.</p>
|
||||
*
|
||||
*
|
||||
* <p>Do <em>NOT</em> use this method for making authorization decisions. Instead use {@link
|
||||
* #isGranted(List, List, boolean)}.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of
|
||||
* <tt>Sid</tt>s. The caller is responsible for correctly handling the result if only a subset of
|
||||
* <tt>Sid</tt>s is represented.</p>
|
||||
@@ -83,11 +84,11 @@ public interface Acl extends Serializable {
|
||||
/**
|
||||
* A domain object may have a parent for the purpose of ACL inheritance. If there is a parent, its ACL can
|
||||
* be accessed via this method. In turn, the parent's parent (grandparent) can be accessed and so on.
|
||||
*
|
||||
*
|
||||
* <p>This method solely represents the presence of a navigation hierarchy between the parent <tt>Acl</tt> and this
|
||||
* <tt>Acl</tt>. For actual inheritance to take place, the {@link #isEntriesInheriting()} must also be
|
||||
* <tt>true</tt>.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of
|
||||
* <tt>Sid</tt>s. The caller is responsible for correctly handling the result if only a subset of
|
||||
* <tt>Sid</tt>s is represented.</p>
|
||||
@@ -110,13 +111,13 @@ public interface Acl extends Serializable {
|
||||
/**
|
||||
* This is the actual authorization logic method, and must be used whenever ACL authorization decisions are
|
||||
* required.
|
||||
*
|
||||
*
|
||||
* <p>An array of <tt>Sid</tt>s are presented, representing security identifies of the current
|
||||
* principal. In addition, an array of <tt>Permission</tt>s is presented which will have one or more bits set
|
||||
* in order to indicate the permissions needed for an affirmative authorization decision. An array is presented
|
||||
* because holding <em>any</em> of the <tt>Permission</tt>s inside the array will be sufficient for an
|
||||
* affirmative authorization.</p>
|
||||
*
|
||||
*
|
||||
* <p>The actual approach used to make authorization decisions is left to the implementation and is not
|
||||
* specified by this interface. For example, an implementation <em>MAY</em> search the current ACL in the order
|
||||
* the ACL entries have been stored. If a single entry is found that has the same active bits as are shown in a
|
||||
@@ -126,9 +127,9 @@ public interface Acl extends Serializable {
|
||||
* ACL, provided that {@link #isEntriesInheriting()} is <tt>true</tt>, the authorization decision may be
|
||||
* passed to the parent ACL. If there is no matching entry, the implementation MAY throw an exception, or make a
|
||||
* predefined authorization decision.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of <tt>Sid</tt>s,
|
||||
* although the implementation is permitted to throw one of the signature-defined exceptions if the method
|
||||
* although the implementation is permitted to throw one of the signature-defined exceptions if the method
|
||||
* is called requesting an authorization decision for a {@link Sid} that was never loaded in this <tt>Acl</tt>.
|
||||
* </p>
|
||||
*
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.io.Serializable;
|
||||
* A caching layer for {@link JdbcAclService}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AclCache {
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ package org.springframework.security.acls.model;
|
||||
* Abstract base class for Acl data operations.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AclDataAccessException extends RuntimeException {
|
||||
@@ -13,7 +14,7 @@ public abstract class AclDataAccessException extends RuntimeException {
|
||||
* message and root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
* @param t the root cause
|
||||
*/
|
||||
public AclDataAccessException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
* Provides retrieval of {@link Acl} instances.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclService {
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -37,7 +38,7 @@ public interface AclService {
|
||||
List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity);
|
||||
|
||||
/**
|
||||
* Same as {@link #readAclsById(List)} except it returns only a single Acl.
|
||||
* Same as {@link #readAclsById(Java.util.List<ObjectIdentity>)} except it returns only a single Acl.
|
||||
* <p>
|
||||
* This method should not be called as it does not leverage the underlying implementation's potential ability to
|
||||
* filter <tt>Acl</tt> entries based on a {@link Sid} parameter.</p>
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an <code>Acl</code> entry already exists for the object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlreadyExistsException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+1
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Represents an ACE that provides auditing information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditableAccessControlEntry extends AccessControlEntry {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* A mutable ACL that provides audit capabilities.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditableAcl extends MutableAcl {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an {@link Acl} cannot be deleted because children <code>Acl</code>s exist.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ChildrenExistException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.Serializable;
|
||||
* before allowing access to its methods.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface MutableAcl extends Acl {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.springframework.security.acls.model;
|
||||
* Provides support for creating and storing <code>Acl</code> instances.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface MutableAclService extends AclService {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an ACL-related object cannot be found.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NotFoundException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface ObjectIdentity extends Serializable {
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -51,7 +52,7 @@ public interface ObjectIdentity extends Serializable {
|
||||
* business meaning, as that business meaning may change in the future such change will cascade to the ACL
|
||||
* subsystem data.</p>
|
||||
*
|
||||
* @return the identifier (unique within this <tt>type</tt>; never <tt>null</tt>)
|
||||
* @return the identifier (unique within this <tt>javaType</tt>; never <tt>null</tt>)
|
||||
*/
|
||||
Serializable getIdentifier();
|
||||
|
||||
|
||||
+4
-3
@@ -4,13 +4,14 @@ import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy which creates an {@link ObjectIdentity} from an object identifier (such as a primary key)
|
||||
* Strategy which creates an <tt>ObjectIdentity</tt> from an object identifier (such as a primary key)
|
||||
* and type information.
|
||||
* <p>
|
||||
* Differs from {@link ObjectIdentityRetrievalStrategy} in that it is used in situations when the actual object
|
||||
* instance isn't available.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface ObjectIdentityGenerator {
|
||||
@@ -18,8 +19,8 @@ public interface ObjectIdentityGenerator {
|
||||
/**
|
||||
*
|
||||
* @param id the identifier of the domain object, not null
|
||||
* @param type the type of the object (often a class name), not null
|
||||
* @return the identity constructed using the supplied identifier and type information.
|
||||
* @param type the type of the object (usually a class name), not null
|
||||
* @return
|
||||
*/
|
||||
ObjectIdentity createObjectIdentity(Serializable id, String type);
|
||||
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ package org.springframework.security.acls.model;
|
||||
* will be returned for a particular domain object
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface ObjectIdentityRetrievalStrategy {
|
||||
|
||||
@@ -24,6 +24,7 @@ package org.springframework.security.acls.model;
|
||||
* well as assign a new owner.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface OwnershipAcl extends MutableAcl {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.Serializable;
|
||||
* Represents a permission granted to a <tt>Sid</tt> for a given domain object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Permission extends Serializable {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
package org.springframework.security.acls.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Allow customization of the logic for determining whether a permission or permissions are granted to a particular
|
||||
* sid or sids by an {@link Acl}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @since 3.0.2
|
||||
*/
|
||||
public interface PermissionGrantingStrategy {
|
||||
|
||||
/**
|
||||
* Returns true if the the supplied strategy decides that the supplied {@code Acl} grants access
|
||||
* based on the supplied list of permissions and sids.
|
||||
*/
|
||||
boolean isGranted(Acl acl, List<Permission> permission, List<Sid> sids, boolean administrativeMode);
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Sid extends Serializable {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.security.core.Authentication;
|
||||
* for an {@link Authentication}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SidRetrievalStrategy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.springframework.security.acls.model;
|
||||
* the caller has requested details for an unloaded <code>Sid</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class UnloadedSidException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
|
||||
*/
|
||||
package org.springframework.security.acls.model;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* The Spring Security ACL package which implements instance-based security for domain objects.
|
||||
* <p>
|
||||
* Consider using the annotation based approach ({@code @PreAuthorize}, {@code @PostFilter} annotations) combined
|
||||
* with a {@link org.springframework.security.acls.AclPermissionEvaluator} in preference to the older and more verbose
|
||||
* attribute/voter/after-invocation approach from versions before Spring Security 3.0.
|
||||
*/
|
||||
package org.springframework.security.acls;
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
-- ACL schema sql used in HSQLDB
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
create table acl_sid(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal)
|
||||
);
|
||||
|
||||
create table acl_class(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
class varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
-- ACL schema sql used in HSQLDB
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
|
||||
create table acl_sid(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal));
|
||||
|
||||
create table acl_class(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
class varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
-- ACL Schema SQL for MySQL 5.5+ / MariaDB equivalent
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
CREATE TABLE acl_sid (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
principal BOOLEAN NOT NULL,
|
||||
sid VARCHAR(100) NOT NULL,
|
||||
UNIQUE KEY unique_acl_sid (sid, principal)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE acl_class (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
class VARCHAR(100) NOT NULL,
|
||||
UNIQUE KEY uk_acl_class (class)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE acl_object_identity (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
object_id_class BIGINT UNSIGNED NOT NULL,
|
||||
object_id_identity BIGINT NOT NULL,
|
||||
parent_object BIGINT UNSIGNED,
|
||||
owner_sid BIGINT UNSIGNED,
|
||||
entries_inheriting BOOLEAN NOT NULL,
|
||||
UNIQUE KEY uk_acl_object_identity (object_id_class, object_id_identity),
|
||||
CONSTRAINT fk_acl_object_identity_parent FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_object_identity_class FOREIGN KEY (object_id_class) REFERENCES acl_class (id),
|
||||
CONSTRAINT fk_acl_object_identity_owner FOREIGN KEY (owner_sid) REFERENCES acl_sid (id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE acl_entry (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
acl_object_identity BIGINT UNSIGNED NOT NULL,
|
||||
ace_order INTEGER NOT NULL,
|
||||
sid BIGINT UNSIGNED NOT NULL,
|
||||
mask INTEGER UNSIGNED NOT NULL,
|
||||
granting BOOLEAN NOT NULL,
|
||||
audit_success BOOLEAN NOT NULL,
|
||||
audit_failure BOOLEAN NOT NULL,
|
||||
UNIQUE KEY unique_acl_entry (acl_object_identity, ace_order),
|
||||
CONSTRAINT fk_acl_entry_object FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_entry_acl FOREIGN KEY (sid) REFERENCES acl_sid (id)
|
||||
) ENGINE=InnoDB;
|
||||
@@ -1,82 +0,0 @@
|
||||
-- ACL Schema SQL for Oracle Database 10g+
|
||||
|
||||
-- drop trigger acl_sid_id_trigger;
|
||||
-- drop trigger acl_class_id_trigger;
|
||||
-- drop trigger acl_object_identity_id_trigger;
|
||||
-- drop trigger acl_entry_id_trigger;
|
||||
-- drop sequence acl_sid_sequence;
|
||||
-- drop sequence acl_class_sequence;
|
||||
-- drop sequence acl_object_identity_sequence;
|
||||
-- drop sequence acl_entry_sequence;
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
CREATE TABLE acl_sid (
|
||||
id NUMBER(38) NOT NULL PRIMARY KEY,
|
||||
principal NUMBER(1) NOT NULL CHECK (principal in (0, 1)),
|
||||
sid NVARCHAR2(100) NOT NULL,
|
||||
CONSTRAINT unique_acl_sid UNIQUE (sid, principal)
|
||||
);
|
||||
CREATE SEQUENCE acl_sid_sequence START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
CREATE OR REPLACE TRIGGER acl_sid_id_trigger
|
||||
BEFORE INSERT ON acl_sid
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SELECT acl_sid_sequence.nextval INTO :new.id FROM dual;
|
||||
END;
|
||||
|
||||
CREATE TABLE acl_class (
|
||||
id NUMBER(38) NOT NULL PRIMARY KEY,
|
||||
class NVARCHAR2(100) NOT NULL,
|
||||
CONSTRAINT uk_acl_class UNIQUE (class)
|
||||
);
|
||||
CREATE SEQUENCE acl_class_sequence START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
CREATE OR REPLACE TRIGGER acl_class_id_trigger
|
||||
BEFORE INSERT ON acl_class
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SELECT acl_class_sequence.nextval INTO :new.id FROM dual;
|
||||
END;
|
||||
|
||||
CREATE TABLE acl_object_identity (
|
||||
id NUMBER(38) NOT NULL PRIMARY KEY,
|
||||
object_id_class NUMBER(38) NOT NULL,
|
||||
object_id_identity NUMBER(38) NOT NULL,
|
||||
parent_object NUMBER(38),
|
||||
owner_sid NUMBER(38),
|
||||
entries_inheriting NUMBER(1) NOT NULL CHECK (entries_inheriting in (0, 1)),
|
||||
CONSTRAINT uk_acl_object_identity UNIQUE (object_id_class, object_id_identity),
|
||||
CONSTRAINT fk_acl_object_identity_parent FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_object_identity_class FOREIGN KEY (object_id_class) REFERENCES acl_class (id),
|
||||
CONSTRAINT fk_acl_object_identity_owner FOREIGN KEY (owner_sid) REFERENCES acl_sid (id)
|
||||
);
|
||||
CREATE SEQUENCE acl_object_identity_sequence START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
CREATE OR REPLACE TRIGGER acl_object_identity_id_trigger
|
||||
BEFORE INSERT ON acl_object_identity
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SELECT acl_object_identity_sequence.nextval INTO :new.id FROM dual;
|
||||
END;
|
||||
|
||||
CREATE TABLE acl_entry (
|
||||
id NUMBER(38) NOT NULL PRIMARY KEY,
|
||||
acl_object_identity NUMBER(38) NOT NULL,
|
||||
ace_order INTEGER NOT NULL,
|
||||
sid NUMBER(38) NOT NULL,
|
||||
mask INTEGER NOT NULL,
|
||||
granting NUMBER(1) NOT NULL CHECK (granting in (0, 1)),
|
||||
audit_success NUMBER(1) NOT NULL CHECK (audit_success in (0, 1)),
|
||||
audit_failure NUMBER(1) NOT NULL CHECK (audit_failure in (0, 1)),
|
||||
CONSTRAINT unique_acl_entry UNIQUE (acl_object_identity, ace_order),
|
||||
CONSTRAINT fk_acl_entry_object FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_entry_acl FOREIGN KEY (sid) REFERENCES acl_sid (id)
|
||||
);
|
||||
CREATE SEQUENCE acl_entry_sequence START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
CREATE OR REPLACE TRIGGER acl_entry_id_trigger
|
||||
BEFORE INSERT ON acl_entry
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SELECT acl_entry_sequence.nextval INTO :new.id FROM dual;
|
||||
END;
|
||||
@@ -1,46 +1,46 @@
|
||||
-- ACL Schema SQL for PostgreSQL
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
create table acl_sid(
|
||||
id bigserial not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal)
|
||||
);
|
||||
|
||||
create table acl_class(
|
||||
id bigserial not null primary key,
|
||||
class varchar(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigserial primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigserial primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
-- ACL Schema SQL for PostgreSQL
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
create table acl_sid(
|
||||
id bigserial not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal)
|
||||
);
|
||||
|
||||
create table acl_class(
|
||||
id bigserial not null primary key,
|
||||
class varchar(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigserial primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigserial primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
-- ACL Schema SQL for Microsoft SQL Server 2008+
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
CREATE TABLE acl_sid (
|
||||
id BIGINT NOT NULL IDENTITY PRIMARY KEY,
|
||||
principal BIT NOT NULL,
|
||||
sid VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT unique_acl_sid UNIQUE (sid, principal)
|
||||
);
|
||||
|
||||
CREATE TABLE acl_class (
|
||||
id BIGINT NOT NULL IDENTITY PRIMARY KEY,
|
||||
class VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT uk_acl_class UNIQUE (class)
|
||||
);
|
||||
|
||||
CREATE TABLE acl_object_identity (
|
||||
id BIGINT NOT NULL IDENTITY PRIMARY KEY,
|
||||
object_id_class BIGINT NOT NULL,
|
||||
object_id_identity BIGINT NOT NULL,
|
||||
parent_object BIGINT,
|
||||
owner_sid BIGINT,
|
||||
entries_inheriting BIT NOT NULL,
|
||||
CONSTRAINT uk_acl_object_identity UNIQUE (object_id_class, object_id_identity),
|
||||
CONSTRAINT fk_acl_object_identity_parent FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_object_identity_class FOREIGN KEY (object_id_class) REFERENCES acl_class (id),
|
||||
CONSTRAINT fk_acl_object_identity_owner FOREIGN KEY (owner_sid) REFERENCES acl_sid (id)
|
||||
);
|
||||
|
||||
CREATE TABLE acl_entry (
|
||||
id BIGINT NOT NULL IDENTITY PRIMARY KEY,
|
||||
acl_object_identity BIGINT NOT NULL,
|
||||
ace_order INTEGER NOT NULL,
|
||||
sid BIGINT NOT NULL,
|
||||
mask INTEGER NOT NULL,
|
||||
granting BIT NOT NULL,
|
||||
audit_success BIT NOT NULL,
|
||||
audit_failure BIT NOT NULL,
|
||||
CONSTRAINT unique_acl_entry UNIQUE (acl_object_identity, ace_order),
|
||||
CONSTRAINT fk_acl_entry_object FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity (id),
|
||||
CONSTRAINT fk_acl_entry_acl FOREIGN KEY (sid) REFERENCES acl_sid (id)
|
||||
);
|
||||
@@ -1,39 +1,39 @@
|
||||
-- Not required. Just shows the sort of queries being sent to DB.
|
||||
|
||||
|
||||
select acl_object_identity.object_id_identity,
|
||||
acl_entry.ace_order,
|
||||
acl_object_identity.id as acl_id,
|
||||
acl_object_identity.parent_object,
|
||||
acl_object_identity,
|
||||
entries_inheriting,
|
||||
acl_entry.id as ace_id,
|
||||
acl_entry.mask,
|
||||
acl_entry.granting,
|
||||
acl_entry.audit_success,
|
||||
acl_entry.audit_failure,
|
||||
acl_sid.principal as ace_principal,
|
||||
acl_sid.sid as ace_sid,
|
||||
acli_sid.principal as acl_principal,
|
||||
acli_sid.sid as acl_sid,
|
||||
acl_class.class
|
||||
|
||||
from acl_object_identity,
|
||||
acl_sid acli_sid,
|
||||
acl_class
|
||||
|
||||
left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity
|
||||
left join acl_sid on acl_entry.sid = acl_sid.id
|
||||
|
||||
where
|
||||
acli_sid.id = acl_object_identity.owner_sid
|
||||
|
||||
and acl_class.id = acl_object_identity.object_id_class
|
||||
|
||||
and (
|
||||
|
||||
(acl_object_identity.object_id_identity = 1 and acl_class.class = 'sample.contact.contact')
|
||||
or
|
||||
(acl_object_identity.object_id_identity = 2000 and acl_class.class = 'sample.contact.contact')
|
||||
|
||||
) order by acl_object_identity.object_id_identity asc, acl_entry.ace_order asc
|
||||
-- Not required. Just shows the sort of queries being sent to DB.
|
||||
|
||||
|
||||
select acl_object_identity.object_id_identity,
|
||||
acl_entry.ace_order,
|
||||
acl_object_identity.id as acl_id,
|
||||
acl_object_identity.parent_object,
|
||||
acl_object_identity,
|
||||
entries_inheriting,
|
||||
acl_entry.id as ace_id,
|
||||
acl_entry.mask,
|
||||
acl_entry.granting,
|
||||
acl_entry.audit_success,
|
||||
acl_entry.audit_failure,
|
||||
acl_sid.principal as ace_principal,
|
||||
acl_sid.sid as ace_sid,
|
||||
acli_sid.principal as acl_principal,
|
||||
acli_sid.sid as acl_sid,
|
||||
acl_class.class
|
||||
|
||||
from acl_object_identity,
|
||||
acl_sid acli_sid,
|
||||
acl_class
|
||||
|
||||
left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity
|
||||
left join acl_sid on acl_entry.sid = acl_sid.id
|
||||
|
||||
where
|
||||
acli_sid.id = acl_object_identity.owner_sid
|
||||
|
||||
and acl_class.id = acl_object_identity.object_id_class
|
||||
|
||||
and (
|
||||
|
||||
(acl_object_identity.object_id_identity = 1 and acl_class.class = 'sample.contact.contact')
|
||||
or
|
||||
(acl_object_identity.object_id_identity = 2000 and acl_class.class = 'sample.contact.contact')
|
||||
|
||||
) order by acl_object_identity.object_id_identity asc, acl_entry.ace_order asc
|
||||
|
||||
+127
-135
@@ -1,135 +1,127 @@
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import org.springframework.security.acls.domain.AclFormattingUtils;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link AclFormattingUtils}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclFormattingUtilsTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public final void testDemergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testDemergePatterns() throws Exception {
|
||||
String original = "...........................A...R";
|
||||
String removeBits = "...............................R";
|
||||
Assert.assertEquals("...........................A....", AclFormattingUtils
|
||||
.demergePatterns(original, removeBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.demergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("......", AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testMergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testMergePatterns() throws Exception {
|
||||
String original = "...............................R";
|
||||
String extraBits = "...........................A....";
|
||||
Assert.assertEquals("...........................A...R", AclFormattingUtils
|
||||
.mergePatterns(original, extraBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.mergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("GHIJKL", AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testBinaryPrints() throws Exception {
|
||||
Assert.assertEquals("............................****", AclFormattingUtils.printBinary(15));
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_ON);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
Assert.assertEquals("............................xxxx", AclFormattingUtils.printBinary(15, 'x'));
|
||||
}
|
||||
|
||||
public void testPrintBinaryNegative() {
|
||||
Assert.assertEquals("*...............................", AclFormattingUtils.printBinary(0x80000000));
|
||||
}
|
||||
|
||||
public void testPrintBinaryMinusOne() {
|
||||
Assert.assertEquals("********************************", AclFormattingUtils.printBinary(0xffffffff));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import org.springframework.security.acls.domain.AclFormattingUtils;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link AclFormattingUtils}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclFormattingUtilsTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public final void testDemergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testDemergePatterns() throws Exception {
|
||||
String original = "...........................A...R";
|
||||
String removeBits = "...............................R";
|
||||
Assert.assertEquals("...........................A....", AclFormattingUtils
|
||||
.demergePatterns(original, removeBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.demergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("......", AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testMergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testMergePatterns() throws Exception {
|
||||
String original = "...............................R";
|
||||
String extraBits = "...........................A....";
|
||||
Assert.assertEquals("...........................A...R", AclFormattingUtils
|
||||
.mergePatterns(original, extraBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.mergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("GHIJKL", AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testBinaryPrints() throws Exception {
|
||||
Assert.assertEquals("............................****", AclFormattingUtils.printBinary(15));
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_ON);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
Assert.assertEquals("............................xxxx", AclFormattingUtils.printBinary(15, 'x'));
|
||||
}
|
||||
}
|
||||
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.AclService;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public class AclPermissionCacheOptimizerTests {
|
||||
|
||||
@Test
|
||||
public void eagerlyLoadsRequiredAcls() throws Exception {
|
||||
AclService service = mock(AclService.class);
|
||||
AclPermissionCacheOptimizer pco = new AclPermissionCacheOptimizer(service);
|
||||
ObjectIdentityRetrievalStrategy oidStrat = mock(ObjectIdentityRetrievalStrategy.class);
|
||||
SidRetrievalStrategy sidStrat = mock(SidRetrievalStrategy.class);
|
||||
pco.setObjectIdentityRetrievalStrategy(oidStrat);
|
||||
pco.setSidRetrievalStrategy(sidStrat);
|
||||
Object[] dos = {new Object(), null, new Object()};
|
||||
ObjectIdentity[] oids = {new ObjectIdentityImpl("A", "1"), new ObjectIdentityImpl("A", "2")};
|
||||
when(oidStrat.getObjectIdentity(dos[0])).thenReturn(oids[0]);
|
||||
when(oidStrat.getObjectIdentity(dos[2])).thenReturn(oids[1]);
|
||||
|
||||
pco.cachePermissionsFor(mock(Authentication.class), Arrays.asList(dos));
|
||||
|
||||
// AclService should be invoked with the list of required Oids
|
||||
verify(service).readAclsById(eq(Arrays.asList(oids)), any(List.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoresEmptyCollection() {
|
||||
AclService service = mock(AclService.class);
|
||||
AclPermissionCacheOptimizer pco = new AclPermissionCacheOptimizer(service);
|
||||
ObjectIdentityRetrievalStrategy oids = mock(ObjectIdentityRetrievalStrategy.class);
|
||||
SidRetrievalStrategy sids = mock(SidRetrievalStrategy.class);
|
||||
pco.setObjectIdentityRetrievalStrategy(oids);
|
||||
pco.setSidRetrievalStrategy(sids);
|
||||
|
||||
pco.cachePermissionsFor(mock(Authentication.class), Collections.emptyList());
|
||||
|
||||
verifyZeroInteractions(service, sids, oids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.springframework.security.core.Authentication;
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AclPermissionEvaluatorTests {
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.springframework.security.acls;
|
||||
* Dummy domain object class
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class TargetObject {
|
||||
|
||||
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.acls.model.*;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public class AclEntryAfterInvocationCollectionFilteringProviderTests {
|
||||
@Test
|
||||
public void objectsAreRemovedIfPermissionDenied() throws Exception {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(false);
|
||||
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl);
|
||||
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(service, Arrays.asList(mock(Permission.class)));
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
provider.setProcessDomainObjectClass(Object.class);
|
||||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
|
||||
Object returned = provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), new ArrayList(Arrays.asList(new Object(), new Object())));
|
||||
assertTrue(returned instanceof List);
|
||||
assertTrue(((List)returned).isEmpty());
|
||||
returned = provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "AFTER_ACL_COLLECTION_READ"), new Object[] {new Object(), new Object()});
|
||||
assertTrue(returned instanceof Object[]);
|
||||
assertTrue(((Object[])returned).length == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsGrantedIfNoAttributesDefined() throws Exception {
|
||||
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
Object returned = new Object();
|
||||
|
||||
assertSame(returned, provider.decide(mock(Authentication.class), new Object(), Collections.<ConfigAttribute>emptyList(), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullReturnObjectIsIgnored() throws Exception {
|
||||
AclService service = mock(AclService.class);
|
||||
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(service, Arrays.asList(mock(Permission.class)));
|
||||
|
||||
assertNull(provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null));
|
||||
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
|
||||
}
|
||||
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.acls.model.*;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public class AclEntryAfterInvocationProviderTests {
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void rejectsMissingPermissions() throws Exception {
|
||||
try {
|
||||
new AclEntryAfterInvocationProvider(mock(AclService.class), null);
|
||||
fail("Exception expected");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
new AclEntryAfterInvocationProvider(mock(AclService.class), Collections.<Permission>emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsAllowedIfPermissionIsGranted() {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(true);
|
||||
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class)));
|
||||
provider.setMessageSource(new SpringSecurityMessageSource());
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
provider.setProcessDomainObjectClass(Object.class);
|
||||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
Object returned = new Object();
|
||||
|
||||
assertSame(returned, provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_READ"), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsGrantedIfNoAttributesDefined() throws Exception {
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
Object returned = new Object();
|
||||
|
||||
assertSame(returned, provider.decide(mock(Authentication.class), new Object(), Collections.<ConfigAttribute>emptyList(), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsGrantedIfObjectTypeNotSupported() throws Exception {
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
provider.setProcessDomainObjectClass(String.class);
|
||||
// Not a String
|
||||
Object returned = new Object();
|
||||
|
||||
assertSame(returned, provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_READ"), returned));
|
||||
}
|
||||
|
||||
|
||||
@Test(expected= AccessDeniedException.class)
|
||||
public void accessIsDeniedIfPermissionIsNotGranted() {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(false);
|
||||
// Try a second time with no permissions found
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenThrow(new NotFoundException(""));
|
||||
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class)));
|
||||
provider.setProcessConfigAttribute("MY_ATTRIBUTE");
|
||||
provider.setMessageSource(new SpringSecurityMessageSource());
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
provider.setProcessDomainObjectClass(Object.class);
|
||||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
try {
|
||||
provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object());
|
||||
fail();
|
||||
} catch (AccessDeniedException expected) {
|
||||
}
|
||||
// Second scenario with no acls found
|
||||
provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullReturnObjectIsIgnored() throws Exception {
|
||||
AclService service = mock(AclService.class);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class)));
|
||||
|
||||
assertNull(provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null));
|
||||
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
|
||||
}
|
||||
}
|
||||
+105
-100
@@ -1,100 +1,105 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessControlEntryImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AccessControlImplEntryTests {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testConstructorRequiredFields() {
|
||||
// Check Acl field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"),
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Sid field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, mock(Acl.class), null,
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Permission field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, mock(Acl.class), new PrincipalSid("johndoe"), null,
|
||||
true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessControlEntryImplGetters() {
|
||||
Acl mockAcl = mock(Acl.class);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
// Create a sample entry
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
// and check every get() method
|
||||
assertEquals(new Long(1), ace.getId());
|
||||
assertEquals(mockAcl, ace.getAcl());
|
||||
assertEquals(sid, ace.getSid());
|
||||
assertTrue(ace.isGranting());
|
||||
assertEquals(BasePermission.ADMINISTRATION, ace.getPermission());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditFailure());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
final Acl mockAcl = mock(Acl.class);
|
||||
final ObjectIdentity oid = mock(ObjectIdentity.class);
|
||||
|
||||
when(mockAcl.getObjectIdentity()).thenReturn(oid);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
assertFalse(ace.equals(null));
|
||||
assertFalse(ace.equals(Long.valueOf(100)));
|
||||
assertTrue(ace.equals(ace));
|
||||
assertTrue(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(2), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, new PrincipalSid("scott"),
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid, BasePermission.WRITE, true,
|
||||
true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, false, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, false, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, false)));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessControlEntryImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccessControlImplEntryTests {
|
||||
Mockery jmock = new JUnit4Mockery();
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testConstructorRequiredFields() {
|
||||
// Check Acl field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"),
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Sid field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), null,
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Permission field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), new PrincipalSid("johndoe"), null,
|
||||
true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessControlEntryImplGetters() {
|
||||
Acl mockAcl = jmock.mock(Acl.class);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
// Create a sample entry
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
// and check every get() method
|
||||
assertEquals(new Long(1), ace.getId());
|
||||
assertEquals(mockAcl, ace.getAcl());
|
||||
assertEquals(sid, ace.getSid());
|
||||
assertTrue(ace.isGranting());
|
||||
assertEquals(BasePermission.ADMINISTRATION, ace.getPermission());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditFailure());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
final Acl mockAcl = jmock.mock(Acl.class);
|
||||
final ObjectIdentity oid = jmock.mock(ObjectIdentity.class);
|
||||
jmock.checking(new Expectations() {{
|
||||
allowing(mockAcl).getObjectIdentity(); will(returnValue(oid));
|
||||
}});
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
assertFalse(ace.equals(null));
|
||||
assertFalse(ace.equals(new Long(100)));
|
||||
assertTrue(ace.equals(ace));
|
||||
assertTrue(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(2), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, new PrincipalSid("scott"),
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.WRITE, true,
|
||||
true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, false, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, false, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, false)));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+260
-259
@@ -1,259 +1,260 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl}
|
||||
* security checks.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplementationSecurityCheckTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityCheckNoACEs() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password","ROLE_GENERAL","ROLE_AUDITING","ROLE_OWNERSHIP");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
|
||||
// Create another authorization strategy
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority("ROLE_TWO"),
|
||||
new SimpleGrantedAuthority("ROLE_THREE"));
|
||||
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
|
||||
// Check access in case the principal has no authorization rights
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityCheckWithMultipleACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
// Let's give the principal the ADMINISTRATION permission, without
|
||||
// granting access
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
|
||||
// The CHANGE_GENERAL test should pass as the principal has ROLE_GENERAL
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
|
||||
// The CHANGE_AUDITING and CHANGE_OWNERSHIP should fail since the
|
||||
// principal doesn't have these authorities,
|
||||
// nor granting access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Add granting access to this principal
|
||||
aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
// and try again for CHANGE_AUDITING - the first ACE's granting flag
|
||||
// (false) will deny this access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Create another ACL and give the principal the ADMINISTRATION
|
||||
// permission, with granting access
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
|
||||
// The CHANGE_AUDITING test should pass as there is one ACE with
|
||||
// granting access
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
|
||||
// Add a deny ACE and test again for CHANGE_AUDITING
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
|
||||
// Create an ACL with no ACE
|
||||
MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
// and still grant access for CHANGE_GENERAL
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityCheckWithInheritableACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority("ROLE_TWO"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
// Let's give the principal an ADMINISTRATION permission, with granting
|
||||
// access
|
||||
MutableAcl parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
MutableAcl childAcl = new AclImpl(identity, 2, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Check against the 'child' acl, which doesn't offer any authorization
|
||||
// rights on CHANGE_OWNERSHIP
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
// Link the child with its parent and test again against the
|
||||
// CHANGE_OWNERSHIP right
|
||||
childAcl.setParent(parentAcl);
|
||||
childAcl.setEntriesInheriting(true);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
// Create a root parent and link it to the middle parent
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
parentAcl.setEntriesInheriting(true);
|
||||
parentAcl.setParent(rootParentAcl);
|
||||
childAcl.setParent(parentAcl);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testSecurityCheckPrincipalOwner() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_ONE");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
Acl acl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null,
|
||||
false, new PrincipalSid(auth));
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl}
|
||||
* security checks.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplementationSecurityCheckTests extends TestCase {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void testSecurityCheckNoACEs() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password","ROLE_GENERAL","ROLE_AUDITING","ROLE_OWNERSHIP");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
|
||||
// Create another authorization strategy
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_THREE") });
|
||||
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
|
||||
// Check access in case the principal has no authorization rights
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithMultipleACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal the ADMINISTRATION permission, without
|
||||
// granting access
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
|
||||
// The CHANGE_GENERAL test should pass as the principal has ROLE_GENERAL
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
|
||||
// The CHANGE_AUDITING and CHANGE_OWNERSHIP should fail since the
|
||||
// principal doesn't have these authorities,
|
||||
// nor granting access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Add granting access to this principal
|
||||
aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
// and try again for CHANGE_AUDITING - the first ACE's granting flag
|
||||
// (false) will deny this access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Create another ACL and give the principal the ADMINISTRATION
|
||||
// permission, with granting access
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
|
||||
// The CHANGE_AUDITING test should pass as there is one ACE with
|
||||
// granting access
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
|
||||
// Add a deny ACE and test again for CHANGE_AUDITING
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
|
||||
// Create an ACL with no ACE
|
||||
MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
// and still grant access for CHANGE_GENERAL
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithInheritableACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal an ADMINISTRATION permission, with granting
|
||||
// access
|
||||
MutableAcl parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
MutableAcl childAcl = new AclImpl(identity, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Check against the 'child' acl, which doesn't offer any authorization
|
||||
// rights on CHANGE_OWNERSHIP
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
// Link the child with its parent and test again against the
|
||||
// CHANGE_OWNERSHIP right
|
||||
childAcl.setParent(parentAcl);
|
||||
childAcl.setEntriesInheriting(true);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
// Create a root parent and link it to the middle parent
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
parentAcl.setEntriesInheriting(true);
|
||||
parentAcl.setParent(rootParentAcl);
|
||||
childAcl.setParent(parentAcl);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckPrincipalOwner() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_ONE"),
|
||||
new GrantedAuthorityImpl("ROLE_ONE") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null,
|
||||
false, new PrincipalSid(auth));
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +1,92 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
|
||||
/**
|
||||
* Test class for {@link ConsoleAuditLogger}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AuditLoggerTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
private PrintStream console;
|
||||
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
private ConsoleAuditLogger logger;
|
||||
private AuditableAccessControlEntry ace;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
logger = new ConsoleAuditLogger();
|
||||
ace = mock(AuditableAccessControlEntry.class);
|
||||
console = System.out;
|
||||
System.setOut(new PrintStream(bytes));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.setOut(console);
|
||||
bytes.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAuditableAceIsIgnored() {
|
||||
AccessControlEntry ace = mock(AccessControlEntry.class);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
when(ace.isAuditSuccess()).thenReturn(false);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
|
||||
when(ace.isAuditSuccess()).thenReturn(true);
|
||||
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertTrue(bytes.toString().startsWith("GRANTED due to ACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
when(ace.isAuditFailure()).thenReturn(false);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
|
||||
when(ace.isAuditFailure()).thenReturn(true);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertTrue(bytes.toString().startsWith("DENIED due to ACE"));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
|
||||
/**
|
||||
* Test class for {@link ConsoleAuditLogger}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuditLoggerTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
private Mockery jmock = new JUnit4Mockery();
|
||||
private PrintStream console;
|
||||
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
private ConsoleAuditLogger logger;
|
||||
private AuditableAccessControlEntry ace;
|
||||
private Expectations aceRequiresAudit;
|
||||
private Expectations aceDoesntRequireAudit;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
logger = new ConsoleAuditLogger();
|
||||
ace = jmock.mock(AuditableAccessControlEntry.class);
|
||||
aceRequiresAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(true));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(true));
|
||||
}};
|
||||
aceDoesntRequireAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(false));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(false));
|
||||
}};
|
||||
|
||||
console = System.out;
|
||||
System.setOut(new PrintStream(bytes));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.setOut(console);
|
||||
bytes.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAuditableAceIsIgnored() {
|
||||
AccessControlEntry ace = jmock.mock(AccessControlEntry.class);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertTrue(bytes.toString().startsWith("GRANTED due to ACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertTrue(bytes.toString().startsWith("DENIED due to ACE"));
|
||||
}
|
||||
}
|
||||
|
||||
+189
-189
@@ -1,189 +1,189 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.IdentityUnavailableException;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ObjectIdentityImplTests {
|
||||
|
||||
private static final String DOMAIN_CLASS =
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockIdDomainObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void constructorsRespectRequiredFields() throws Exception {
|
||||
// Check one-argument constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl(null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check String-Serializable constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Serializable parameter is not null
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// The correct way of using String-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check the Class-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(MockIdDomainObject.class, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gettersReturnExpectedValues() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
assertEquals(Long.valueOf(1), obj.getIdentifier());
|
||||
assertEquals(MockIdDomainObject.class.getName(), obj.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIdMethodConstraints() throws Exception {
|
||||
// Check the getId() method is present
|
||||
try {
|
||||
new ObjectIdentityImpl("A_STRING_OBJECT");
|
||||
fail("It should have thrown IdentityUnavailableException");
|
||||
}
|
||||
catch (IdentityUnavailableException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a non-null value
|
||||
MockIdDomainObject mockId = new MockIdDomainObject();
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new MockIdDomainObject());
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new Long(100));
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsInvalidTypeParameter() throws Exception {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
MockIdDomainObject mockObj = new MockIdDomainObject();
|
||||
mockObj.setId(Long.valueOf(1));
|
||||
|
||||
String string = "SOME_STRING";
|
||||
assertNotSame(obj, string);
|
||||
assertFalse(obj.equals(null));
|
||||
assertFalse(obj.equals("DIFFERENT_OBJECT_TYPE"));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2))));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
Long.valueOf(1))));
|
||||
assertEquals(new ObjectIdentityImpl(DOMAIN_CLASS,Long.valueOf(1)), obj);
|
||||
assertEquals(obj, new ObjectIdentityImpl(mockObj));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
|
||||
assertFalse(obj.hashCode() == obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndIntegerIdsWithSameValueAreEqualAndHaveSameHashcode() {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, new Long(5));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Integer.valueOf(5));
|
||||
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalStringIdsAreEqualAndHaveSameHashcode() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, "1000");
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringAndNumericIdsAreNotEqual() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertFalse(obj.equals(obj2));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockOtherIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.IdentityUnavailableException;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityImplTests {
|
||||
|
||||
private static final String DOMAIN_CLASS =
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockIdDomainObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void constructorsRespectRequiredFields() throws Exception {
|
||||
// Check one-argument constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl(null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check String-Serializable constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Serializable parameter is not null
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// The correct way of using String-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check the Class-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(MockIdDomainObject.class, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gettersReturnExpectedValues() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
assertEquals(Long.valueOf(1), obj.getIdentifier());
|
||||
assertEquals(MockIdDomainObject.class.getName(), obj.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIdMethodConstraints() throws Exception {
|
||||
// Check the getId() method is present
|
||||
try {
|
||||
new ObjectIdentityImpl("A_STRING_OBJECT");
|
||||
fail("It should have thrown IdentityUnavailableException");
|
||||
}
|
||||
catch (IdentityUnavailableException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a non-null value
|
||||
MockIdDomainObject mockId = new MockIdDomainObject();
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new MockIdDomainObject());
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new Long(100));
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsInvalidTypeParameter() throws Exception {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
MockIdDomainObject mockObj = new MockIdDomainObject();
|
||||
mockObj.setId(Long.valueOf(1));
|
||||
|
||||
String string = "SOME_STRING";
|
||||
assertNotSame(obj, string);
|
||||
assertFalse(obj.equals(null));
|
||||
assertFalse(obj.equals("DIFFERENT_OBJECT_TYPE"));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2))));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
Long.valueOf(1))));
|
||||
assertEquals(new ObjectIdentityImpl(DOMAIN_CLASS,Long.valueOf(1)), obj);
|
||||
assertEquals(obj, new ObjectIdentityImpl(mockObj));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
|
||||
assertFalse(obj.hashCode() == obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndIntegerIdsWithSameValueAreEqualAndHaveSameHashcode() {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, new Long(5));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, new Integer(5));
|
||||
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalStringIdsAreEqualAndHaveSameHashcode() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, "1000");
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringAndNumericIdsAreNotEqual() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertFalse(obj.equals(obj2));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class MockOtherIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-42
@@ -1,42 +1,42 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImplTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testObjectIdentityCreation() throws Exception {
|
||||
MockIdDomainObject domain = new MockIdDomainObject();
|
||||
domain.setId(Integer.valueOf(1));
|
||||
|
||||
ObjectIdentityRetrievalStrategy retStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
ObjectIdentity identity = retStrategy.getObjectIdentity(domain);
|
||||
|
||||
assertNotNull(identity);
|
||||
assertEquals(identity, new ObjectIdentityImpl(domain));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
@SuppressWarnings("unused")
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImplTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testObjectIdentityCreation() throws Exception {
|
||||
MockIdDomainObject domain = new MockIdDomainObject();
|
||||
domain.setId(new Integer(1));
|
||||
|
||||
ObjectIdentityRetrievalStrategy retStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
ObjectIdentity identity = retStrategy.getObjectIdentity(domain);
|
||||
|
||||
assertNotNull(identity);
|
||||
assertEquals(identity, new ObjectIdentityImpl(domain));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* Tests classes associated with Permission.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PermissionTests {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* A test permission.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SpecialPermission extends BasePermission {
|
||||
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
|
||||
|
||||
+310
-304
@@ -1,304 +1,310 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
import org.junit.*;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.BasePermission;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.DefaultPermissionFactory;
|
||||
import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Tests {@link BasicLookupStrategy}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class BasicLookupStrategyTests {
|
||||
|
||||
private static final Sid BEN_SID = new PrincipalSid("ben");
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static JdbcTemplate jdbcTemplate;
|
||||
private BasicLookupStrategy strategy;
|
||||
private static SingleConnectionDataSource dataSource;
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = CacheManager.create();
|
||||
cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createDatabase() throws Exception {
|
||||
dataSource = new SingleConnectionDataSource("jdbc:hsqldb:mem:lookupstrategytest", "sa", "", true);
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
|
||||
Resource resource = new ClassPathResource("createAclSchema.sql");
|
||||
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() throws Exception {
|
||||
dataSource.destroy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void populateDatabase() {
|
||||
String query = "INSERT INTO acl_sid(ID,PRINCIPAL,SID) VALUES (1,1,'ben');"
|
||||
+ "INSERT INTO acl_class(ID,CLASS) VALUES (2,'" + TARGET_CLASS + "');"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (1,2,100,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (2,2,101,1,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (3,2,102,2,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (1,1,0,1,1,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (2,1,1,1,2,0,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (3,2,0,1,8,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (4,3,0,1,8,0,0,0);";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeBeans() {
|
||||
EhCacheBasedAclCache cache = new EhCacheBasedAclCache(getCache());
|
||||
AclAuthorizationStrategy authorizationStrategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"));
|
||||
strategy = new BasicLookupStrategy(dataSource, cache, authorizationStrategy,
|
||||
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()));
|
||||
strategy.setPermissionFactory(new DefaultPermissionFactory());
|
||||
}
|
||||
|
||||
@After
|
||||
public void emptyDatabase() {
|
||||
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 7;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 6;" + "DELETE FROM acl_object_identity WHERE ID = 5;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 4;" + "DELETE FROM acl_object_identity WHERE ID = 3;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 2;" + "DELETE FROM acl_object_identity WHERE ID = 1;"
|
||||
+ "DELETE FROM acl_class;" + "DELETE FROM acl_sid;";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("basiclookuptestcache");
|
||||
cache.removeAll();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(102));
|
||||
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalFromCacheOnly() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Objects were put in cache
|
||||
strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
// Let's empty the database to force acls retrieval from cache
|
||||
emptyDatabase();
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithCustomBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Set a batch size to allow multiple database queries in order to retrieve all acls
|
||||
this.strategy.setBatchSize(1);
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
private void checkEntries(ObjectIdentity topParentOid, ObjectIdentity middleParentOid, ObjectIdentity childOid,
|
||||
Map<ObjectIdentity, Acl> map) throws Exception {
|
||||
Assert.assertEquals(3, map.size());
|
||||
|
||||
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
|
||||
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
|
||||
MutableAcl child = (MutableAcl) map.get(childOid);
|
||||
|
||||
// Check the retrieved versions has IDs
|
||||
Assert.assertNotNull(topParent.getId());
|
||||
Assert.assertNotNull(middleParent.getId());
|
||||
Assert.assertNotNull(child.getId());
|
||||
|
||||
// Check their parents were correctly retrieved
|
||||
Assert.assertNull(topParent.getParentAcl());
|
||||
Assert.assertEquals(topParentOid, middleParent.getParentAcl().getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, child.getParentAcl().getObjectIdentity());
|
||||
|
||||
// Check their ACEs were correctly retrieved
|
||||
Assert.assertEquals(2, topParent.getEntries().size());
|
||||
Assert.assertEquals(1, middleParent.getEntries().size());
|
||||
Assert.assertEquals(1, child.getEntries().size());
|
||||
|
||||
// Check object identities were correctly retrieved
|
||||
Assert.assertEquals(topParentOid, topParent.getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, middleParent.getObjectIdentity());
|
||||
Assert.assertEquals(childOid, child.getObjectIdentity());
|
||||
|
||||
// Check each entry
|
||||
Assert.assertTrue(topParent.isEntriesInheriting());
|
||||
Assert.assertEquals(topParent.getId(), Long.valueOf(1));
|
||||
Assert.assertEquals(topParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getId(), Long.valueOf(1));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getPermission(), BasePermission.READ);
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue((topParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getId(), Long.valueOf(2));
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getPermission(), BasePermission.WRITE);
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess());
|
||||
Assert.assertFalse(topParent.getEntries().get(1).isGranting());
|
||||
|
||||
Assert.assertTrue(middleParent.isEntriesInheriting());
|
||||
Assert.assertEquals(middleParent.getId(), Long.valueOf(2));
|
||||
Assert.assertEquals(middleParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getId(), Long.valueOf(3));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(middleParent.getEntries().get(0).isGranting());
|
||||
|
||||
Assert.assertTrue(child.isEntriesInheriting());
|
||||
Assert.assertEquals(child.getId(), Long.valueOf(3));
|
||||
Assert.assertEquals(child.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(child.getEntries().get(0).getId(), Long.valueOf(4));
|
||||
Assert.assertEquals(child.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(child.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertFalse((child.getEntries().get(0)).isGranting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParentsAreRetrievedWhenChildIsLoaded() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,103,1,1,1);";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102));
|
||||
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(103));
|
||||
|
||||
// Retrieve the child
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(childOid), null);
|
||||
|
||||
// Check that the child and all its parents were retrieved
|
||||
Assert.assertNotNull(map.get(childOid));
|
||||
Assert.assertEquals(childOid, map.get(childOid).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(middleParentOid));
|
||||
Assert.assertEquals(middleParentOid, map.get(middleParentOid).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(topParentOid));
|
||||
Assert.assertEquals(topParentOid, map.get(topParentOid).getObjectIdentity());
|
||||
|
||||
// The second parent shouldn't have been retrieved
|
||||
Assert.assertNull(map.get(middleParent2Oid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test created from SEC-590.
|
||||
*/
|
||||
@Test
|
||||
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (5,2,105,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,106,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (7,2,107,5,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,1,1,0,0)";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
ObjectIdentity parent1Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(105));
|
||||
ObjectIdentity parent2Oid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(106));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(107));
|
||||
|
||||
// First lookup only child, thus populating the cache with grandParent, parent1 and child
|
||||
List<Permission> checkPermission = Arrays.asList(BasePermission.READ);
|
||||
List<Sid> sids = Arrays.asList(BEN_SID);
|
||||
List<ObjectIdentity> childOids = Arrays.asList(childOid);
|
||||
|
||||
strategy.setBatchSize(6);
|
||||
Map<ObjectIdentity, Acl> foundAcls = strategy.readAclsById(childOids, sids);
|
||||
|
||||
Acl foundChildAcl = foundAcls.get(childOid);
|
||||
Assert.assertNotNull(foundChildAcl);
|
||||
Assert.assertTrue(foundChildAcl.isGranted(checkPermission, sids, false));
|
||||
|
||||
// Search for object identities has to be done in the following order: last element have to be one which
|
||||
// is already in cache and the element before it must not be stored in cache
|
||||
List<ObjectIdentity> allOids = Arrays.asList(grandParentOid, parent1Oid, parent2Oid, childOid);
|
||||
try {
|
||||
foundAcls = strategy.readAclsById(allOids, sids);
|
||||
Assert.assertTrue(true);
|
||||
} catch (NotFoundException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
Acl foundParent2Acl = foundAcls.get(parent2Oid);
|
||||
Assert.assertNotNull(foundParent2Acl);
|
||||
Assert.assertTrue(foundParent2Acl.isGranted(checkPermission, sids, false));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void nullOwnerIsNotSupported() {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,null,1);";
|
||||
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
|
||||
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
}
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.BasePermission;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link BasicLookupStrategy}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class BasicLookupStrategyTests {
|
||||
|
||||
private static final Sid BEN_SID = new PrincipalSid("ben");
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static JdbcTemplate jdbcTemplate;
|
||||
private BasicLookupStrategy strategy;
|
||||
private static SingleConnectionDataSource dataSource;
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createDatabase() throws Exception {
|
||||
dataSource = new SingleConnectionDataSource("jdbc:hsqldb:mem:lookupstrategytest", "sa", "", true);
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
|
||||
Resource resource = new ClassPathResource("createAclSchema.sql");
|
||||
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() throws Exception {
|
||||
dataSource.destroy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void populateDatabase() {
|
||||
String query = "INSERT INTO acl_sid(ID,PRINCIPAL,SID) VALUES (1,1,'ben');"
|
||||
+ "INSERT INTO acl_class(ID,CLASS) VALUES (2,'" + TARGET_CLASS + "');"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (1,2,100,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (2,2,101,1,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (3,2,102,2,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (1,1,0,1,1,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (2,1,1,1,2,0,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (3,2,0,1,8,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (4,3,0,1,8,0,0,0);";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeBeans() {
|
||||
EhCacheBasedAclCache cache = new EhCacheBasedAclCache(getCache());
|
||||
AclAuthorizationStrategy authorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"), new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"),
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR") });
|
||||
strategy = new BasicLookupStrategy(dataSource, cache, authorizationStrategy, new ConsoleAuditLogger());
|
||||
}
|
||||
|
||||
@After
|
||||
public void emptyDatabase() {
|
||||
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 7;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 6;" + "DELETE FROM acl_object_identity WHERE ID = 5;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 4;" + "DELETE FROM acl_object_identity WHERE ID = 3;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 2;" + "DELETE FROM acl_object_identity WHERE ID = 1;"
|
||||
+ "DELETE FROM acl_class;" + "DELETE FROM acl_sid;";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("basiclookuptestcache");
|
||||
cache.removeAll();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(102));
|
||||
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalFromCacheOnly() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Objects were put in cache
|
||||
strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
// Let's empty the database to force acls retrieval from cache
|
||||
emptyDatabase();
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithCustomBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Set a batch size to allow multiple database queries in order to retrieve all acls
|
||||
((BasicLookupStrategy) this.strategy).setBatchSize(1);
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
private void checkEntries(ObjectIdentity topParentOid, ObjectIdentity middleParentOid, ObjectIdentity childOid,
|
||||
Map<ObjectIdentity, Acl> map) throws Exception {
|
||||
Assert.assertEquals(3, map.size());
|
||||
|
||||
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
|
||||
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
|
||||
MutableAcl child = (MutableAcl) map.get(childOid);
|
||||
|
||||
// Check the retrieved versions has IDs
|
||||
Assert.assertNotNull(topParent.getId());
|
||||
Assert.assertNotNull(middleParent.getId());
|
||||
Assert.assertNotNull(child.getId());
|
||||
|
||||
// Check their parents were correctly retrieved
|
||||
Assert.assertNull(topParent.getParentAcl());
|
||||
Assert.assertEquals(topParentOid, middleParent.getParentAcl().getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, child.getParentAcl().getObjectIdentity());
|
||||
|
||||
// Check their ACEs were correctly retrieved
|
||||
Assert.assertEquals(2, topParent.getEntries().size());
|
||||
Assert.assertEquals(1, middleParent.getEntries().size());
|
||||
Assert.assertEquals(1, child.getEntries().size());
|
||||
|
||||
// Check object identities were correctly retrieved
|
||||
Assert.assertEquals(topParentOid, topParent.getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, middleParent.getObjectIdentity());
|
||||
Assert.assertEquals(childOid, child.getObjectIdentity());
|
||||
|
||||
// Check each entry
|
||||
Assert.assertTrue(topParent.isEntriesInheriting());
|
||||
Assert.assertEquals(topParent.getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getPermission(), BasePermission.READ);
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getId(), new Long(2));
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getPermission(), BasePermission.WRITE);
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isGranting());
|
||||
|
||||
Assert.assertTrue(middleParent.isEntriesInheriting());
|
||||
Assert.assertEquals(middleParent.getId(), new Long(2));
|
||||
Assert.assertEquals(middleParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getId(), new Long(3));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertTrue(child.isEntriesInheriting());
|
||||
Assert.assertEquals(child.getId(), new Long(3));
|
||||
Assert.assertEquals(child.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(child.getEntries().get(0).getId(), new Long(4));
|
||||
Assert.assertEquals(child.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(child.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertFalse((child.getEntries().get(0)).isGranting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParentsAreRetrievedWhenChildIsLoaded() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,103,1,1,1);";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(103));
|
||||
|
||||
// Retrieve the child
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(childOid), null);
|
||||
|
||||
// Check that the child and all its parents were retrieved
|
||||
Assert.assertNotNull(map.get(childOid));
|
||||
Assert.assertEquals(childOid, ((Acl) map.get(childOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(middleParentOid));
|
||||
Assert.assertEquals(middleParentOid, ((Acl) map.get(middleParentOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(topParentOid));
|
||||
Assert.assertEquals(topParentOid, ((Acl) map.get(topParentOid)).getObjectIdentity());
|
||||
|
||||
// The second parent shouldn't have been retrieved
|
||||
Assert.assertNull(map.get(middleParent2Oid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test created from SEC-590.
|
||||
*/
|
||||
@Test
|
||||
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (5,2,105,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,106,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (7,2,107,5,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,1,1,0,0)";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
ObjectIdentity parent1Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(105));
|
||||
ObjectIdentity parent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(106));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(107));
|
||||
|
||||
// First lookup only child, thus populating the cache with grandParent, parent1 and child
|
||||
List<Permission> checkPermission = Arrays.asList(BasePermission.READ);
|
||||
List<Sid> sids = Arrays.asList(BEN_SID);
|
||||
List<ObjectIdentity> childOids = Arrays.asList(childOid);
|
||||
|
||||
strategy.setBatchSize(6);
|
||||
Map<ObjectIdentity, Acl> foundAcls = strategy.readAclsById(childOids, sids);
|
||||
|
||||
Acl foundChildAcl = (Acl) foundAcls.get(childOid);
|
||||
Assert.assertNotNull(foundChildAcl);
|
||||
Assert.assertTrue(foundChildAcl.isGranted(checkPermission, sids, false));
|
||||
|
||||
// Search for object identities has to be done in the following order: last element have to be one which
|
||||
// is already in cache and the element before it must not be stored in cache
|
||||
List<ObjectIdentity> allOids = Arrays.asList(grandParentOid, parent1Oid, parent2Oid, childOid);
|
||||
try {
|
||||
foundAcls = strategy.readAclsById(allOids, sids);
|
||||
Assert.assertTrue(true);
|
||||
} catch (NotFoundException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
Acl foundParent2Acl = (Acl) foundAcls.get(parent2Oid);
|
||||
Assert.assertNotNull(foundParent2Acl);
|
||||
Assert.assertTrue(foundParent2Acl.isGranted(checkPermission, sids, false));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void nullOwnerIsNotSupported() {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,null,1);";
|
||||
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
|
||||
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.sql.DataSource;
|
||||
* Seeds the database for {@link JdbcMutableAclServiceTests}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DatabaseSeeder {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+267
-267
@@ -1,267 +1,267 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.fest.assertions.Assertions.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.ehcache.Ehcache;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
@Mock
|
||||
private Ehcache cache;
|
||||
@Captor
|
||||
private ArgumentCaptor<Element> element;
|
||||
|
||||
private EhCacheBasedAclCache myCache;
|
||||
|
||||
private MutableAcl acl;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new EhCacheBasedAclCache(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodsRejectNullParameters() throws Exception {
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.evictFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.evictFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.getFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.getFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
MutableAcl acl = null;
|
||||
myCache.putInCache(acl);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
// SEC-527
|
||||
@Test
|
||||
public void testDiskSerializationOfMutableAclObjectInstance() throws Exception {
|
||||
// Serialization test
|
||||
File file = File.createTempFile("SEC_TEST", ".object");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(acl);
|
||||
oos.close();
|
||||
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
MutableAcl retrieved = (MutableAcl) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
assertEquals(acl, retrieved);
|
||||
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved);
|
||||
assertEquals(null, retrieved1);
|
||||
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue("permissionGrantingStrategy", retrieved);
|
||||
assertEquals(null, retrieved2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearCache() throws Exception {
|
||||
myCache.clearCache();
|
||||
|
||||
verify(cache).removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putInCache() throws Exception {
|
||||
myCache.putInCache(acl);
|
||||
|
||||
verify(cache, times(2)).put(element.capture());
|
||||
assertThat(element.getValue().getKey()).isEqualTo(acl.getId());
|
||||
assertThat(element.getValue().getObjectValue()).isEqualTo(acl);
|
||||
assertThat(element.getAllValues().get(0).getKey()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(element.getAllValues().get(0).getObjectValue()).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putInCacheAclWithParent() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
verify(cache, times(4)).put(element.capture());
|
||||
|
||||
List<Element> allValues = element.getAllValues();
|
||||
|
||||
assertThat(allValues.get(0).getKey()).isEqualTo(parentAcl.getObjectIdentity());
|
||||
assertThat(allValues.get(0).getObjectValue()).isEqualTo(parentAcl);
|
||||
|
||||
assertThat(allValues.get(1).getKey()).isEqualTo(parentAcl.getId());
|
||||
assertThat(allValues.get(1).getObjectValue()).isEqualTo(parentAcl);
|
||||
|
||||
|
||||
assertThat(allValues.get(2).getKey()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(allValues.get(2).getObjectValue()).isEqualTo(acl);
|
||||
|
||||
assertThat(allValues.get(3).getKey()).isEqualTo(acl.getId());
|
||||
assertThat(allValues.get(3).getObjectValue()).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheSerializable() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
assertThat(myCache.getFromCache(acl.getId())).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheSerializablePopulatesTransient() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
ReflectionTestUtils.setField(acl, "permissionGrantingStrategy", null);
|
||||
ReflectionTestUtils.setField(acl, "aclAuthorizationStrategy", null);
|
||||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getId());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheObjectIdentity() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
assertThat(myCache.getFromCache(acl.getId())).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheObjectIdentityPopulatesTransient() throws Exception {
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
ReflectionTestUtils.setField(acl, "permissionGrantingStrategy", null);
|
||||
ReflectionTestUtils.setField(acl, "aclAuthorizationStrategy", null);
|
||||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getObjectIdentity());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictCacheSerializable() throws Exception {
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.evictFromCache(acl.getObjectIdentity());
|
||||
|
||||
verify(cache).remove(acl.getId());
|
||||
verify(cache).remove(acl.getObjectIdentity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictCacheObjectIdentity() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.evictFromCache(acl.getId());
|
||||
|
||||
verify(cache).remove(acl.getId());
|
||||
verify(cache).remove(acl.getObjectIdentity());
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.addCache(new Cache("ehcachebasedacltests", 0, true, false, 600, 300));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("ehcachebasedacltests");
|
||||
cache.removeAll();
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new EhCacheBasedAclCache(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodsRejectNullParameters() throws Exception {
|
||||
Ehcache cache = new MockEhcache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.evictFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.evictFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.getFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.getFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
MutableAcl acl = null;
|
||||
myCache.putInCache(acl);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
// SEC-527
|
||||
@Test
|
||||
public void testDiskSerializationOfMutableAclObjectInstance() throws Exception {
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Serialization test
|
||||
File file = File.createTempFile("SEC_TEST", ".object");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(acl);
|
||||
oos.close();
|
||||
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
MutableAcl retrieved = (MutableAcl) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
assertEquals(acl, retrieved);
|
||||
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved);
|
||||
assertEquals(null, retrieved1);
|
||||
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue("auditLogger", retrieved);
|
||||
assertEquals(null, retrieved2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(new Long(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(new Long(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, new Long(102)));
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
myCache.evictFromCache(new Long(1));
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(new Long(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(cache.getSize(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, new Long(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertTrue(cache.isElementOnDisk(Long.valueOf(1)));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(Long.valueOf(1)));
|
||||
cache.flush();
|
||||
// Wait for the spool to be written to disk (it's asynchronous)
|
||||
Map spool = (Map) FieldUtils.getFieldValue(cache, "diskStore.spool");
|
||||
|
||||
while(spool.size() > 0) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(new Long(1));
|
||||
// For the checks on transient fields, we need to be sure that the object is being loaded from the cache,
|
||||
// not from the ehcache spool or elsewhere...
|
||||
assertFalse(acl == aclFromCache);
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "auditLogger"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(new Long(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockEhcache extends Cache {
|
||||
public MockEhcache() {
|
||||
super("cache", 0, true, true, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.mockito.Matchers.anyListOf;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class JdbcAclServiceTests {
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
|
||||
@Mock
|
||||
private LookupStrategy lookupStrategy;
|
||||
|
||||
private JdbcAclService aclService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
aclService = new JdbcAclService(dataSource, lookupStrategy);
|
||||
}
|
||||
|
||||
// SEC-1898
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void readAclByIdMissingAcl() {
|
||||
Map<ObjectIdentity, Acl> result = new HashMap<ObjectIdentity, Acl>();
|
||||
when(lookupStrategy.readAclsById(anyListOf(ObjectIdentity.class), anyListOf(Sid.class))).thenReturn(result);
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(Object.class, 1);
|
||||
List<Sid> sids = Arrays.<Sid> asList(new PrincipalSid("user"));
|
||||
|
||||
aclService.readAclById(objectIdentity, sids);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -57,6 +57,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Andrei Stefan
|
||||
* @version $Id:JdbcMutableAclServiceTests.java 1754 2006-11-17 02:01:21Z benalex $
|
||||
*/
|
||||
@ContextConfiguration(locations={"/jdbcMutableAclServiceTests-context.xml"})
|
||||
public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
@@ -105,7 +106,6 @@ public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4Sprin
|
||||
jdbcTemplate.execute("drop table acl_object_identity");
|
||||
jdbcTemplate.execute("drop table acl_class");
|
||||
jdbcTemplate.execute("drop table acl_sid");
|
||||
aclCache.clearCache();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
import org.springframework.security.acls.domain.*;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests {@link org.springframework.security.acls.domain.SpringCacheBasedAclCache}
|
||||
*
|
||||
* @author Marten Deinum
|
||||
*/
|
||||
public class SpringCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new ConcurrentMapCacheManager();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.getCache("springcasebasedacltests");
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Cache getCache() {
|
||||
Cache cache = cacheManager.getCache("springcasebasedacltests");
|
||||
cache.clear();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new SpringCacheBasedAclCache(null, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Cache cache = getCache();
|
||||
Map realCache = (Map) cache.getNativeCache();
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
assertEquals(0, realCache.size());
|
||||
myCache.putInCache(acl);
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, Long.valueOf(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(Long.valueOf(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
|
||||
assertEquals(realCache.size(), 4);
|
||||
|
||||
myCache.evictFromCache(Long.valueOf(1));
|
||||
assertEquals(realCache.size(), 2);
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(realCache.size(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Cache cache = getCache();
|
||||
Map realCache = (Map) cache.getNativeCache();
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, auditLogger);
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2), aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, realCache.size());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(realCache.size(), 4);
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(1));
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "permissionGrantingStrategy"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
}
|
||||
+66
-67
@@ -1,67 +1,66 @@
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link SidRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SidRetrievalStrategyTests {
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void correctSidsAreRetrieved() throws Exception {
|
||||
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
|
||||
List<Sid> sids = retrStrategy.getSids(authentication);
|
||||
|
||||
assertNotNull(sids);
|
||||
assertEquals(4, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
|
||||
for (int i = 1; i < sids.size(); i++) {
|
||||
assertTrue(sids.get(i) instanceof GrantedAuthoritySid);
|
||||
}
|
||||
|
||||
assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
|
||||
assertEquals("A", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
assertEquals("B", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
|
||||
assertEquals("C", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roleHierarchyIsUsedWhenSet() throws Exception {
|
||||
RoleHierarchy rh = mock(RoleHierarchy.class);
|
||||
List rhAuthorities = AuthorityUtils.createAuthorityList("D");
|
||||
when(rh.getReachableGrantedAuthorities(anyCollection())).thenReturn(rhAuthorities);
|
||||
SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
|
||||
|
||||
List<Sid> sids = strat.getSids(authentication);
|
||||
assertEquals(2, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
assertEquals("D", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link SidRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SidRetrievalStrategyTests {
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void correctSidsAreRetrieved() throws Exception {
|
||||
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
|
||||
List<Sid> sids = retrStrategy.getSids(authentication);
|
||||
|
||||
assertNotNull(sids);
|
||||
assertEquals(4, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
|
||||
for (int i = 1; i < sids.size(); i++) {
|
||||
assertTrue(sids.get(i) instanceof GrantedAuthoritySid);
|
||||
}
|
||||
|
||||
assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
|
||||
assertEquals("A", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
assertEquals("B", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
|
||||
assertEquals("C", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roleHierarchyIsUsedWhenSet() throws Exception {
|
||||
RoleHierarchy rh = mock(RoleHierarchy.class);
|
||||
List<GrantedAuthority> rhAuthorities = AuthorityUtils.createAuthorityList("D");
|
||||
when(rh.getReachableGrantedAuthorities(anyList())).thenReturn(rhAuthorities);
|
||||
SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
|
||||
|
||||
List<Sid> sids = strat.getSids(authentication);
|
||||
assertEquals(2, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
assertEquals("D", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,189 +1,190 @@
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
|
||||
public class SidTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testPrincipalSidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new PrincipalSid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("johndoe");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one Authentication-argument constructor
|
||||
try {
|
||||
Authentication authentication = null;
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken(null, "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new GrantedAuthoritySid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("ROLE_TEST");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one GrantedAuthority-argument constructor
|
||||
try {
|
||||
GrantedAuthority ga = null;
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority(null);
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPrincipalSidEquals() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertFalse(principalSid.equals(null));
|
||||
Assert.assertFalse(principalSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(principalSid.equals(principalSid));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(authentication)));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("johndoe", null))));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("scott", null))));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid("johndoe")));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid("scott")));
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidEquals() throws Exception {
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertFalse(gaSid.equals(null));
|
||||
Assert.assertFalse(gaSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(gaSid.equals(gaSid));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(ga)));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST"))));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_NOT_EQUAL"))));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid("ROLE_TEST")));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid("ROLE_NOT_EQUAL")));
|
||||
}
|
||||
|
||||
public void testPrincipalSidHashCode() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertTrue(principalSid.hashCode() == "johndoe".hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() == new PrincipalSid("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid("scott").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidHashCode() throws Exception {
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue(gaSid.hashCode() == "ROLE_TEST".hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() == new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST_2")).hashCode());
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
PrincipalSid principalSid = new PrincipalSid(authentication);
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
|
||||
GrantedAuthoritySid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue("johndoe".equals(principalSid.getPrincipal()));
|
||||
Assert.assertFalse("scott".equals(principalSid.getPrincipal()));
|
||||
|
||||
Assert.assertTrue("ROLE_TEST".equals(gaSid.getGrantedAuthority()));
|
||||
Assert.assertFalse("ROLE_TEST2".equals(gaSid.getGrantedAuthority()));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
|
||||
public class SidTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testPrincipalSidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new PrincipalSid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("johndoe");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one Authentication-argument constructor
|
||||
try {
|
||||
Authentication authentication = null;
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken(null, "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new GrantedAuthoritySid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("ROLE_TEST");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one GrantedAuthority-argument constructor
|
||||
try {
|
||||
GrantedAuthority ga = null;
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl(null);
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPrincipalSidEquals() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertFalse(principalSid.equals(null));
|
||||
Assert.assertFalse(principalSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(principalSid.equals(principalSid));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(authentication)));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("johndoe", null))));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("scott", null))));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid("johndoe")));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid("scott")));
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidEquals() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertFalse(gaSid.equals(null));
|
||||
Assert.assertFalse(gaSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(gaSid.equals(gaSid));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(ga)));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST"))));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_NOT_EQUAL"))));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid("ROLE_TEST")));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid("ROLE_NOT_EQUAL")));
|
||||
}
|
||||
|
||||
public void testPrincipalSidHashCode() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertTrue(principalSid.hashCode() == new String("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() == new PrincipalSid("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid("scott").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidHashCode() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue(gaSid.hashCode() == new String("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() == new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST_2")).hashCode());
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
PrincipalSid principalSid = new PrincipalSid(authentication);
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
GrantedAuthoritySid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue("johndoe".equals(principalSid.getPrincipal()));
|
||||
Assert.assertFalse("scott".equals(principalSid.getPrincipal()));
|
||||
|
||||
Assert.assertTrue("ROLE_TEST".equals(gaSid.getGrantedAuthority()));
|
||||
Assert.assertFalse("ROLE_TEST2".equals(gaSid.getGrantedAuthority()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing business beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
-->
|
||||
|
||||
<beans>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName" value="aclCache"/>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
|
||||
<!-- Uncomment to use PostgreSQL
|
||||
<property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))"/>
|
||||
<property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))"/>
|
||||
-->
|
||||
</bean>
|
||||
|
||||
<!-- PostgreSQL DataSource configuration
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.postgresql.Driver"/>
|
||||
<property name="url" value="jdbc:postgresql://localhost:5432/acltest"/>
|
||||
<property name="username" value="acltest"/>
|
||||
<property name="password" value="acltest"/>
|
||||
</bean>
|
||||
-->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:acltest"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing business beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
- $Id:applicationContext-test.xml 1754 2006-11-17 02:01:21Z benalex $
|
||||
-->
|
||||
|
||||
<beans>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName" value="aclCache"/>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
|
||||
<!-- Uncomment to use PostgreSQL
|
||||
<property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))"/>
|
||||
<property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))"/>
|
||||
-->
|
||||
</bean>
|
||||
|
||||
<!-- PostgreSQL DataSource configuration
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.postgresql.Driver"/>
|
||||
<property name="url" value="jdbc:postgresql://localhost:5432/acltest"/>
|
||||
<property name="username" value="acltest"/>
|
||||
<property name="password" value="acltest"/>
|
||||
</bean>
|
||||
-->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:acltest"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.security" level="${sec.log.level}:-WARN"/>
|
||||
|
||||
<root level="${root.level}:-WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
+14
-17
@@ -1,24 +1,21 @@
|
||||
Implementation-Title: org.springframework.security.acls
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.acls
|
||||
Bundle-Name: Spring Security Acls
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aopalliance.*;version="${aopAllianceRange}",
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.cache.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.access.*;version="${secRange}",
|
||||
org.springframework.security.util.*;version="${secRange}",
|
||||
org.springframework.context.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.dao.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.jdbc.core.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.transaction.support.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.util.*;version="${springRange}";resolution:=optional,
|
||||
net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
|
||||
javax.sql.*;version="0";resolution:=optional
|
||||
Import-Template:
|
||||
org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
|
||||
org.springframework.security.core.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.security.access.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.security.util.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.context.*;version="[3.0.0, 3.1.0)";resolution:=optional,
|
||||
org.springframework.dao.*;version="[3.0.0, 3.1.0)";resolution:=optional,
|
||||
org.springframework.jdbc.core.*;version="[3.0.0, 3.1.0)";resolution:=optional,
|
||||
org.springframework.transaction.support.*;version="[3.0.0, 3.1.0)";resolution:=optional,
|
||||
org.springframework.util.*;version="[3.0.0, 3.1.0)";resolution:=optional,
|
||||
net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional,
|
||||
javax.sql.*;version="0";resolution:=optional
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
springCoreDependency,
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion"
|
||||
|
||||
testCompile 'aopalliance:aopalliance:1.0',
|
||||
"org.springframework:spring-aop:$springVersion"
|
||||
}
|
||||
+63
-137
@@ -1,139 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>3.2.6.RELEASE</version>
|
||||
<name>spring-security-aspects</name>
|
||||
<description>spring-security-aspects</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
<organization>
|
||||
<name>spring.io</name>
|
||||
<url>http://spring.io/</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>rwinch</id>
|
||||
<name>Rob Winch</name>
|
||||
<email>rwinch@gopivotal.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/spring-projects/spring-security</connection>
|
||||
<developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>
|
||||
<url>https://github.com/spring-projects/spring-security</url>
|
||||
</scm>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>3.2.6.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.6.10</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
<artifactId>aopalliance</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>0.9.29</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easytesting</groupId>
|
||||
<artifactId>fest-assert</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<version>3.0.0.CI-SNAPSHOT</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<name>Spring Security - Aspects</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>3.0.0.CI-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<dependencies>
|
||||
<!--
|
||||
NB: You must use Maven 2.0.9 or above or these
|
||||
are ignored (see MNG-2972)
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.6.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>1.6.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user