1
0
mirror of synced 2026-07-13 22:55:10 +00:00

Compare commits

..

33 Commits

Author SHA1 Message Date
Spring Operator 4e61de0ef9 URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# Fixed URLs

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* http://www.apache.org/licenses/ with 1 occurrences migrated to:
  https://www.apache.org/licenses/ ([https](https://www.apache.org/licenses/) result 200).
* http://www.apache.org/licenses/LICENSE-2.0 with 1777 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200).
* http://www.apache.org/licenses/LICENSE-2.0.html with 1 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0.html ([https](https://www.apache.org/licenses/LICENSE-2.0.html) result 200).
* http://www.apache.org/licenses/LICENSE-2.0.txt with 1 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0.txt ([https](https://www.apache.org/licenses/LICENSE-2.0.txt) result 200).
2019-03-14 20:21:48 -05:00
Rob Winch c8e4ffb5b9 Polish URLs
We have performed some polish on your URLs. We do not follow redirects to avoid expanding intentionally shorter URLs (i.e. URL shortened URLs)

# Fixed URLs

## Fixed But Review Recommended
These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request, so we migrated them. Your review is recommended.

| HTTP URL | Result URL | HTTPS Result | HTTP Result | Count |
| --- | --- | --- | --- | --- |
| http://repo.terracotta.org/maven2/ | https://repo.terracotta.org/maven2/ | HttpResponse(httpStatus = 403 FORBIDDEN) | HttpResponse(httpStatus = 403 FORBIDDEN) | 1 |
| http://repository.springsource.com/maven/bundles/external | https://repository.springsource.com/maven/bundles/external | HttpResponse(httpStatus = 404 NOT_FOUND) | HttpResponse(httpStatus = 404 NOT_FOUND) | 1 |
| http://repository.springsource.com/maven/bundles/release | https://repository.springsource.com/maven/bundles/release | HttpResponse(httpStatus = 404 NOT_FOUND) | HttpResponse(httpStatus = 404 NOT_FOUND) | 1 |
## Fixed Success
These URLs were fixed successfully.

| HTTP URL | Result URL | HTTPS Result | HTTP Result | Count |
| --- | --- | --- | --- | --- |
| http://docs.spring.io/spring-ldap/docs/1.3.x/apidocs/ | https://docs.spring.io/spring-ldap/docs/1.3.x/apidocs/ | HttpResponse(httpStatus = 200 OK) | null | 2 |
| http://docs.spring.io/spring/docs/3.2.x/javadoc-api | https://docs.spring.io/spring/docs/3.2.x/javadoc-api | HttpResponse(httpStatus = 301 MOVED_PERMANENTLY redirectUrl = http://docs.spring.io/spring/docs/3.2.x/javadoc-api/) | null | 1 |
| http://docs.spring.io/spring/docs/3.2.x/javadoc-api/ | https://docs.spring.io/spring/docs/3.2.x/javadoc-api/ | HttpResponse(httpStatus = 200 OK) | null | 1 |
| http://download.oracle.com/javase/6/docs/api/ | https://download.oracle.com/javase/6/docs/api/ | HttpResponse(httpStatus = 302 FOUND redirectUrl = https://docs.oracle.com/javase/6/docs/api/) | null | 2 |
| http://spring.io/ | https://spring.io/ | HttpResponse(httpStatus = 200 OK) | null | 54 |
| http://spring.io/spring-security | https://spring.io/spring-security | HttpResponse(httpStatus = 302 FOUND redirectUrl = https://projects.spring.io/spring-security) | null | 54 |
| http://www.apache.org/licenses/LICENSE-2.0.txt | https://www.apache.org/licenses/LICENSE-2.0.txt | HttpResponse(httpStatus = 200 OK) | null | 54 |
| http://forums.gradle.org/gradle/topics/after_upgrade_gradle_to_2_0_version_the_maven_pom_not_support_build_property | https://discuss.gradle.org/gradle/topics/after_upgrade_gradle_to_2_0_version_the_maven_pom_not_support_build_property | HttpResponse(httpStatus = 404 NOT_FOUND) | HttpResponse(httpStatus = 301 MOVED_PERMANENTLY redirectUrl = https://discuss.gradle.org/gradle/topics/after_upgrade_gradle_to_2_0_version_the_maven_pom_not_support_build_property) | 1 |
| http://forums.gradle.org/gradle/topics/eclipse_wtp_deploys_testcode_to_server_example_provided | https://discuss.gradle.org/gradle/topics/eclipse_wtp_deploys_testcode_to_server_example_provided | HttpResponse(httpStatus = 404 NOT_FOUND) | HttpResponse(httpStatus = 301 MOVED_PERMANENTLY redirectUrl = https://discuss.gradle.org/gradle/topics/eclipse_wtp_deploys_testcode_to_server_example_provided) | 1 |

# Ignored
These URLs were intentionally ignored so we didn't migrate them.

| HTTP URL |
| --- |
| http://maven.apache.org/POM/4.0.0 |
| http://maven.apache.org/xsd/maven-4.0.0.xsd |
| http://www.w3.org/2001/XMLSchema-instance |
2019-03-01 17:35:15 -06:00
Spring Buildmaster 2fdef0455b Next development version 2018-01-25 18:32:07 +00:00
Spring Buildmaster 45421d63ac Release version 4.1.5.RELEASE 2018-01-25 18:32:00 +00:00
Rob Winch 976ce05373 DelegatingApplicationListener uses CopyOnWriteArrayList
Fixes: gh-4979
2018-01-25 11:28:01 -06:00
Rob Winch a898415c65 Update .gitignore
- ignore classes/
- ignore s101plugin.state
2018-01-25 11:28:01 -06:00
Joris Portegies Zwart 01910419f0 JavaDoc for Pbkdf2PasswordEncoder refer to constants
Fix Javadoc so that it uses the actual values for default hash width and number of iterations

Fixes gh-4978
2018-01-25 11:27:10 -06:00
Kyle Anderson e7a15e85a1 Fix Typo in Reference Docs
Fixes: gh-4976
2018-01-25 11:26:51 -06:00
Rob Winch 65da28e4bf Add StrictHttpFirewall 2018-01-25 11:26:51 -06:00
Rob Winch 04d14fb6fe Lookup HandlerMappingIntrospector from Bean 2018-01-25 11:26:51 -06:00
Rob Winch 17238707b7 Update to Spring 4.3.14
Fixes: gh-4977
2018-01-25 11:26:40 -06:00
Craig Andrews bf075a2cae Configure permissionEvaluator and roleHierarchy by default
Implementations of AbstractSecurityExpressionHandler (such as the very commonly used DefaultWebSecurityExpressionHandler) get PermissionEvaluator and RoleHierarchy from the application context (if the application context is provided, and exactly one of such a bean exists in it). This approach matches that used in GlobalMethodSecurityConfiguration, making everything in Spring Security work the same way (including WebSecurity).

Issue gh-4077
2017-10-30 00:57:37 -05:00
Spring Buildmaster d0ede98db5 Next development version 2016-12-21 16:50:22 +00:00
Spring Buildmaster 57ed7ddf3c Release version 4.1.4.RELEASE 2016-12-21 16:50:16 +00:00
Rob Winch 5574fd2029 Update to Spring 4.3.5.RELEASE
Fixes gh-4168
2016-12-21 10:14:33 -06:00
Rob Winch ed2ae21074 Block URL Encoded "/" in DefaultHttpFirewall
Fixes gh-4170
2016-12-21 09:32:35 -06:00
Rob Winch d25c4a23ba Remove only master from .travis.yml 2016-08-30 09:14:04 -05:00
Spring Buildmaster 548a542417 Next development version 2016-08-23 01:05:57 +00:00
Spring Buildmaster 325b814d49 Release version 4.1.3.RELEASE 2016-08-23 01:05:48 +00:00
Rob Winch 8f1c977c0d Update Dependency Versions (#4035) 2016-08-19 16:09:10 -05:00
Joe Grandja e0d9487e6b Remove unused MvcReqestMatcher.getMvcPattern (#4034) 2016-08-19 14:38:19 -05:00
Rob Winch 9dc3242db3 Remove MvcRequestMatcher.afterPropertiesSet()
The validation does not work due to restrictions within the servlet
container. Specifically we cannot access the servlets that are registered.

This commit reverts the validation logic for MvcRequestMatcher to determine
if servletPath is required.

Fixes gh-4027
2016-08-19 11:12:38 -05:00
Spring Buildmaster a070046f26 Next development version 2016-08-11 19:14:39 +00:00
Spring Buildmaster e412fb7ac0 Release version 4.1.2.RELEASE 2016-08-11 19:14:32 +00:00
Rob Winch 28278eab89 Fix defaultMethodExpressionHandler autowiring
Previously if a Bean for GlobalMethodSecurityConfiguration's
defaultMethodExpressionHandler was found on a Configuration that also
@Autowired a Bean that enabled method security, the Bean that was
@Autowired would not have security enabled.

This fixes the issue by delaying the lookup of Beans populated on
GlobalMethodSecurityConfiguration's defaultMethodExpressionHandler.

Fixes gh-4020
2016-08-10 23:48:49 -05:00
Rob Winch a93fb1e0e7 Fix csrf() when used then not used
Previously if csrf() was used and subsequently not used, the
TestCsrfTokenRepository was still used. This makes it difficult to test
the actual CsrfTokenRepository implementation.

Now the TestCsrfTokenRepository is only used if explicitly enabled.

Fixes gh-4016
2016-08-09 17:28:33 -04:00
Joe Grandja dabcc5416a MvcRequestMatcher servletPath Polish / XML Config
Fixes gh-4014
2016-08-09 15:47:41 -05:00
Rob Winch 8a6d0cd16d MvcRequestMatcher servletPath / JavaConfig
Issue: gh-3987
2016-08-09 15:47:01 -05:00
Rob Winch edb7ef567a Logout is 204 for XMLHttpRequest
Fixes gh-3997
2016-08-02 14:14:44 -07:00
Rob Winch d002681bec Add ObjectPostProcessor support for SmartInitializingSingleton 2016-07-21 10:46:55 -05:00
Rob Winch 6649d46896 DummyRequest supports methods for MvcRequestMatcher
To support MvcRequestMatcher DummyRequest needs to support
getCharacterEncoding() and getAttribute(String)
2016-07-14 16:02:08 -04:00
Rob Winch 1d97ee8dd6 Add HttpSecurity.mvcMatcher
Fixes gh-3970
2016-07-14 11:46:29 -04:00
Rob Winch 7d1344fca8 Fix NPE requestMatchers().mvcMatchers
Fixes gh-3969
2016-07-14 11:45:45 -04:00
3155 changed files with 84232 additions and 229307 deletions
+6 -11
View File
@@ -1,22 +1,17 @@
# EditorConfig for Spring Security
# see https://github.com/spring-projects/spring-security/blob/master/CONTRIBUTING.md#mind-the-whitespace
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
charset = latin1
[*.{java,xml}]
# 4 tabs indentation
indent_style = tab
indent_size = 4
charset = utf-8
continuation_indent_size = 8
tab_width = 4
ij_smart_tabs = false
ij_java_align_multiline_parameters = false
[*.gradle]
indent_style = tab
trim_trailing_whitespace = true
-10
View File
@@ -1,10 +0,0 @@
### Complete and Minimal Sample
It would be very helpful if you could provide a complete and minimal sample that reproduces the issue and share it via a GitHub repository. This will allow us to efficiently troubleshoot and help resolve the issue. The sample should contain the minimum amount of code to reproduce the issue along with detailed steps on how to reproduce. Please see the following references for what a complete and minimal sample should consist of.
- https://stackoverflow.com/help/mcve
### Post questions on StackOverflow not GitHub
Thanks for getting in touch, but it feels like this is a question that would be better suited to [Stack Overflow](https://stackoverflow.com/). As mentioned in [the guidelines for contributing](https://github.com/spring-projects/spring-security/blob/master/CONTRIBUTING.md#using-github-issues), we prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
-4
View File
@@ -1,7 +1,3 @@
<!--
For Security Vulnerabilities, please use https://pivotal.io/security#reporting
-->
### Summary
<!--
+1 -7
View File
@@ -1,9 +1,3 @@
<!--
For Security Vulnerabilities, please use https://pivotal.io/security#reporting
-->
<!--
Before creating new features, we recommend creating an issue to discuss the feature. This ensures that everyone is on the same page before extensive work is done.
Thanks for contributing to Spring Security. Please provide a brief description of your pull-request and reference any related issue numbers (prefix references with gh-).
Thanks for contributing to Spring Security. Please provide a brief description of your pull-request and reference any related issue numbers (prefix references with #).
-->
+2 -6
View File
@@ -1,4 +1,3 @@
classes/
target/
*/src/*/java/META-INF
*/src/META-INF/
@@ -8,7 +7,7 @@ target/
.project
.DS_Store
.settings/
.idea/*
.idea/
out/
bin/
intellij/
@@ -22,8 +21,5 @@ build/
atlassian-ide-plugin.xml
!etc/eclipse/.checkstyle
.checkstyle
classes/
s101plugin.state
.attach_pid*
!.idea/checkstyle-idea.xml
!.idea/externalDependencies.xml
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="PROJECT_RELATIVE:$PROJECT_DIR$/etc/checkstyle/checkstyle.xml:spring-security" />
<entry key="checkstyle-version" value="8.14" />
<entry key="copy-libs" value="false" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="location-2" value="PROJECT_RELATIVE:$PROJECT_DIR$/etc/checkstyle/checkstyle.xml:spring-security" />
<entry key="property-2.config_loc" value="$PROJECT_DIR$/etc/checkstyle" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnlyWithTests" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
</project>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalDependencies">
<plugin id="CheckStyle-IDEA" />
<plugin id="org.jetbrains.plugins.gradle" />
</component>
</project>
+16
View File
@@ -0,0 +1,16 @@
language: java
jdk:
- oraclejdk8
os:
- linux
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
script: ./gradlew build
+2 -2
View File
@@ -40,5 +40,5 @@ appropriate to the circumstances. Maintainers are obligated to maintain confiden
with regard to the reporter of an incident.
This Code of Conduct is adapted from the
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
+9 -36
View File
@@ -8,11 +8,11 @@ By participating, you are expected to uphold this code. Please report unaccepta
# 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/spring-projects/spring-framework/wiki/Contributor-guidelines). However, there are some subtle differences between the two documents, so please be sure to read this document thoroughly.
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.
# Importing into IDE
The following provides information on setting up a development environment that can run the sample in [Spring Tool Suite 3.6.0+](https://www.springsource.org/sts). Other IDE's should work using Gradle's IDE support, but have not been tested.
The following provides information on setting up a development environment that can run the sample in [Spring Tool Suite 3.6.0+](http://www.springsource.org/sts). Other IDE's should work using Gradle's IDE support, but have not been tested.
* IDE Setup
* Install Spring Tool Suite 3.6.0+
@@ -22,31 +22,14 @@ The following provides information on setting up a development environment that
* Importing the project into Spring Tool Suite
* File->Import...->Gradle Project
As of new versions of Spring Tool Suite, you might need to install Groovy Eclipse pointing directly to the updates plugin location. To install Groovy Eclipse on Spring Tool Suite based on Eclipse Oxigen you must do the following steps:
Help->Install New Software...->Add the following URL into _Work with_ field:
https://dist.springsource.org/snapshot/GRECLIPSE/e4.7/
# 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 GitHub issues; create an issue if necessary
Is there already an issue that addresses your concern? Do a bit of searching in our [GitHub issues ](https://github.com/spring-projects/spring-security/issues) 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.
# Using GitHub Issues
We use GitHub issues to track bugs and enhancements.
If you have a general usage question please ask on [Stack Overflow](https://stackoverflow.com).
The Spring Security team and the broader community monitor the [`spring-security`](https://stackoverflow.com/tags/spring-security) tag.
If you are reporting a bug, please help to speed up problem diagnosis by providing as much
information as possible. Ideally, that would include a small
[sample project](https://github.com/spring-projects/spring-boot-issues) that reproduces the
problem.
# 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 Gitter](https://gitter.im/spring-projects/spring-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.
If you're considering anything more than correcting a typo or fixing a minor bug , please discuss it on the [Spring Security Gitter](https://gitter.im/spring-projects/spring-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
@@ -59,7 +42,7 @@ Create your topic branch to be submitted as a pull request from master. The Spri
# Use short branch names
Branches used when submitting pull requests should preferably be named according to GitHub issues, e.g. 'gh-1234' or 'gh-1234-fix-npe'. 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
#Keep commits focused
Remember each ticket should be focused on a single item of interest since the tickets are used to produce the changelog. Since each commit should be tied to a single GitHub issue, ensure that your commits are focused. For example, do not include an update to a transitive library in your commit unless the GitHub is to update the library. Reviewing your commits is essential before sending a pull request.
@@ -72,12 +55,12 @@ Please carefully follow the whitespace and formatting conventions already presen
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. UTF-8 encoding for Java sources
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](https://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](https://git-scm.com/book/cs/ch7-3.html)
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
@@ -121,23 +104,14 @@ e.g.
*/
</pre>
# Submit JUnit test cases for all behavior changes
#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.
# Update spring-security-x.y.rnc for schema changes
Update the [RELAX NG](https://relaxng.org/) schema `spring-security-x.y.rnc` instead of `spring-security-x.y.xsd` if you contribute changes to supported XML configuration. The XML schema file can be generated the following Gradle task:
<pre>
./gradlew spring-security-config:rncToXsd
</pre>
Changes to the XML schema will be overwritten by the Gradle build task.
# 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 from the [Git SCM Book](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).
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:
@@ -192,7 +166,6 @@ Fixes gh-123
2. Do not end the subject line with a period
3. In the body of the commit message, explain how things worked before this commit, what has changed, and how things work now
3. Include Fixes gh-<issue-number> at the end if this fixes a GitHub issue
5. Avoid markdown, including back-ticks identifying code
# Run all tests prior to submission
+14 -18
View File
@@ -1,17 +1,13 @@
image::https://badges.gitter.im/Join%20Chat.svg[Gitter,link=https://gitter.im/spring-projects/spring-security?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
[NOTE]
======
This branch of Spring Security has reached its https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions#supported-versions[End of Life], meaning that there are no further maintenance releases or security patches planned.
Please migrate to a supported branch as soon as possible.
======
image:https://travis-ci.org/spring-projects/spring-security.svg?branch=master["Build Status", link="https://travis-ci.org/spring-security/spring-security"]
= Spring Security
Spring Security provides security services for the https://docs.spring.io[Spring IO Platform]. Spring Security 5.0 requires Spring 5.0 as
a minimum and also requires Java 8.
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 https://spring.io/projects[Spring projects].
For a detailed list of features and access to the latest release, please visit http://spring.io/projects[Spring projects].
== Code of Conduct
This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct].
@@ -21,21 +17,21 @@ By participating, you are expected to uphold this code. Please report unaccepta
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 https://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 https://docs.spring.io/spring-security/site/docs/current/api/[Spring Security API 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
See https://docs.spring.io/spring-security/site/docs/5.2.x/reference/html5/#servlet-hello[Hello Spring Security] to get started with a "Hello, World" application.
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 https://gradle.org[Gradle]-based build system.
In the instructions below, https://vimeo.com/34436402[`./gradlew`] is invoked from the root of the source tree and serves as
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
https://help.github.com/set-up-git-redirect[Git] and the https://www.oracle.com/technetwork/java/javase/downloads[JDK8 build].
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.8.0` folder extracted from the JDK download.
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]
@@ -59,11 +55,11 @@ 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 https://stackoverflow.com/questions/tagged/spring-security[Spring Security tags on Stack Overflow].
https://spring.io/services[Commercial support] is available too.
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
https://help.github.com/articles/creating-a-pull-request[Pull requests] are welcome; see the https://github.com/spring-projects/spring-security/blob/master/CONTRIBUTING.md[contributor guidelines] for details.
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
+19
View File
@@ -0,0 +1,19 @@
// 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:$ehcacheVersion"
testCompile "org.springframework:spring-beans:$springVersion",
"org.springframework:spring-context-support:$springVersion",
"org.springframework:spring-test:$springVersion"
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
}
+165
View File
@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" 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>4.1.5.RELEASE</version>
<name>spring-security-acl</name>
<description>spring-security-acl</description>
<url>https://spring.io/spring-security</url>
<organization>
<name>spring.io</name>
<url>https://spring.io/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>https://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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.14.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<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>4.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<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>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
-18
View File
@@ -1,18 +0,0 @@
apply plugin: 'io.spring.convention.spring-module'
dependencies {
compile project(':spring-security-core')
compile 'org.springframework:spring-aop'
compile 'org.springframework:spring-context'
compile 'org.springframework:spring-core'
compile 'org.springframework:spring-jdbc'
compile 'org.springframework:spring-tx'
optional 'net.sf.ehcache:ehcache'
testCompile 'org.springframework:spring-beans'
testCompile 'org.springframework:spring-context-support'
testCompile 'org.springframework:spring-test'
testRuntime 'org.hsqldb:hsqldb'
}
@@ -52,7 +52,7 @@ public class AclPermissionCacheOptimizer implements PermissionCacheOptimizer {
return;
}
List<ObjectIdentity> oidsToCache = new ArrayList<>(objects.size());
List<ObjectIdentity> oidsToCache = new ArrayList<ObjectIdentity>(objects.size());
for (Object domainObject : objects) {
if (domainObject == null) {
@@ -127,7 +127,8 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
List<Permission> resolvePermission(Object permission) {
if (permission instanceof Integer) {
return Arrays.asList(permissionFactory.buildFromMask((Integer) permission));
return Arrays.asList(permissionFactory.buildFromMask(((Integer) permission)
.intValue()));
}
if (permission instanceof Permission) {
@@ -52,7 +52,7 @@ class ArrayFilterer<T> implements Filterer<T> {
// Collect the removed objects to a HashSet so that
// it is fast to lookup them when a filtered array
// is constructed.
removeList = new HashSet<>();
removeList = new HashSet<T>();
}
// ~ Methods
@@ -56,7 +56,7 @@ class CollectionFilterer<T> implements Filterer<T> {
// to the method may not necessarily be re-constructable (as
// the Collection(collection) constructor is not guaranteed and
// manually adding may lose sort order or other capabilities)
removeList = new HashSet<>();
removeList = new HashSet<T>();
}
// ~ Methods
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,7 +64,6 @@ public class AccessControlEntryImpl implements AccessControlEntry,
// ~ Methods
// ========================================================================================================
@Override
public boolean equals(Object arg0) {
if (!(arg0 instanceof AccessControlEntryImpl)) {
return false;
@@ -129,48 +128,30 @@ public class AccessControlEntryImpl implements AccessControlEntry,
return true;
}
@Override
public int hashCode() {
int result = this.permission.hashCode();
result = 31 * result + (this.id != null ? this.id.hashCode() : 0);
result = 31 * result + (this.sid.hashCode());
result = 31 * result + (this.auditFailure ? 1 : 0);
result = 31 * result + (this.auditSuccess ? 1 : 0);
result = 31 * result + (this.granting ? 1 : 0);
return result;
}
@Override
public Acl getAcl() {
return acl;
}
@Override
public Serializable getId() {
return id;
}
@Override
public Permission getPermission() {
return permission;
}
@Override
public Sid getSid() {
return sid;
}
@Override
public boolean isAuditFailure() {
return auditFailure;
}
@Override
public boolean isAuditSuccess() {
return auditSuccess;
}
@Override
public boolean isGranting() {
return granting;
}
@@ -188,7 +169,6 @@ public class AccessControlEntryImpl implements AccessControlEntry,
this.permission = permission;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("AccessControlEntryImpl[");
@@ -16,20 +16,18 @@
package org.springframework.security.acls.domain;
import java.util.Arrays;
import java.util.List;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.acls.model.SidRetrievalStrategy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* Default implementation of {@link AclAuthorizationStrategy}.
* <p>
@@ -120,8 +118,7 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
}
// Iterate this principal's authorities to determine right
Set<String> authorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (authorities.contains(requiredAuthority.getAuthority())) {
if (authentication.getAuthorities().contains(requiredAuthority)) {
return;
}
@@ -92,11 +92,11 @@ public abstract class AclFormattingUtils {
*/
public static String printBinary(int mask, char code) {
Assert.doesNotContain(Character.toString(code),
Character.toString(Permission.RESERVED_ON),
() -> Permission.RESERVED_ON + " is a reserved character code");
Character.toString(Permission.RESERVED_ON), Permission.RESERVED_ON
+ " is a reserved character code");
Assert.doesNotContain(Character.toString(code),
Character.toString(Permission.RESERVED_OFF),
() -> Permission.RESERVED_OFF + " is a reserved character code");
Character.toString(Permission.RESERVED_OFF), Permission.RESERVED_OFF
+ " is a reserved character code");
return printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF)
.replace(Permission.RESERVED_ON, code);
@@ -44,7 +44,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
private Acl parentAcl;
private transient AclAuthorizationStrategy aclAuthorizationStrategy;
private transient PermissionGrantingStrategy permissionGrantingStrategy;
private final List<AccessControlEntry> aces = new ArrayList<>();
private final List<AccessControlEntry> aces = new ArrayList<AccessControlEntry>();
private ObjectIdentity objectIdentity;
private Serializable id;
private Sid owner; // OwnershipAcl
@@ -123,7 +123,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
// ~ Methods
// ========================================================================================================
@Override
public void deleteAce(int aceIndex) throws NotFoundException {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_GENERAL);
@@ -145,7 +144,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
}
}
@Override
public void insertAce(int atIndexLocation, Permission permission, Sid sid,
boolean granting) throws NotFoundException {
aclAuthorizationStrategy.securityCheck(this,
@@ -169,24 +167,20 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
}
}
@Override
public List<AccessControlEntry> getEntries() {
// Can safely return AccessControlEntry directly, as they're immutable outside the
// ACL package
return new ArrayList<>(aces);
return new ArrayList<AccessControlEntry>(aces);
}
@Override
public Serializable getId() {
return this.id;
}
@Override
public ObjectIdentity getObjectIdentity() {
return objectIdentity;
}
@Override
public boolean isEntriesInheriting() {
return entriesInheriting;
}
@@ -198,7 +192,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
* ACL was only loaded for a subset of SIDs
* @see DefaultPermissionGrantingStrategy
*/
@Override
public boolean isGranted(List<Permission> permission, List<Sid> sids,
boolean administrativeMode) throws NotFoundException, UnloadedSidException {
Assert.notEmpty(permission, "Permissions required");
@@ -212,7 +205,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
administrativeMode);
}
@Override
public boolean isSidLoaded(List<Sid> sids) {
// If loadedSides is null, this indicates all SIDs were loaded
// Also return true if the caller didn't specify a SID to find
@@ -241,14 +233,12 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
return true;
}
@Override
public void setEntriesInheriting(boolean entriesInheriting) {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_GENERAL);
this.entriesInheriting = entriesInheriting;
}
@Override
public void setOwner(Sid newOwner) {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
@@ -256,12 +246,10 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
this.owner = newOwner;
}
@Override
public Sid getOwner() {
return this.owner;
}
@Override
public void setParent(Acl newParent) {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_GENERAL);
@@ -270,12 +258,10 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
this.parentAcl = newParent;
}
@Override
public Acl getParentAcl() {
return parentAcl;
}
@Override
public void updateAce(int aceIndex, Permission permission) throws NotFoundException {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_GENERAL);
@@ -287,7 +273,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
}
}
@Override
public void updateAuditing(int aceIndex, boolean auditSuccess, boolean auditFailure) {
aclAuthorizationStrategy.securityCheck(this,
AclAuthorizationStrategy.CHANGE_AUDITING);
@@ -300,7 +285,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
}
}
@Override
public boolean equals(Object obj) {
if (obj instanceof AclImpl) {
AclImpl rhs = (AclImpl) obj;
@@ -341,23 +325,6 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
return false;
}
@Override
public int hashCode() {
int result = this.parentAcl != null ? this.parentAcl.hashCode() : 0;
result = 31 * result + this.aclAuthorizationStrategy.hashCode();
result = 31 * result + (this.permissionGrantingStrategy != null ?
this.permissionGrantingStrategy.hashCode() :
0);
result = 31 * result + (this.aces != null ? this.aces.hashCode() : 0);
result = 31 * result + this.objectIdentity.hashCode();
result = 31 * result + this.id.hashCode();
result = 31 * result + (this.owner != null ? this.owner.hashCode() : 0);
result = 31 * result + (this.loadedSids != null ? this.loadedSids.hashCode() : 0);
result = 31 * result + (this.entriesInheriting ? 1 : 0);
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("AclImpl[");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
@@ -38,8 +38,8 @@ import org.springframework.util.Assert;
* @since 2.0.3
*/
public class DefaultPermissionFactory implements PermissionFactory {
private final Map<Integer, Permission> registeredPermissionsByInteger = new HashMap<>();
private final Map<String, Permission> registeredPermissionsByName = new HashMap<>();
private final Map<Integer, Permission> registeredPermissionsByInteger = new HashMap<Integer, Permission>();
private final Map<String, Permission> registeredPermissionsByName = new HashMap<String, Permission>();
/**
* Registers the <tt>Permission</tt> fields from the <tt>BasePermission</tt> class.
@@ -100,13 +100,13 @@ public class DefaultPermissionFactory implements PermissionFactory {
Assert.notNull(perm, "Permission required");
Assert.hasText(permissionName, "Permission name required");
Integer mask = perm.getMask();
Integer mask = Integer.valueOf(perm.getMask());
// Ensure no existing Permission uses this integer or code
Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask),
() -> "An existing Permission already provides mask " + mask);
"An existing Permission already provides mask " + mask);
Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName),
() -> "An existing Permission already provides name '" + permissionName + "'");
"An existing Permission already provides name '" + permissionName + "'");
// Register the new Permission
registeredPermissionsByInteger.put(mask, perm);
@@ -114,10 +114,10 @@ public class DefaultPermissionFactory implements PermissionFactory {
}
public Permission buildFromMask(int mask) {
if (registeredPermissionsByInteger.containsKey(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(mask);
return registeredPermissionsByInteger.get(Integer.valueOf(mask));
}
// To get this far, we have to use a CumulativePermission
@@ -127,7 +127,8 @@ public class DefaultPermissionFactory implements PermissionFactory {
int permissionToCheck = 1 << i;
if ((mask & permissionToCheck) == permissionToCheck) {
Permission p = registeredPermissionsByInteger.get(permissionToCheck);
Permission p = registeredPermissionsByInteger.get(Integer
.valueOf(permissionToCheck));
if (p == null) {
throw new IllegalStateException("Mask '" + permissionToCheck
@@ -155,7 +156,7 @@ public class DefaultPermissionFactory implements PermissionFactory {
return Collections.emptyList();
}
List<Permission> permissions = new ArrayList<>(names.size());
List<Permission> permissions = new ArrayList<Permission>(names.size());
for (String name : names) {
permissions.add(buildFromName(name));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
@@ -87,7 +87,7 @@ public class DefaultPermissionGrantingStrategy implements PermissionGrantingStra
for (AccessControlEntry ace : aces) {
if (isGranted(ace, p)
if ((ace.getPermission().getMask() == p.getMask())
&& ace.getSid().equals(sid)) {
// Found a matching ACE, so its authorization decision will
// prevail
@@ -142,25 +142,4 @@ public class DefaultPermissionGrantingStrategy implements PermissionGrantingStra
}
}
/**
* Compares an ACE Permission to the given Permission.
* By default, we compare the Permission masks for exact match.
* Subclasses of this strategy can override this behavior and implement
* more sophisticated comparisons, e.g. a bitwise comparison for ACEs that grant access.
* <pre>{@code
* if (ace.isGranting() && p.getMask() != 0) {
* return (ace.getPermission().getMask() & p.getMask()) != 0;
* } else {
* return ace.getPermission().getMask() == p.getMask();
* }
* }</pre>
*
* @param ace the ACE from the Acl holding the mask.
* @param p the Permission we are checking against.
* @return true, if the respective masks are considered to be equal.
*/
protected boolean isGranted(AccessControlEntry ace, Permission p) {
return ace.getPermission().getMask() == p.getMask();
}
}
@@ -55,7 +55,6 @@ public class GrantedAuthoritySid implements Sid {
// ~ Methods
// ========================================================================================================
@Override
public boolean equals(Object object) {
if ((object == null) || !(object instanceof GrantedAuthoritySid)) {
return false;
@@ -67,7 +66,6 @@ public class GrantedAuthoritySid implements Sid {
this.getGrantedAuthority());
}
@Override
public int hashCode() {
return this.getGrantedAuthority().hashCode();
}
@@ -76,7 +74,6 @@ public class GrantedAuthoritySid implements Sid {
return grantedAuthority;
}
@Override
public String toString() {
return "GrantedAuthoritySid[" + this.grantedAuthority + "]";
}
@@ -110,7 +110,6 @@ public class ObjectIdentityImpl implements ObjectIdentity {
*
* @return <code>true</code> if the presented object matches this object
*/
@Override
public boolean equals(Object arg0) {
if (arg0 == null || !(arg0 instanceof ObjectIdentityImpl)) {
return false;
@@ -135,12 +134,10 @@ public class ObjectIdentityImpl implements ObjectIdentity {
return type.equals(other.type);
}
@Override
public Serializable getIdentifier() {
return identifier;
}
@Override
public String getType() {
return type;
}
@@ -150,14 +147,14 @@ public class ObjectIdentityImpl implements ObjectIdentity {
*
* @return the hash
*/
@Override
public int hashCode() {
int result = this.type.hashCode();
result = 31 * result + this.identifier.hashCode();
return result;
int code = 31;
code ^= this.type.hashCode();
code ^= this.identifier.hashCode();
return code;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.getClass().getName()).append("[");
@@ -17,6 +17,7 @@ package org.springframework.security.acls.domain;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;
@@ -48,13 +49,17 @@ public class PrincipalSid implements Sid {
Assert.notNull(authentication, "Authentication required");
Assert.notNull(authentication.getPrincipal(), "Principal required");
this.principal = authentication.getName();
if (authentication.getPrincipal() instanceof UserDetails) {
this.principal = ((UserDetails) authentication.getPrincipal()).getUsername();
}
else {
this.principal = authentication.getPrincipal().toString();
}
}
// ~ Methods
// ========================================================================================================
@Override
public boolean equals(Object object) {
if ((object == null) || !(object instanceof PrincipalSid)) {
return false;
@@ -65,7 +70,6 @@ public class PrincipalSid implements Sid {
return ((PrincipalSid) object).getPrincipal().equals(this.getPrincipal());
}
@Override
public int hashCode() {
return this.getPrincipal().hashCode();
}
@@ -74,7 +78,6 @@ public class PrincipalSid implements Sid {
return principal;
}
@Override
public String toString() {
return "PrincipalSid[" + this.principal + "]";
}
@@ -57,7 +57,7 @@ public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
public List<Sid> getSids(Authentication authentication) {
Collection<? extends GrantedAuthority> authorities = roleHierarchy
.getReachableGrantedAuthorities(authentication.getAuthorities());
List<Sid> sids = new ArrayList<>(authorities.size() + 1);
List<Sid> sids = new ArrayList<Sid>(authorities.size() + 1);
sids.add(new PrincipalSid(authentication));
@@ -1,161 +0,0 @@
/*
* Copyright 2002-2018 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
*
* https://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.jdbc;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.util.Assert;
/**
* Utility class for helping convert database representations of {@link ObjectIdentity#getIdentifier()} into
* the correct Java type as specified by <code>acl_class.class_id_type</code>.
* @author paulwheeler
*/
class AclClassIdUtils {
private static final String DEFAULT_CLASS_ID_TYPE_COLUMN_NAME = "class_id_type";
private static final Log log = LogFactory.getLog(AclClassIdUtils.class);
private ConversionService conversionService;
AclClassIdUtils() {
GenericConversionService genericConversionService = new GenericConversionService();
genericConversionService.addConverter(String.class, Long.class, new StringToLongConverter());
genericConversionService.addConverter(String.class, UUID.class, new StringToUUIDConverter());
this.conversionService = genericConversionService;
}
AclClassIdUtils(ConversionService conversionService) {
Assert.notNull(conversionService, "conversionService must not be null");
this.conversionService = conversionService;
}
/**
* Converts the raw type from the database into the right Java type. For most applications the 'raw type' will be Long, for some applications
* it could be String.
* @param identifier The identifier from the database
* @param resultSet Result set of the query
* @return The identifier in the appropriate target Java type. Typically Long or UUID.
* @throws SQLException
*/
Serializable identifierFrom(Serializable identifier, ResultSet resultSet) throws SQLException {
if (isString(identifier) && hasValidClassIdType(resultSet)
&& canConvertFromStringTo(classIdTypeFrom(resultSet))) {
identifier = convertFromStringTo((String) identifier, classIdTypeFrom(resultSet));
} else {
// Assume it should be a Long type
identifier = convertToLong(identifier);
}
return identifier;
}
private boolean hasValidClassIdType(ResultSet resultSet) {
boolean hasClassIdType = false;
try {
hasClassIdType = classIdTypeFrom(resultSet) != null;
} catch (SQLException e) {
log.debug("Unable to obtain the class id type", e);
}
return hasClassIdType;
}
private <T extends Serializable> Class<T> classIdTypeFrom(ResultSet resultSet) throws SQLException {
return classIdTypeFrom(resultSet.getString(DEFAULT_CLASS_ID_TYPE_COLUMN_NAME));
}
private <T extends Serializable> Class<T> classIdTypeFrom(String className) {
Class targetType = null;
if (className != null) {
try {
targetType = Class.forName(className);
} catch (ClassNotFoundException e) {
log.debug("Unable to find class id type on classpath", e);
}
}
return targetType;
}
private <T> boolean canConvertFromStringTo(Class<T> targetType) {
return conversionService.canConvert(String.class, targetType);
}
private <T extends Serializable> T convertFromStringTo(String identifier, Class<T> targetType) {
return conversionService.convert(identifier, targetType);
}
/**
* Converts to a {@link Long}, attempting to use the {@link ConversionService} if available.
* @param identifier The identifier
* @return Long version of the identifier
* @throws NumberFormatException if the string cannot be parsed to a long.
* @throws org.springframework.core.convert.ConversionException if a conversion exception occurred
* @throws IllegalArgumentException if targetType is null
*/
private Long convertToLong(Serializable identifier) {
Long idAsLong;
if (conversionService.canConvert(identifier.getClass(), Long.class)) {
idAsLong = conversionService.convert(identifier, Long.class);
} else {
idAsLong = Long.valueOf(identifier.toString());
}
return idAsLong;
}
private boolean isString(Serializable object) {
return object.getClass().isAssignableFrom(String.class);
}
public void setConversionService(ConversionService conversionService) {
Assert.notNull(conversionService, "conversionService must not be null");
this.conversionService = conversionService;
}
private static class StringToLongConverter implements Converter<String, Long> {
@Override
public Long convert(String identifierAsString) {
if (identifierAsString == null) {
throw new ConversionFailedException(TypeDescriptor.valueOf(String.class),
TypeDescriptor.valueOf(Long.class), null, null);
}
return Long.parseLong(identifierAsString);
}
}
private static class StringToUUIDConverter implements Converter<String, UUID> {
@Override
public UUID convert(String identifierAsString) {
if (identifierAsString == null) {
throw new ConversionFailedException(TypeDescriptor.valueOf(String.class),
TypeDescriptor.valueOf(UUID.class), null, null);
}
return UUID.fromString(identifierAsString);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2004, 2005, 2006, 2017 Acegi Technology Pty Limited
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.springframework.security.acls.jdbc;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -29,9 +30,8 @@ import java.util.Set;
import javax.sql.DataSource;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.security.acls.domain.AccessControlEntryImpl;
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
@@ -78,7 +78,7 @@ import org.springframework.util.Assert;
*/
public class BasicLookupStrategy implements LookupStrategy {
private final static String DEFAULT_SELECT_CLAUSE_COLUMNS = "select acl_object_identity.object_id_identity, "
public final static String DEFAULT_SELECT_CLAUSE = "select acl_object_identity.object_id_identity, "
+ "acl_entry.ace_order, "
+ "acl_object_identity.id as acl_id, "
+ "acl_object_identity.parent_object, "
@@ -92,19 +92,13 @@ public class BasicLookupStrategy implements LookupStrategy {
+ "acl_sid.sid as ace_sid, "
+ "acli_sid.principal as acl_principal, "
+ "acli_sid.sid as acl_sid, "
+ "acl_class.class ";
private final static String DEFAULT_SELECT_CLAUSE_ACL_CLASS_ID_TYPE_COLUMN = ", acl_class.class_id_type ";
private final static String DEFAULT_SELECT_CLAUSE_FROM = "from acl_object_identity "
+ "acl_class.class "
+ "from acl_object_identity "
+ "left join acl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid "
+ "left join acl_class on acl_class.id = acl_object_identity.object_id_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 ( ";
public final static String DEFAULT_SELECT_CLAUSE = DEFAULT_SELECT_CLAUSE_COLUMNS + DEFAULT_SELECT_CLAUSE_FROM;
public final static String DEFAULT_ACL_CLASS_ID_SELECT_CLAUSE = DEFAULT_SELECT_CLAUSE_COLUMNS +
DEFAULT_SELECT_CLAUSE_ACL_CLASS_ID_TYPE_COLUMN + DEFAULT_SELECT_CLAUSE_FROM;
private final static String DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE = "(acl_object_identity.id = ?)";
private final static String DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE = "(acl_object_identity.object_id_identity = ? and acl_class.class = ?)";
@@ -132,8 +126,6 @@ public class BasicLookupStrategy implements LookupStrategy {
private String lookupObjectIdentitiesWhereClause = DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE;
private String orderByClause = DEFAULT_ORDER_BY_CLAUSE;
private AclClassIdUtils aclClassIdUtils;
// ~ Constructors
// ===================================================================================================
@@ -169,9 +161,9 @@ public class BasicLookupStrategy implements LookupStrategy {
this.aclCache = aclCache;
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
this.grantingStrategy = grantingStrategy;
this.aclClassIdUtils = new AclClassIdUtils();
fieldAces.setAccessible(true);
fieldAcl.setAccessible(true);
}
// ~ Methods
@@ -246,12 +238,14 @@ public class BasicLookupStrategy implements LookupStrategy {
String sql = computeRepeatingSql(lookupPrimaryKeysWhereClause, findNow.size());
Set<Long> parentsToLookup = jdbcTemplate.query(sql,
ps -> {
int i = 0;
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
int i = 0;
for (Long toFind : findNow) {
i++;
ps.setLong(i, toFind);
for (Long toFind : findNow) {
i++;
ps.setLong(i, toFind);
}
}
}, new ProcessResultSet(acls, sids));
@@ -288,13 +282,13 @@ public class BasicLookupStrategy implements LookupStrategy {
Assert.notEmpty(objects, "Objects to lookup required");
// Map<ObjectIdentity,Acl>
Map<ObjectIdentity, Acl> result = new HashMap<>(); // contains
Map<ObjectIdentity, Acl> result = new HashMap<ObjectIdentity, Acl>(); // contains
// FULLY
// loaded
// Acl
// objects
Set<ObjectIdentity> currentBatchToLoad = new HashSet<>();
Set<ObjectIdentity> currentBatchToLoad = new HashSet<ObjectIdentity>();
for (int i = 0; i < objects.size(); i++) {
final ObjectIdentity oid = objects.get(i);
@@ -368,7 +362,7 @@ public class BasicLookupStrategy implements LookupStrategy {
final Collection<ObjectIdentity> objectIdentities, List<Sid> sids) {
Assert.notEmpty(objectIdentities, "Must provide identities to lookup");
final Map<Serializable, Acl> acls = new HashMap<>(); // contains
final Map<Serializable, Acl> acls = new HashMap<Serializable, Acl>(); // contains
// Acls
// with
// StubAclParents
@@ -379,20 +373,23 @@ public class BasicLookupStrategy implements LookupStrategy {
objectIdentities.size());
Set<Long> parentsToLookup = jdbcTemplate.query(sql,
ps -> {
int i = 0;
for (ObjectIdentity oid : objectIdentities) {
// Determine prepared statement values for this iteration
String type = oid.getType();
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
int i = 0;
for (ObjectIdentity oid : objectIdentities) {
// Determine prepared statement values for this iteration
String type = oid.getType();
// No need to check for nulls, as guaranteed non-null by
// ObjectIdentity.getIdentifier() interface contract
String identifier = oid.getIdentifier().toString();
// No need to check for nulls, as guaranteed non-null by
// ObjectIdentity.getIdentifier() interface contract
String identifier = oid.getIdentifier().toString();
long id = (Long.valueOf(identifier)).longValue();
// Inject values
ps.setString((2 * i) + 1, identifier);
ps.setString((2 * i) + 2, type);
i++;
// Inject values
ps.setLong((2 * i) + 1, id);
ps.setString((2 * i) + 2, type);
i++;
}
}
}, new ProcessResultSet(acls, sids));
@@ -403,7 +400,7 @@ public class BasicLookupStrategy implements LookupStrategy {
}
// Finally, convert our "acls" containing StubAclParents into true Acls
Map<ObjectIdentity, Acl> resultMap = new HashMap<>();
Map<ObjectIdentity, Acl> resultMap = new HashMap<ObjectIdentity, Acl>();
for (Acl inputAcl : acls.values()) {
Assert.isInstanceOf(AclImpl.class, inputAcl,
@@ -449,7 +446,7 @@ public class BasicLookupStrategy implements LookupStrategy {
// Now we have the parent (if there is one), create the true AclImpl
AclImpl result = new AclImpl(inputAcl.getObjectIdentity(),
inputAcl.getId(), aclAuthorizationStrategy, grantingStrategy,
(Long) inputAcl.getId(), aclAuthorizationStrategy, grantingStrategy,
parent, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner());
// Copy the "aces" from the input to the destination
@@ -458,7 +455,7 @@ public class BasicLookupStrategy implements LookupStrategy {
List<AccessControlEntryImpl> aces = readAces(inputAcl);
// Create a list in which to store the "aces" for the "result" AclImpl instance
List<AccessControlEntryImpl> acesNew = new ArrayList<>();
List<AccessControlEntryImpl> acesNew = new ArrayList<AccessControlEntryImpl>();
// Iterate over the "aces" input and replace each nested
// AccessControlEntryImpl.getAcl() with the new "result" AclImpl instance
@@ -540,18 +537,6 @@ public class BasicLookupStrategy implements LookupStrategy {
this.orderByClause = orderByClause;
}
public final void setAclClassIdSupported(boolean aclClassIdSupported) {
if (aclClassIdSupported) {
Assert.isTrue(this.selectClause.equals(DEFAULT_SELECT_CLAUSE), "Cannot set aclClassIdSupported and override the select clause; "
+ "just override the select clause");
this.selectClause = DEFAULT_ACL_CLASS_ID_SELECT_CLAUSE;
}
}
public final void setConversionService(ConversionService conversionService) {
this.aclClassIdUtils = new AclClassIdUtils(conversionService);
}
// ~ Inner Classes
// ==================================================================================================
@@ -559,7 +544,7 @@ public class BasicLookupStrategy implements LookupStrategy {
private final Map<Serializable, Acl> acls;
private final List<Sid> sids;
ProcessResultSet(Map<Serializable, Acl> acls, List<Sid> sids) {
public ProcessResultSet(Map<Serializable, Acl> acls, List<Sid> sids) {
Assert.notNull(acls, "ACLs cannot be null");
this.acls = acls;
this.sids = sids; // can be null
@@ -576,7 +561,7 @@ public class BasicLookupStrategy implements LookupStrategy {
* @throws SQLException
*/
public Set<Long> extractData(ResultSet rs) throws SQLException {
Set<Long> parentIdsToLookup = new HashSet<>(); // Set of parent_id Longs
Set<Long> parentIdsToLookup = new HashSet<Long>(); // Set of parent_id Longs
while (rs.next()) {
// Convert current row into an Acl (albeit with a StubAclParent)
@@ -587,15 +572,15 @@ public class BasicLookupStrategy implements LookupStrategy {
if (parentId != 0) {
// See if it's already in the "acls"
if (acls.containsKey(parentId)) {
if (acls.containsKey(new Long(parentId))) {
continue; // skip this while iteration
}
// Now try to find it in the cache
MutableAcl cached = aclCache.getFromCache(parentId);
MutableAcl cached = aclCache.getFromCache(new Long(parentId));
if ((cached == null) || !cached.isSidLoaded(sids)) {
parentIdsToLookup.add(parentId);
parentIdsToLookup.add(new Long(parentId));
}
else {
// Pop into the acls map, so our convert method doesn't
@@ -617,29 +602,25 @@ public class BasicLookupStrategy implements LookupStrategy {
* @param rs the ResultSet focused on a current row
*
* @throws SQLException if something goes wrong converting values
* @throws ConversionException if can't convert to the desired Java type
*/
private void convertCurrentResultIntoObject(Map<Serializable, Acl> acls,
ResultSet rs) throws SQLException {
Long id = rs.getLong("acl_id");
Long id = new Long(rs.getLong("acl_id"));
// If we already have an ACL for this ID, just create the ACE
Acl acl = acls.get(id);
if (acl == null) {
// Make an AclImpl and pop it into the Map
// If the Java type is a String, check to see if we can convert it to the target id type, e.g. UUID.
Serializable identifier = (Serializable) rs.getObject("object_id_identity");
identifier = aclClassIdUtils.identifierFrom(identifier, rs);
ObjectIdentity objectIdentity = new ObjectIdentityImpl(
rs.getString("class"), identifier);
rs.getString("class"), Long.valueOf(rs
.getLong("object_id_identity")));
Acl parentAcl = null;
long parentAclId = rs.getLong("parent_object");
if (parentAclId != 0) {
parentAcl = new StubAclParent(parentAclId);
parentAcl = new StubAclParent(Long.valueOf(parentAclId));
}
boolean entriesInheriting = rs.getBoolean("entries_inheriting");
@@ -656,7 +637,7 @@ public class BasicLookupStrategy implements LookupStrategy {
// It is permissible to have no ACEs in an ACL (which is detected by a null
// ACE_SID)
if (rs.getString("ace_sid") != null) {
Long aceId = rs.getLong("ace_id");
Long aceId = new Long(rs.getLong("ace_id"));
Sid recipient = createSid(rs.getBoolean("ace_principal"),
rs.getString("ace_sid"));
@@ -683,7 +664,7 @@ public class BasicLookupStrategy implements LookupStrategy {
private static class StubAclParent implements Acl {
private final Long id;
StubAclParent(Long id) {
public StubAclParent(Long id) {
this.id = id;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2004, 2005, 2006, 2017, 2018 Acegi Technology Pty Limited
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,8 @@
*/
package org.springframework.security.acls.jdbc;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -24,9 +25,8 @@ import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.AclService;
@@ -49,15 +49,8 @@ public class JdbcAclService implements AclService {
// =====================================================================================
protected static final Log log = LogFactory.getLog(JdbcAclService.class);
private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS = "class.class as class";
private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE = DEFAULT_SELECT_ACL_CLASS_COLUMNS + ", class.class_id_type as class_id_type";
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, " + DEFAULT_SELECT_ACL_CLASS_COLUMNS
+ " from acl_object_identity obj, acl_object_identity parent, acl_class class "
+ "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+ "and parent.object_id_identity = ? and parent.object_id_class = ("
+ "select id FROM acl_class where acl_class.class = ?)";
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE = "select obj.object_id_identity as obj_id, " + DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE
+ " from acl_object_identity obj, acl_object_identity parent, acl_class class "
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, class.class as class "
+ "from acl_object_identity obj, acl_object_identity parent, acl_class class "
+ "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+ "and parent.object_id_identity = ? and parent.object_id_class = ("
+ "select id FROM acl_class where acl_class.class = ?)";
@@ -65,38 +58,34 @@ public class JdbcAclService implements AclService {
// ~ Instance fields
// ================================================================================================
protected final JdbcOperations jdbcOperations;
protected final JdbcTemplate jdbcTemplate;
private final LookupStrategy lookupStrategy;
private boolean aclClassIdSupported;
private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
private AclClassIdUtils aclClassIdUtils;
// ~ Constructors
// ===================================================================================================
public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
this(new JdbcTemplate(dataSource), lookupStrategy);
}
public JdbcAclService(JdbcOperations jdbcOperations, LookupStrategy lookupStrategy) {
Assert.notNull(jdbcOperations, "JdbcOperations required");
Assert.notNull(dataSource, "DataSource required");
Assert.notNull(lookupStrategy, "LookupStrategy required");
this.jdbcOperations = jdbcOperations;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.lookupStrategy = lookupStrategy;
this.aclClassIdUtils = new AclClassIdUtils();
}
// ~ Methods
// ========================================================================================================
public List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {
Object[] args = { parentIdentity.getIdentifier().toString(), parentIdentity.getType() };
List<ObjectIdentity> objects = jdbcOperations.query(findChildrenSql, args,
(rs, rowNum) -> {
String javaType = rs.getString("class");
Serializable identifier = (Serializable) rs.getObject("obj_id");
identifier = aclClassIdUtils.identifierFrom(identifier, rs);
return new ObjectIdentityImpl(javaType, identifier);
Object[] args = { parentIdentity.getIdentifier(), parentIdentity.getType() };
List<ObjectIdentity> objects = jdbcTemplate.query(findChildrenSql, args,
new RowMapper<ObjectIdentity>() {
public ObjectIdentity mapRow(ResultSet rs, int rowNum)
throws SQLException {
String javaType = rs.getString("class");
Long identifier = new Long(rs.getLong("obj_id"));
return new ObjectIdentityImpl(javaType, identifier);
}
});
if (objects.size() == 0) {
@@ -110,9 +99,9 @@ public class JdbcAclService implements AclService {
throws NotFoundException {
Map<ObjectIdentity, Acl> map = readAclsById(Arrays.asList(object), sids);
Assert.isTrue(map.containsKey(object),
() -> "There should have been an Acl entry for ObjectIdentity " + object);
"There should have been an Acl entry for ObjectIdentity " + object);
return map.get(object);
return (Acl) map.get(object);
}
public Acl readAclById(ObjectIdentity object) throws NotFoundException {
@@ -149,24 +138,4 @@ public class JdbcAclService implements AclService {
public void setFindChildrenQuery(String findChildrenSql) {
this.findChildrenSql = findChildrenSql;
}
public void setAclClassIdSupported(boolean aclClassIdSupported) {
this.aclClassIdSupported = aclClassIdSupported;
if (aclClassIdSupported) {
// Change the default children select if it hasn't been overridden
if (this.findChildrenSql.equals(DEFAULT_SELECT_ACL_WITH_PARENT_SQL)) {
this.findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE;
} else {
log.debug("Find children statement has already been overridden, so not overridding the default");
}
}
}
public void setConversionService(ConversionService conversionService) {
this.aclClassIdUtils = new AclClassIdUtils(conversionService);
}
protected boolean isAclClassIdSupported() {
return aclClassIdSupported;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2004, 2005, 2006, 2017, 2018 Acegi Technology Pty Limited
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,8 +58,6 @@ import org.springframework.util.Assert;
* @author Johannes Zlattinger
*/
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
private static final String DEFAULT_INSERT_INTO_ACL_CLASS = "insert into acl_class (class) values (?)";
private static final String DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID = "insert into acl_class (class, class_id_type) values (?, ?)";
// ~ Instance fields
// ================================================================================================
@@ -69,7 +67,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
private String deleteObjectIdentityByPrimaryKey = "delete from acl_object_identity where id=?";
private String classIdentityQuery = "call identity()";
private String sidIdentityQuery = "call identity()";
private String insertClass = DEFAULT_INSERT_INTO_ACL_CLASS;
private String insertClass = "insert into acl_class (class) values (?)";
private String insertEntry = "insert into acl_entry "
+ "(acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
+ "values (?, ?, ?, ?, ?, ?, ?)";
@@ -135,7 +133,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
if (acl.getEntries().isEmpty()) {
return;
}
jdbcOperations.batchUpdate(insertEntry, new BatchPreparedStatementSetter() {
jdbcTemplate.batchUpdate(insertEntry, new BatchPreparedStatementSetter() {
public int getBatchSize() {
return acl.getEntries().size();
}
@@ -146,9 +144,10 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
"Unknown ACE class");
AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
stmt.setLong(1, (Long) acl.getId());
stmt.setLong(1, ((Long) acl.getId()).longValue());
stmt.setInt(2, i);
stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true));
stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true)
.longValue());
stmt.setInt(4, entry.getPermission().getMask());
stmt.setBoolean(5, entry.isGranting());
stmt.setBoolean(6, entry.isAuditSuccess());
@@ -168,8 +167,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
*/
protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
Long classId = createOrRetrieveClassPrimaryKey(object.getType(), true, object.getIdentifier().getClass());
jdbcOperations.update(insertObjectIdentity, classId, object.getIdentifier().toString(), sidId,
Long classId = createOrRetrieveClassPrimaryKey(object.getType(), true);
jdbcTemplate.update(insertObjectIdentity, classId, object.getIdentifier(), sidId,
Boolean.TRUE);
}
@@ -182,8 +181,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
*
* @return the primary key or null if not found
*/
protected Long createOrRetrieveClassPrimaryKey(String type, boolean allowCreate, Class idType) {
List<Long> classIds = jdbcOperations.queryForList(selectClassPrimaryKey,
protected Long createOrRetrieveClassPrimaryKey(String type, boolean allowCreate) {
List<Long> classIds = jdbcTemplate.queryForList(selectClassPrimaryKey,
new Object[] { type }, Long.class);
if (!classIds.isEmpty()) {
@@ -191,14 +190,10 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
}
if (allowCreate) {
if (!isAclClassIdSupported()) {
jdbcOperations.update(insertClass, type);
} else {
jdbcOperations.update(insertClass, type, idType.getCanonicalName());
}
jdbcTemplate.update(insertClass, type);
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
return jdbcOperations.queryForObject(classIdentityQuery, Long.class);
return jdbcTemplate.queryForObject(classIdentityQuery, Long.class);
}
return null;
@@ -247,18 +242,18 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
protected Long createOrRetrieveSidPrimaryKey(String sidName, boolean sidIsPrincipal,
boolean allowCreate) {
List<Long> sidIds = jdbcOperations.queryForList(selectSidPrimaryKey, new Object[] {
sidIsPrincipal, sidName }, Long.class);
List<Long> sidIds = jdbcTemplate.queryForList(selectSidPrimaryKey, new Object[] {
Boolean.valueOf(sidIsPrincipal), sidName }, Long.class);
if (!sidIds.isEmpty()) {
return sidIds.get(0);
}
if (allowCreate) {
jdbcOperations.update(insertSid, sidIsPrincipal, sidName);
jdbcTemplate.update(insertSid, Boolean.valueOf(sidIsPrincipal), sidName);
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
return jdbcOperations.queryForObject(sidIdentityQuery, Long.class);
return jdbcTemplate.queryForObject(sidIdentityQuery, Long.class);
}
return null;
@@ -310,7 +305,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
* @param oidPrimaryKey the rows in acl_entry to delete
*/
protected void deleteEntries(Long oidPrimaryKey) {
jdbcOperations.update(deleteEntryByObjectIdentityForeignKey, oidPrimaryKey);
jdbcTemplate.update(deleteEntryByObjectIdentityForeignKey, oidPrimaryKey);
}
/**
@@ -324,7 +319,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
*/
protected void deleteObjectIdentity(Long oidPrimaryKey) {
// Delete the acl_object_identity row
jdbcOperations.update(deleteObjectIdentityByPrimaryKey, oidPrimaryKey);
jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, oidPrimaryKey);
}
/**
@@ -338,8 +333,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
*/
protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
try {
return jdbcOperations.queryForObject(selectObjectIdentityPrimaryKey, Long.class,
oid.getType(), oid.getIdentifier().toString());
return jdbcTemplate.queryForObject(selectObjectIdentityPrimaryKey, Long.class,
oid.getType(), oid.getIdentifier());
}
catch (DataAccessException notFound) {
return null;
@@ -408,8 +403,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
Assert.notNull(acl.getOwner(), "Owner is required in this implementation");
Long ownerSid = createOrRetrieveSidPrimaryKey(acl.getOwner(), true);
int count = jdbcOperations.update(updateObjectIdentity, parentId, ownerSid,
acl.isEntriesInheriting(), acl.getId());
int count = jdbcTemplate.update(updateObjectIdentity, parentId, ownerSid,
Boolean.valueOf(acl.isEntriesInheriting()), acl.getId());
if (count != 1) {
throw new NotFoundException("Unable to locate ACL to update");
@@ -490,17 +485,4 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
public void setForeignKeysInDatabase(boolean foreignKeysInDatabase) {
this.foreignKeysInDatabase = foreignKeysInDatabase;
}
@Override
public void setAclClassIdSupported(boolean aclClassIdSupported) {
super.setAclClassIdSupported(aclClassIdSupported);
if (aclClassIdSupported) {
// Change the default insert if it hasn't been overridden
if (this.insertClass.equals(DEFAULT_INSERT_INTO_ACL_CLASS)) {
this.insertClass = DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID;
} else {
log.debug("Insert class statement has already been overridden, so not overridding the default");
}
}
}
}
@@ -21,7 +21,7 @@ CREATE TABLE acl_class (
CREATE TABLE acl_object_identity (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
object_id_class BIGINT UNSIGNED NOT NULL,
object_id_identity VARCHAR(36) NOT NULL,
object_id_identity BIGINT NOT NULL,
parent_object BIGINT UNSIGNED,
owner_sid BIGINT UNSIGNED,
entries_inheriting BOOLEAN NOT NULL,
@@ -43,7 +43,7 @@ END;
CREATE TABLE acl_object_identity (
id NUMBER(38) NOT NULL PRIMARY KEY,
object_id_class NUMBER(38) NOT NULL,
object_id_identity NVARCHAR2(36) 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)),
@@ -15,14 +15,13 @@ create table acl_sid(
create table acl_class(
id bigserial not null primary key,
class varchar(100) not null,
class_id_type varchar(100),
constraint unique_uk_2 unique(class)
);
create table acl_object_identity(
id bigserial primary key,
object_id_class bigint not null,
object_id_identity varchar(36) not null,
object_id_identity bigint not null,
parent_object bigint,
owner_sid bigint,
entries_inheriting boolean not null,
@@ -21,7 +21,7 @@ CREATE TABLE acl_class (
CREATE TABLE acl_object_identity (
id BIGINT NOT NULL IDENTITY PRIMARY KEY,
object_id_class BIGINT NOT NULL,
object_id_identity VARCHAR(36) NOT NULL,
object_id_identity BIGINT NOT NULL,
parent_object BIGINT,
owner_sid BIGINT,
entries_inheriting BIT NOT NULL,
@@ -1,47 +0,0 @@
-- 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,
class_id_type varchar_ignorecase(100),
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 varchar_ignorecase(36) 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)
);
@@ -32,7 +32,7 @@ public class AclFormattingUtilsTests {
// ~ Methods
// ========================================================================================================
@Test
public final void testDemergePatternsParametersConstraints() {
public final void testDemergePatternsParametersConstraints() throws Exception {
try {
AclFormattingUtils.demergePatterns(null, "SOME STRING");
fail("It should have thrown IllegalArgumentException");
@@ -63,7 +63,7 @@ public class AclFormattingUtilsTests {
}
@Test
public final void testDemergePatterns() {
public final void testDemergePatterns() throws Exception {
String original = "...........................A...R";
String removeBits = "...............................R";
assertThat(AclFormattingUtils.demergePatterns(original, removeBits)).isEqualTo(
@@ -76,7 +76,7 @@ public class AclFormattingUtilsTests {
}
@Test
public final void testMergePatternsParametersConstraints() {
public final void testMergePatternsParametersConstraints() throws Exception {
try {
AclFormattingUtils.mergePatterns(null, "SOME STRING");
fail("It should have thrown IllegalArgumentException");
@@ -106,7 +106,7 @@ public class AclFormattingUtilsTests {
}
@Test
public final void testMergePatterns() {
public final void testMergePatterns() throws Exception {
String original = "...............................R";
String extraBits = "...........................A....";
assertThat(AclFormattingUtils.mergePatterns(original, extraBits)).isEqualTo(
@@ -119,7 +119,7 @@ public class AclFormattingUtilsTests {
}
@Test
public final void testBinaryPrints() {
public final void testBinaryPrints() throws Exception {
assertThat(AclFormattingUtils.printBinary(15)).isEqualTo(
"............................****");
@@ -36,7 +36,7 @@ import java.util.List;
public class AclPermissionCacheOptimizerTests {
@Test
public void eagerlyLoadsRequiredAcls() {
public void eagerlyLoadsRequiredAcls() throws Exception {
AclService service = mock(AclService.class);
AclPermissionCacheOptimizer pco = new AclPermissionCacheOptimizer(service);
ObjectIdentityRetrievalStrategy oidStrat = mock(ObjectIdentityRetrievalStrategy.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
@@ -37,12 +37,13 @@ import org.springframework.security.core.Authentication;
public class AclPermissionEvaluatorTests {
@Test
public void hasPermissionReturnsTrueIfAclGrantsPermission() {
@SuppressWarnings("unchecked")
public void hasPermissionReturnsTrueIfAclGrantsPermission() throws Exception {
AclService service = mock(AclService.class);
AclPermissionEvaluator pe = new AclPermissionEvaluator(service);
ObjectIdentity oid = mock(ObjectIdentity.class);
ObjectIdentityRetrievalStrategy oidStrategy = mock(ObjectIdentityRetrievalStrategy.class);
when(oidStrategy.getObjectIdentity(any(Object.class))).thenReturn(oid);
when(oidStrategy.getObjectIdentity(anyObject())).thenReturn(oid);
pe.setObjectIdentityRetrievalStrategy(oidStrategy);
pe.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
Acl acl = mock(Acl.class);
@@ -62,7 +63,7 @@ public class AclPermissionEvaluatorTests {
AclPermissionEvaluator pe = new AclPermissionEvaluator(service);
ObjectIdentity oid = mock(ObjectIdentity.class);
ObjectIdentityRetrievalStrategy oidStrategy = mock(ObjectIdentityRetrievalStrategy.class);
when(oidStrategy.getObjectIdentity(any(Object.class))).thenReturn(oid);
when(oidStrategy.getObjectIdentity(anyObject())).thenReturn(oid);
pe.setObjectIdentityRetrievalStrategy(oidStrategy);
pe.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
Acl acl = mock(Acl.class);
@@ -37,12 +37,12 @@ import java.util.List;
@SuppressWarnings({ "unchecked" })
public class AclEntryAfterInvocationCollectionFilteringProviderTests {
@Test
public void objectsAreRemovedIfPermissionDenied() {
public void objectsAreRemovedIfPermissionDenied() throws Exception {
AclService service = mock(AclService.class);
Acl acl = mock(Acl.class);
when(acl.isGranted(any(), any(), anyBoolean())).thenReturn(
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(
false);
when(service.readAclById(any(), any())).thenReturn(
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(
acl);
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(
service, Arrays.asList(mock(Permission.class)));
@@ -63,7 +63,7 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
}
@Test
public void accessIsGrantedIfNoAttributesDefined() {
public void accessIsGrantedIfNoAttributesDefined() throws Exception {
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(
mock(AclService.class), Arrays.asList(mock(Permission.class)));
Object returned = new Object();
@@ -75,14 +75,14 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
}
@Test
public void nullReturnObjectIsIgnored() {
public void nullReturnObjectIsIgnored() throws Exception {
AclService service = mock(AclService.class);
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(
service, Arrays.asList(mock(Permission.class)));
assertThat(provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
.isNull();
.isNull();;
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
}
@@ -37,7 +37,7 @@ import java.util.List;
public class AclEntryAfterInvocationProviderTests {
@Test(expected = IllegalArgumentException.class)
public void rejectsMissingPermissions() {
public void rejectsMissingPermissions() throws Exception {
try {
new AclEntryAfterInvocationProvider(mock(AclService.class), null);
fail("Exception expected");
@@ -54,7 +54,7 @@ public class AclEntryAfterInvocationProviderTests {
Acl acl = mock(Acl.class);
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(
true);
when(service.readAclById(any(), any())).thenReturn(
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(
acl);
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
service, Arrays.asList(mock(Permission.class)));
@@ -72,7 +72,7 @@ public class AclEntryAfterInvocationProviderTests {
}
@Test
public void accessIsGrantedIfNoAttributesDefined() {
public void accessIsGrantedIfNoAttributesDefined() throws Exception {
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
mock(AclService.class), Arrays.asList(mock(Permission.class)));
Object returned = new Object();
@@ -85,7 +85,7 @@ public class AclEntryAfterInvocationProviderTests {
}
@Test
public void accessIsGrantedIfObjectTypeNotSupported() {
public void accessIsGrantedIfObjectTypeNotSupported() throws Exception {
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
mock(AclService.class), Arrays.asList(mock(Permission.class)));
provider.setProcessDomainObjectClass(String.class);
@@ -106,9 +106,9 @@ public class AclEntryAfterInvocationProviderTests {
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(
false);
// Try a second time with no permissions found
when(acl.isGranted(any(), any(List.class), anyBoolean())).thenThrow(
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenThrow(
new NotFoundException(""));
when(service.readAclById(any(), any())).thenReturn(
when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(
acl);
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
service, Arrays.asList(mock(Permission.class)));
@@ -131,14 +131,14 @@ public class AclEntryAfterInvocationProviderTests {
}
@Test
public void nullReturnObjectIsIgnored() {
public void nullReturnObjectIsIgnored() throws Exception {
AclService service = mock(AclService.class);
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
service, Arrays.asList(mock(Permission.class)));
assertThat(provider.decide(mock(Authentication.class), new Object(),
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
.isNull();
.isNull();;
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
}
}
@@ -71,11 +71,11 @@ public class AccessControlImplEntryTests {
Sid sid = new PrincipalSid("johndoe");
// Create a sample entry
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl,
AccessControlEntry ace = new AccessControlEntryImpl(Long.valueOf(1), mockAcl,
sid, BasePermission.ADMINISTRATION, true, true, true);
// and check every get() method
assertThat(ace.getId()).isEqualTo(1L);
assertThat(ace.getId()).isEqualTo(new Long(1));
assertThat(ace.getAcl()).isEqualTo(mockAcl);
assertThat(ace.getSid()).isEqualTo(sid);
assertThat(ace.isGranting()).isTrue();
@@ -92,26 +92,26 @@ public class AccessControlImplEntryTests {
when(mockAcl.getObjectIdentity()).thenReturn(oid);
Sid sid = new PrincipalSid("johndoe");
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl,
AccessControlEntry ace = new AccessControlEntryImpl(Long.valueOf(1), mockAcl,
sid, BasePermission.ADMINISTRATION, true, true, true);
assertThat(ace).isNotNull();
assertThat(ace).isNotEqualTo(100L);
assertThat(ace).isNotEqualTo(Long.valueOf(100));
assertThat(ace).isEqualTo(ace);
assertThat(ace).isEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
assertThat(ace).isEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(2L, mockAcl, sid,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(2), mockAcl, sid,
BasePermission.ADMINISTRATION, true, true, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl,
new PrincipalSid("scott"), BasePermission.ADMINISTRATION, true, true,
true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
BasePermission.WRITE, true, true, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
BasePermission.ADMINISTRATION, false, true, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
BasePermission.ADMINISTRATION, true, false, true));
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(Long.valueOf(1), mockAcl, sid,
BasePermission.ADMINISTRATION, true, true, false));
}
}
@@ -1,72 +0,0 @@
/*
* Copyright 2002-2016 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
*
* https://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 java.util.Arrays;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
*
* @author Rob Winch
*
*/
@RunWith(MockitoJUnitRunner.class)
public class AclAuthorizationStrategyImplTests {
@Mock
Acl acl;
GrantedAuthority authority;
AclAuthorizationStrategyImpl strategy;
@Before
public void setup() {
authority = new SimpleGrantedAuthority("ROLE_AUTH");
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar", Arrays.asList(authority));
authentication.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
@After
public void cleanup() {
SecurityContextHolder.clearContext();
}
// gh-4085
@Test
public void securityCheckWhenCustomAuthorityThenNameIsUsed() {
strategy = new AclAuthorizationStrategyImpl(new CustomAuthority());
strategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
}
@SuppressWarnings("serial")
class CustomAuthority implements GrantedAuthority {
@Override
public String getAuthority() {
return authority.getAuthority();
}
}
}
@@ -49,28 +49,26 @@ public class AclImplTests {
PermissionGrantingStrategy pgs;
AuditLogger mockAuditLogger;
ObjectIdentity objectIdentity = new ObjectIdentityImpl(TARGET_CLASS, 100);
private DefaultPermissionFactory permissionFactory;
// ~ Methods
// ========================================================================================================
@Before
public void setUp() {
public void setUp() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
authzStrategy = mock(AclAuthorizationStrategy.class);
mockAuditLogger = mock(AuditLogger.class);
pgs = new DefaultPermissionGrantingStrategy(mockAuditLogger);
auth.setAuthenticated(true);
permissionFactory = new DefaultPermissionFactory();
}
@After
public void tearDown() {
public void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
@Test(expected = IllegalArgumentException.class)
public void constructorsRejectNullObjectIdentity() {
public void constructorsRejectNullObjectIdentity() throws Exception {
try {
new AclImpl(null, 1, authzStrategy, pgs, null, null, true, new PrincipalSid(
"joe"));
@@ -82,7 +80,7 @@ public class AclImplTests {
}
@Test(expected = IllegalArgumentException.class)
public void constructorsRejectNullId() {
public void constructorsRejectNullId() throws Exception {
try {
new AclImpl(objectIdentity, null, authzStrategy, pgs, null, null, true,
new PrincipalSid("joe"));
@@ -95,7 +93,7 @@ public class AclImplTests {
@SuppressWarnings("deprecation")
@Test(expected = IllegalArgumentException.class)
public void constructorsRejectNullAclAuthzStrategy() {
public void constructorsRejectNullAclAuthzStrategy() throws Exception {
try {
new AclImpl(objectIdentity, 1, null, new DefaultPermissionGrantingStrategy(
mockAuditLogger), null, null, true, new PrincipalSid("joe"));
@@ -107,7 +105,7 @@ public class AclImplTests {
}
@Test
public void insertAceRejectsNullParameters() {
public void insertAceRejectsNullParameters() throws Exception {
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
try {
@@ -125,7 +123,7 @@ public class AclImplTests {
}
@Test
public void insertAceAddsElementAtCorrectIndex() {
public void insertAceAddsElementAtCorrectIndex() throws Exception {
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
MockAclService service = new MockAclService();
@@ -168,7 +166,7 @@ public class AclImplTests {
}
@Test(expected = NotFoundException.class)
public void insertAceFailsForNonExistentElement() {
public void insertAceFailsForNonExistentElement() throws Exception {
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
MockAclService service = new MockAclService();
@@ -182,7 +180,7 @@ public class AclImplTests {
}
@Test
public void deleteAceKeepsInitialOrdering() {
public void deleteAceKeepsInitialOrdering() throws Exception {
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
MockAclService service = new MockAclService();
@@ -219,7 +217,7 @@ public class AclImplTests {
}
@Test
public void deleteAceFailsForNonExistentElement() {
public void deleteAceFailsForNonExistentElement() throws Exception {
AclAuthorizationStrategyImpl strategy = new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
@@ -234,18 +232,18 @@ public class AclImplTests {
}
@Test
public void isGrantingRejectsEmptyParameters() {
public void isGrantingRejectsEmptyParameters() throws Exception {
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
Sid ben = new PrincipalSid("ben");
try {
acl.isGranted(new ArrayList<>(0), Arrays.asList(ben), false);
acl.isGranted(new ArrayList<Permission>(0), Arrays.asList(ben), false);
fail("It should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
}
try {
acl.isGranted(READ, new ArrayList<>(0), false);
acl.isGranted(READ, new ArrayList<Sid>(0), false);
fail("It should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
@@ -253,7 +251,7 @@ public class AclImplTests {
}
@Test
public void isGrantingGrantsAccessForAclWithNoParent() {
public void isGrantingGrantsAccessForAclWithNoParent() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_GENERAL", "ROLE_GUEST");
auth.setAuthenticated(true);
@@ -299,7 +297,7 @@ public class AclImplTests {
}
@Test
public void isGrantingGrantsAccessForInheritableAcls() {
public void isGrantingGrantsAccessForInheritableAcls() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_GENERAL");
auth.setAuthenticated(true);
@@ -381,7 +379,7 @@ public class AclImplTests {
}
@Test
public void updatedAceValuesAreCorrectlyReflectedInAcl() {
public void updatedAceValuesAreCorrectlyReflectedInAcl() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_GENERAL");
auth.setAuthenticated(true);
@@ -413,7 +411,7 @@ public class AclImplTests {
}
@Test
public void auditableEntryFlagsAreUpdatedCorrectly() {
public void auditableEntryFlagsAreUpdatedCorrectly() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_AUDITING", "ROLE_GENERAL");
auth.setAuthenticated(true);
@@ -451,7 +449,7 @@ public class AclImplTests {
}
@Test
public void gettersAndSettersAreConsistent() {
public void gettersAndSettersAreConsistent() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_GENERAL");
auth.setAuthenticated(true);
@@ -487,7 +485,7 @@ public class AclImplTests {
}
@Test
public void isSidLoadedBehavesAsExpected() {
public void isSidLoadedBehavesAsExpected() throws Exception {
List<Sid> loadedSids = Arrays.asList(new PrincipalSid("ben"),
new GrantedAuthoritySid("ROLE_IGNORED"));
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null,
@@ -497,39 +495,40 @@ public class AclImplTests {
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"),
new PrincipalSid("ben"))))
.isTrue();
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid(
assertThat(acl.isSidLoaded(Arrays.asList((Sid)new GrantedAuthoritySid(
"ROLE_IGNORED"))))
.isTrue();
assertThat(acl.isSidLoaded(BEN)).isTrue();
assertThat(acl.isSidLoaded(null)).isTrue();
assertThat(acl.isSidLoaded(new ArrayList<>(0))).isTrue();
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
assertThat(acl.isSidLoaded(new ArrayList<Sid>(0))).isTrue();
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid(
"ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_IGNORED"))))
.isTrue();
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid(
"ROLE_GENERAL"), new GrantedAuthoritySid("ROLE_IGNORED"))))
.isFalse();
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
assertThat(acl.isSidLoaded(Arrays.asList((Sid)new GrantedAuthoritySid(
"ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_GENERAL"))))
.isFalse();
}
@Test(expected = NotFoundException.class)
public void insertAceRaisesNotFoundExceptionForIndexLessThanZero() {
public void insertAceRaisesNotFoundExceptionForIndexLessThanZero() throws Exception {
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
acl.insertAce(-1, mock(Permission.class), mock(Sid.class), true);
}
@Test(expected = NotFoundException.class)
public void deleteAceRaisesNotFoundExceptionForIndexLessThanZero() {
public void deleteAceRaisesNotFoundExceptionForIndexLessThanZero() throws Exception {
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
acl.deleteAce(-1);
}
@Test(expected = NotFoundException.class)
public void insertAceRaisesNotFoundExceptionForIndexGreaterThanSize() {
public void insertAceRaisesNotFoundExceptionForIndexGreaterThanSize()
throws Exception {
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
// Insert at zero, OK.
@@ -540,7 +539,7 @@ public class AclImplTests {
// SEC-1151
@Test(expected = NotFoundException.class)
public void deleteAceRaisesNotFoundExceptionForIndexEqualToSize() {
public void deleteAceRaisesNotFoundExceptionForIndexEqualToSize() throws Exception {
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
true, new PrincipalSid("joe"));
acl.insertAce(0, mock(Permission.class), mock(Sid.class), true);
@@ -550,7 +549,7 @@ public class AclImplTests {
// SEC-1795
@Test
public void changingParentIsSuccessful() {
public void changingParentIsSuccessful() throws Exception {
AclImpl parentAcl = new AclImpl(objectIdentity, 1L, authzStrategy,
mockAuditLogger);
AclImpl childAcl = new AclImpl(objectIdentity, 2L, authzStrategy, mockAuditLogger);
@@ -561,58 +560,9 @@ public class AclImplTests {
childAcl.setParent(changeParentAcl);
}
// SEC-2342
@Test
public void maskPermissionGrantingStrategy() {
DefaultPermissionGrantingStrategy maskPgs = new MaskPermissionGrantingStrategy(mockAuditLogger);
MockAclService service = new MockAclService();
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, maskPgs, null, null,
true, new PrincipalSid("joe"));
Permission permission = permissionFactory.buildFromMask(BasePermission.READ.getMask() | BasePermission.WRITE.getMask());
Sid sid = new PrincipalSid("ben");
acl.insertAce(0, permission, sid, true);
service.updateAcl(acl);
List<Permission> permissions = Arrays.asList(BasePermission.READ);
List<Sid> sids = Arrays.asList(sid);
assertThat(acl.isGranted(permissions, sids, false)).isTrue();
}
@Test
public void hashCodeWithoutStackOverFlow() throws Exception {
//given
Sid sid = new PrincipalSid("pSid");
ObjectIdentity oid = new ObjectIdentityImpl("type", 1);
AclAuthorizationStrategy authStrategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("role"));
PermissionGrantingStrategy grantingStrategy = new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
AclImpl acl = new AclImpl(oid, 1L, authStrategy, grantingStrategy, null, null, false, sid);
AccessControlEntryImpl ace = new AccessControlEntryImpl(1L, acl, sid, BasePermission.READ, true, true, true);
Field fieldAces = FieldUtils.getField(AclImpl.class, "aces");
fieldAces.setAccessible(true);
List<AccessControlEntryImpl> aces = (List<AccessControlEntryImpl>) fieldAces.get(acl);
aces.add(ace);
//when - then none StackOverFlowError been raised
ace.hashCode();
}
// ~ Inner Classes
// ==================================================================================================
private static class MaskPermissionGrantingStrategy extends DefaultPermissionGrantingStrategy {
MaskPermissionGrantingStrategy(AuditLogger auditLogger) {
super(auditLogger);
}
@Override
protected boolean isGranted(AccessControlEntry ace, Permission p) {
if (p.getMask() != 0) {
return (p.getMask() & ace.getPermission().getMask()) != 0;
}
return super.isGranted(ace, p);
}
}
private class MockAclService implements MutableAclService {
public MutableAcl createAcl(ObjectIdentity objectIdentity)
throws AlreadyExistsException {
@@ -41,28 +41,28 @@ public class AclImplementationSecurityCheckTests {
// ========================================================================================================
@Before
public void setUp() {
public void setUp() throws Exception {
SecurityContextHolder.clearContext();
}
@After
public void tearDown() {
public void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
@Test
public void testSecurityCheckNoACEs() {
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, 100L);
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, 1L, aclAuthorizationStrategy,
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
new ConsoleAuditLogger());
aclAuthorizationStrategy.securityCheck(acl,
@@ -76,7 +76,7 @@ public class AclImplementationSecurityCheckTests {
AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority(
"ROLE_TWO"), new SimpleGrantedAuthority("ROLE_THREE"));
Acl acl2 = new AclImpl(identity, 1L, aclAuthorizationStrategy2,
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2,
new ConsoleAuditLogger());
// Check access in case the principal has no authorization rights
try {
@@ -103,14 +103,14 @@ public class AclImplementationSecurityCheckTests {
}
@Test
public void testSecurityCheckWithMultipleACEs() {
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, 100L);
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(
@@ -118,7 +118,7 @@ public class AclImplementationSecurityCheckTests {
// Let's give the principal the ADMINISTRATION permission, without
// granting access
MutableAcl aclFirstDeny = new AclImpl(identity, 1L,
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1),
aclAuthorizationStrategy, new ConsoleAuditLogger());
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
false);
@@ -160,7 +160,7 @@ public class AclImplementationSecurityCheckTests {
// Create another ACL and give the principal the ADMINISTRATION
// permission, with granting access
MutableAcl aclFirstAllow = new AclImpl(identity, 1L,
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1),
aclAuthorizationStrategy, new ConsoleAuditLogger());
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
true);
@@ -184,7 +184,7 @@ public class AclImplementationSecurityCheckTests {
}
// Create an ACL with no ACE
MutableAcl aclNoACE = new AclImpl(identity, 1L,
MutableAcl aclNoACE = new AclImpl(identity, new Long(1),
aclAuthorizationStrategy, new ConsoleAuditLogger());
try {
aclAuthorizationStrategy.securityCheck(aclNoACE,
@@ -206,7 +206,7 @@ public class AclImplementationSecurityCheckTests {
}
@Test
public void testSecurityCheckWithInheritableACEs() {
public void testSecurityCheckWithInheritableACEs() throws Exception {
// Create a simple authentication with ROLE_GENERAL
Authentication auth = new TestingAuthenticationToken("user", "password",
"ROLE_GENERAL");
@@ -273,7 +273,7 @@ public class AclImplementationSecurityCheckTests {
}
@Test
public void testSecurityCheckPrincipalOwner() {
public void testSecurityCheckPrincipalOwner() throws Exception {
Authentication auth = new TestingAuthenticationToken("user", "password",
"ROLE_ONE");
auth.setAuthenticated(true);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2016 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.
@@ -44,7 +44,7 @@ public class AuditLoggerTests {
// ========================================================================================================
@Before
public void setUp() {
public void setUp() throws Exception {
logger = new ConsoleAuditLogger();
ace = mock(AuditableAccessControlEntry.class);
console = System.out;
@@ -52,7 +52,7 @@ public class AuditLoggerTests {
}
@After
public void tearDown() {
public void tearDown() throws Exception {
System.setOut(console);
bytes.reset();
}
@@ -61,35 +61,35 @@ public class AuditLoggerTests {
public void nonAuditableAceIsIgnored() {
AccessControlEntry ace = mock(AccessControlEntry.class);
logger.logIfNeeded(true, ace);
assertThat(bytes.size()).isZero();
assertThat(bytes.size()).isEqualTo(0);
}
@Test
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() {
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
when(ace.isAuditSuccess()).thenReturn(false);
logger.logIfNeeded(true, ace);
assertThat(bytes.size()).isZero();
assertThat(bytes.size()).isEqualTo(0);
}
@Test
public void successIsLoggedIfAceRequiresSuccessAudit() {
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
when(ace.isAuditSuccess()).thenReturn(true);
logger.logIfNeeded(true, ace);
assertThat(bytes.toString()).startsWith("GRANTED due to ACE");
assertThat(bytes.toString().startsWith("GRANTED due to ACE")).isTrue();
}
@Test
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() {
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
when(ace.isAuditFailure()).thenReturn(false);
logger.logIfNeeded(false, ace);
assertThat(bytes.size()).isZero();
assertThat(bytes.size()).isEqualTo(0);
}
@Test
public void failureIsLoggedIfAceRequiresFailureAudit() {
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
when(ace.isAuditFailure()).thenReturn(true);
logger.logIfNeeded(false, ace);
assertThat(bytes.toString()).startsWith("DENIED due to ACE");
assertThat(bytes.toString().startsWith("DENIED due to ACE")).isTrue();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2016 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.
@@ -36,7 +36,7 @@ public class ObjectIdentityImplTests {
// ========================================================================================================
@Test
public void constructorsRespectRequiredFields() {
public void constructorsRespectRequiredFields() throws Exception {
// Check one-argument constructor required field
try {
new ObjectIdentityImpl(null);
@@ -47,7 +47,7 @@ public class ObjectIdentityImplTests {
// Check String-Serializable constructor required field
try {
new ObjectIdentityImpl("", 1L);
new ObjectIdentityImpl("", Long.valueOf(1));
fail("It should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
@@ -63,7 +63,7 @@ public class ObjectIdentityImplTests {
// The correct way of using String-Serializable constructor
try {
new ObjectIdentityImpl(DOMAIN_CLASS, 1L);
new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
}
catch (IllegalArgumentException notExpected) {
fail("It shouldn't have thrown IllegalArgumentException");
@@ -79,14 +79,14 @@ public class ObjectIdentityImplTests {
}
@Test
public void gettersReturnExpectedValues() {
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, 1L);
assertThat(obj.getIdentifier()).isEqualTo(1L);
public void gettersReturnExpectedValues() throws Exception {
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
assertThat(obj.getIdentifier()).isEqualTo(Long.valueOf(1));
assertThat(obj.getType()).isEqualTo(MockIdDomainObject.class.getName());
}
@Test
public void testGetIdMethodConstraints() {
public void testGetIdMethodConstraints() throws Exception {
// Check the getId() method is present
try {
new ObjectIdentityImpl("A_STRING_OBJECT");
@@ -116,7 +116,7 @@ public class ObjectIdentityImplTests {
}
// getId() should return a Serializable object
mockId.setId(100L);
mockId.setId(new Long(100));
try {
new ObjectIdentityImpl(mockId);
}
@@ -125,46 +125,46 @@ public class ObjectIdentityImplTests {
}
@Test(expected = IllegalArgumentException.class)
public void constructorRejectsInvalidTypeParameter() {
new ObjectIdentityImpl("", 1L);
public void constructorRejectsInvalidTypeParameter() throws Exception {
new ObjectIdentityImpl("", Long.valueOf(1));
}
@Test
public void testEquals() {
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, 1L);
public void testEquals() throws Exception {
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
MockIdDomainObject mockObj = new MockIdDomainObject();
mockObj.setId(1L);
mockObj.setId(Long.valueOf(1));
String string = "SOME_STRING";
assertThat(string).isNotSameAs(obj);
assertThat(obj).isNotNull();
assertThat(obj).isNotEqualTo("DIFFERENT_OBJECT_TYPE");
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(DOMAIN_CLASS, 2L));
assertThat(obj.equals(null)).isFalse();
assertThat(obj.equals("DIFFERENT_OBJECT_TYPE")).isFalse();
assertThat(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2)))).isFalse();
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
1L));
Long.valueOf(1)));
assertThat(new ObjectIdentityImpl(DOMAIN_CLASS, 1L)).isEqualTo(obj);
assertThat(new ObjectIdentityImpl(mockObj)).isEqualTo(obj);
}
@Test
public void hashcodeIsDifferentForDifferentJavaTypes() {
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, 1L);
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, 1L);
assertThat(obj.hashCode()).isNotEqualTo(obj2.hashCode());
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
assertThat(obj.hashCode() == obj2.hashCode()).isFalse();
}
@Test
public void longAndIntegerIdsWithSameValueAreEqualAndHaveSameHashcode() {
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, 5L);
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, 5);
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, new Long(5));
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Integer.valueOf(5));
assertThat(obj2).isEqualTo(obj);
assertThat(obj2.hashCode()).isEqualTo(obj.hashCode());
}
@Test
public void equalStringIdsAreEqualAndHaveSameHashcode() {
public void equalStringIdsAreEqualAndHaveSameHashcode() throws Exception {
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, "1000");
assertThat(obj2).isEqualTo(obj);
@@ -172,10 +172,10 @@ public class ObjectIdentityImplTests {
}
@Test
public void stringAndNumericIdsAreNotEqual() {
public void stringAndNumericIdsAreNotEqual() throws Exception {
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, 1000L);
assertThat(obj).isNotEqualTo(obj2);
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
assertThat(obj.equals(obj2)).isFalse();
}
// ~ Inner Classes
@@ -31,9 +31,9 @@ public class ObjectIdentityRetrievalStrategyImplTests {
// ~ Methods
// ========================================================================================================
@Test
public void testObjectIdentityCreation() {
public void testObjectIdentityCreation() throws Exception {
MockIdDomainObject domain = new MockIdDomainObject();
domain.setId(1);
domain.setId(Integer.valueOf(1));
ObjectIdentityRetrievalStrategy retStrategy = new ObjectIdentityRetrievalStrategyImpl();
ObjectIdentity identity = retStrategy.getObjectIdentity(domain);
@@ -1,341 +0,0 @@
/*
* Copyright 2002-2017 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
*
* https://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.jdbc;
import static org.assertj.core.api.Assertions.*;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import org.junit.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.acls.TargetObject;
import org.springframework.security.acls.TargetObjectWithUUID;
import org.springframework.security.acls.domain.*;
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 java.util.*;
import javax.sql.DataSource;
/**
* Tests {@link BasicLookupStrategy}
*
* @author Andrei Stefan
*/
public abstract class AbstractBasicLookupStrategyTests {
protected static final Sid BEN_SID = new PrincipalSid("ben");
protected static final String TARGET_CLASS = TargetObject.class.getName();
protected static final String TARGET_CLASS_WITH_UUID = TargetObjectWithUUID.class.getName();
protected static final UUID OBJECT_IDENTITY_UUID = UUID.randomUUID();
protected static final Long OBJECT_IDENTITY_LONG_AS_UUID = 110L;
// ~ Instance fields
// ================================================================================================
private BasicLookupStrategy strategy;
private static CacheManager cacheManager;
// ~ Methods
// ========================================================================================================
public abstract JdbcTemplate getJdbcTemplate();
public abstract DataSource getDataSource();
@BeforeClass
public static void initCacheManaer() {
cacheManager = CacheManager.create();
cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30));
}
@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);";
getJdbcTemplate().execute(query);
}
@Before
public void initializeBeans() {
strategy = new BasicLookupStrategy(getDataSource(), aclCache(), aclAuthStrategy(),
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()));
strategy.setPermissionFactory(new DefaultPermissionFactory());
}
protected AclAuthorizationStrategy aclAuthStrategy() {
return new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"));
}
protected EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(getCache(),
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")));
}
@After
public void emptyDatabase() {
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 9;"
+ "DELETE FROM acl_object_identity WHERE ID = 8;" + "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;";
getJdbcTemplate().execute(query);
}
protected Ehcache getCache() {
Ehcache cache = cacheManager.getCache("basiclookuptestcache");
cache.removeAll();
return cache;
}
@Test
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101L);
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 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, 100);
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101L);
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 102L);
// 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, 100L);
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101);
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 102L);
// 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) {
assertThat(map).hasSize(3);
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
MutableAcl child = (MutableAcl) map.get(childOid);
// Check the retrieved versions has IDs
assertThat(topParent.getId()).isNotNull();
assertThat(middleParent.getId()).isNotNull();
assertThat(child.getId()).isNotNull();
// Check their parents were correctly retrieved
assertThat(topParent.getParentAcl()).isNull();
assertThat(middleParent.getParentAcl().getObjectIdentity()).isEqualTo(topParentOid);
assertThat(child.getParentAcl().getObjectIdentity()).isEqualTo(middleParentOid);
// Check their ACEs were correctly retrieved
assertThat(topParent.getEntries()).hasSize(2);
assertThat(middleParent.getEntries()).hasSize(1);
assertThat(child.getEntries()).hasSize(1);
// Check object identities were correctly retrieved
assertThat(topParent.getObjectIdentity()).isEqualTo(topParentOid);
assertThat(middleParent.getObjectIdentity()).isEqualTo(middleParentOid);
assertThat(child.getObjectIdentity()).isEqualTo(childOid);
// Check each entry
assertThat(topParent.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(1)).isEqualTo(topParent.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(topParent.getOwner());
assertThat(Long.valueOf(1)).isEqualTo(topParent.getEntries().get(0).getId());
assertThat(topParent.getEntries().get(0).getPermission()).isEqualTo(BasePermission.READ);
assertThat(topParent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat((topParent.getEntries().get(0)).isGranting()).isTrue();
assertThat(Long.valueOf(2)).isEqualTo(topParent.getEntries().get(1).getId());
assertThat(topParent.getEntries().get(1).getPermission()).isEqualTo(BasePermission.WRITE);
assertThat(topParent.getEntries().get(1).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess()).isFalse();
assertThat(topParent.getEntries().get(1).isGranting()).isFalse();
assertThat(middleParent.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(2)).isEqualTo(middleParent.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(middleParent.getOwner());
assertThat(Long.valueOf(3)).isEqualTo(middleParent.getEntries().get(0).getId());
assertThat(middleParent.getEntries().get(0).getPermission()).isEqualTo(BasePermission.DELETE);
assertThat(middleParent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat(middleParent.getEntries().get(0).isGranting()).isTrue();
assertThat(child.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(3)).isEqualTo(child.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(child.getOwner());
assertThat(Long.valueOf(4)).isEqualTo(child.getEntries().get(0).getId());
assertThat(child.getEntries().get(0).getPermission()).isEqualTo(BasePermission.DELETE);
assertThat(new PrincipalSid("ben")).isEqualTo(child.getEntries().get(0).getSid());
assertThat(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat((child.getEntries().get(0)).isGranting()).isFalse();
}
@Test
public void testAllParentsAreRetrievedWhenChildIsLoaded() {
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,103,1,1,1);";
getJdbcTemplate().execute(query);
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101L);
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 102L);
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl(TARGET_CLASS, 103L);
// Retrieve the child
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(childOid), null);
// Check that the child and all its parents were retrieved
assertThat(map.get(childOid)).isNotNull();
assertThat(map.get(childOid).getObjectIdentity()).isEqualTo(childOid);
assertThat(map.get(middleParentOid)).isNotNull();
assertThat(map.get(middleParentOid).getObjectIdentity()).isEqualTo(middleParentOid);
assertThat(map.get(topParentOid)).isNotNull();
assertThat(map.get(topParentOid).getObjectIdentity()).isEqualTo(topParentOid);
// The second parent shouldn't have been retrieved
assertThat(map.get(middleParent2Oid)).isNull();
}
/**
* Test created from SEC-590.
*/
@Test
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() {
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,105,null,1,1);"
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (7,2,106,6,1,1);"
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (8,2,107,6,1,1);"
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (9,2,108,7,1,1);"
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (7,6,0,1,1,1,0,0)";
getJdbcTemplate().execute(query);
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, 104L);
ObjectIdentity parent1Oid = new ObjectIdentityImpl(TARGET_CLASS, 105L);
ObjectIdentity parent2Oid = new ObjectIdentityImpl(TARGET_CLASS, 106);
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 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);
assertThat(foundChildAcl).isNotNull();
assertThat(foundChildAcl.isGranted(checkPermission, sids, false)).isTrue();
// 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);
} catch (NotFoundException notExpected) {
fail("It shouldn't have thrown NotFoundException");
}
Acl foundParent2Acl = foundAcls.get(parent2Oid);
assertThat(foundParent2Acl).isNotNull();
assertThat(foundParent2Acl.isGranted(checkPermission, sids, false)).isTrue();
}
@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 (6,2,104,null,null,1);";
getJdbcTemplate().execute(query);
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 104L);
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
}
@Test
public void testCreatePrincipalSid() {
Sid result = strategy.createSid(true, "sid");
assertThat(result.getClass()).isEqualTo(PrincipalSid.class);
assertThat(((PrincipalSid) result).getPrincipal()).isEqualTo("sid");
}
@Test
public void testCreateGrantedAuthority() {
Sid result = strategy.createSid(false, "sid");
assertThat(result.getClass()).isEqualTo(GrantedAuthoritySid.class);
assertThat(((GrantedAuthoritySid) result).getGrantedAuthority()).isEqualTo("sid");
}
}
@@ -1,175 +0,0 @@
/*
* Copyright 2002-2018 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
*
* https://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.jdbc;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.convert.ConversionService;
import java.io.Serializable;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Tests for {@link AclClassIdUtils}.
* @author paulwheeler
*/
@RunWith(MockitoJUnitRunner.class)
public class AclClassIdUtilsTest {
private static final Long DEFAULT_IDENTIFIER = 999L;
private static final BigInteger BIGINT_IDENTIFIER = new BigInteger("999");
private static final String DEFAULT_IDENTIFIER_AS_STRING = DEFAULT_IDENTIFIER.toString();
@Mock
private ResultSet resultSet;
@Mock
private ConversionService conversionService;
private AclClassIdUtils aclClassIdUtils;
@Before
public void setUp() {
aclClassIdUtils = new AclClassIdUtils();
}
@Test
public void shouldReturnLongIfIdentifierIsLong() throws SQLException {
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongIfIdentifierIsBigInteger() throws SQLException {
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(BIGINT_IDENTIFIER, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongIfClassIdTypeIsNull() throws SQLException {
// given
given(resultSet.getString("class_id_type")).willReturn(null);
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongIfNoClassIdTypeColumn() throws SQLException {
// given
given(resultSet.getString("class_id_type")).willThrow(SQLException.class);
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongIfTypeClassNotFound() throws SQLException {
// given
given(resultSet.getString("class_id_type")).willReturn("com.example.UnknownType");
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongEvenIfCustomConversionServiceDoesNotSupportLongConversion() throws SQLException {
// given
given(resultSet.getString("class_id_type")).willReturn("java.lang.Long");
given(conversionService.canConvert(String.class, Long.class)).willReturn(false);
aclClassIdUtils.setConversionService(conversionService);
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnLongWhenLongClassIdType() throws SQLException {
// given
given(resultSet.getString("class_id_type")).willReturn("java.lang.Long");
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
// then
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
}
@Test
public void shouldReturnUUIDWhenUUIDClassIdType() throws SQLException {
// given
UUID identifier = UUID.randomUUID();
given(resultSet.getString("class_id_type")).willReturn("java.util.UUID");
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(identifier.toString(), resultSet);
// then
assertThat(newIdentifier).isEqualTo(identifier);
}
@Test
public void shouldReturnStringWhenStringClassIdType() throws SQLException {
// given
String identifier = "MY_STRING_IDENTIFIER";
given(resultSet.getString("class_id_type")).willReturn("java.lang.String");
// when
Serializable newIdentifier = aclClassIdUtils.identifierFrom(identifier, resultSet);
// then
assertThat(newIdentifier).isEqualTo(identifier);
}
@Test(expected = IllegalArgumentException.class)
public void shouldNotAcceptNullConversionServiceInConstruction() {
// when
new AclClassIdUtils(null);
}
@Test(expected = IllegalArgumentException.class)
public void shouldNotAcceptNullConversionServiceInSetter() {
// when
aclClassIdUtils.setConversionService(null);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2016 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.
@@ -15,39 +15,330 @@
*/
package org.springframework.security.acls.jdbc;
import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
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.*;
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} with Acl Class type id not specified.
* Tests {@link BasicLookupStrategy}
*
* @author Andrei Stefan
* @author Paul Wheeler
*/
public class BasicLookupStrategyTests extends AbstractBasicLookupStrategyTests {
private static final BasicLookupStrategyTestsDbHelper DATABASE_HELPER = new BasicLookupStrategyTestsDbHelper();
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 {
DATABASE_HELPER.createDatabase();
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() {
DATABASE_HELPER.getDataSource().destroy();
public static void dropDatabase() throws Exception {
dataSource.destroy();
}
@Override
public JdbcTemplate getJdbcTemplate() {
return DATABASE_HELPER.getJdbcTemplate();
@AfterClass
public static void shutdownCacheManager() {
cacheManager.removalAll();
cacheManager.shutdown();
}
@Override
public DataSource getDataSource() {
return DATABASE_HELPER.getDataSource();
@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(),
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")));
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 {
assertThat(map).hasSize(3);
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
MutableAcl child = (MutableAcl) map.get(childOid);
// Check the retrieved versions has IDs
assertThat(topParent.getId()).isNotNull();
assertThat(middleParent.getId()).isNotNull();
assertThat(child.getId()).isNotNull();
// Check their parents were correctly retrieved
assertThat(topParent.getParentAcl()).isNull();
assertThat(middleParent.getParentAcl().getObjectIdentity()).isEqualTo(topParentOid);
assertThat(child.getParentAcl().getObjectIdentity()).isEqualTo(middleParentOid);
// Check their ACEs were correctly retrieved
assertThat(topParent.getEntries()).hasSize(2);
assertThat(middleParent.getEntries()).hasSize(1);
assertThat(child.getEntries()).hasSize(1);
// Check object identities were correctly retrieved
assertThat(topParent.getObjectIdentity()).isEqualTo(topParentOid);
assertThat(middleParent.getObjectIdentity()).isEqualTo(middleParentOid);
assertThat(child.getObjectIdentity()).isEqualTo(childOid);
// Check each entry
assertThat(topParent.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(1)).isEqualTo(topParent.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(topParent.getOwner());
assertThat(Long.valueOf(1)).isEqualTo(topParent.getEntries().get(0).getId());
assertThat(topParent.getEntries().get(0).getPermission()).isEqualTo(BasePermission.READ);
assertThat(topParent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat((topParent.getEntries().get(0)).isGranting()).isTrue();
assertThat(Long.valueOf(2)).isEqualTo(topParent.getEntries().get(1).getId());
assertThat(topParent.getEntries().get(1).getPermission()).isEqualTo(BasePermission.WRITE);
assertThat(topParent.getEntries().get(1).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess()).isFalse();
assertThat(topParent.getEntries().get(1).isGranting()).isFalse();
assertThat(middleParent.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(2)).isEqualTo(middleParent.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(middleParent.getOwner());
assertThat(Long.valueOf(3)).isEqualTo(middleParent.getEntries().get(0).getId());
assertThat(middleParent.getEntries().get(0).getPermission()).isEqualTo(BasePermission.DELETE);
assertThat(middleParent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
assertThat(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat(middleParent.getEntries().get(0).isGranting()).isTrue();
assertThat(child.isEntriesInheriting()).isTrue();
assertThat(Long.valueOf(3)).isEqualTo(child.getId());
assertThat(new PrincipalSid("ben")).isEqualTo(child.getOwner());
assertThat(Long.valueOf(4)).isEqualTo(child.getEntries().get(0).getId());
assertThat(child.getEntries().get(0).getPermission()).isEqualTo(BasePermission.DELETE);
assertThat(new PrincipalSid("ben")).isEqualTo(child.getEntries().get(0).getSid());
assertThat(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure()).isFalse();
assertThat(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess()).isFalse();
assertThat((child.getEntries().get(0)).isGranting()).isFalse();
}
@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
assertThat(map.get(childOid)).isNotNull();
assertThat(map.get(childOid).getObjectIdentity()).isEqualTo(childOid);
assertThat(map.get(middleParentOid)).isNotNull();
assertThat(map.get(middleParentOid).getObjectIdentity()).isEqualTo(middleParentOid);
assertThat(map.get(topParentOid)).isNotNull();
assertThat(map.get(topParentOid).getObjectIdentity()).isEqualTo(topParentOid);
// The second parent shouldn't have been retrieved
assertThat(map.get(middleParent2Oid)).isNull();
}
/**
* 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);
assertThat(foundChildAcl).isNotNull();
assertThat(foundChildAcl.isGranted(checkPermission, sids, false)).isTrue();
// 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);
} catch (NotFoundException notExpected) {
fail("It shouldn't have thrown NotFoundException");
}
Acl foundParent2Acl = foundAcls.get(parent2Oid);
assertThat(foundParent2Acl).isNotNull();
assertThat(foundParent2Acl.isGranted(checkPermission, sids, false)).isTrue();
}
@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));
}
@Test
public void testCreatePrincipalSid() {
Sid result = strategy.createSid(true, "sid");
assertThat(result.getClass()).isEqualTo(PrincipalSid.class);
assertThat(((PrincipalSid) result).getPrincipal()).isEqualTo("sid");
}
@Test
public void testCreateGrantedAuthority() {
Sid result = strategy.createSid(false, "sid");
assertThat(result.getClass()).isEqualTo(GrantedAuthoritySid.class);
assertThat(((GrantedAuthoritySid) result).getGrantedAuthority()).isEqualTo("sid");
}
}
@@ -1,72 +0,0 @@
/*
* Copyright 2002-2017 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
*
* https://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.jdbc;
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.util.FileCopyUtils;
/**
* Helper class to initialize the database for BasicLookupStrategyTests.
* @author Andrei Stefan
* @author Paul Wheeler
*/
public class BasicLookupStrategyTestsDbHelper {
private static final String ACL_SCHEMA_SQL_FILE = "createAclSchema.sql";
private static final String ACL_SCHEMA_SQL_FILE_WITH_ACL_CLASS_ID = "createAclSchemaWithAclClassIdType.sql";
private SingleConnectionDataSource dataSource;
private JdbcTemplate jdbcTemplate;
private boolean withAclClassIdType;
public BasicLookupStrategyTestsDbHelper() {
}
public BasicLookupStrategyTestsDbHelper(boolean withAclClassIdType) {
this.withAclClassIdType = withAclClassIdType;
}
public void createDatabase() throws Exception {
// Use a different connection url so the tests can run in parallel
String connectionUrl;
String sqlClassPathResource;
if (!withAclClassIdType) {
connectionUrl = "jdbc:hsqldb:mem:lookupstrategytest";
sqlClassPathResource = ACL_SCHEMA_SQL_FILE;
} else {
connectionUrl = "jdbc:hsqldb:mem:lookupstrategytestWithAclClassIdType";
sqlClassPathResource = ACL_SCHEMA_SQL_FILE_WITH_ACL_CLASS_ID;
}
dataSource = new SingleConnectionDataSource(connectionUrl, "sa", "", true);
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
jdbcTemplate = new JdbcTemplate(dataSource);
Resource resource = new ClassPathResource(sqlClassPathResource);
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
jdbcTemplate.execute(sql);
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public SingleConnectionDataSource getDataSource() {
return dataSource;
}
}
@@ -1,115 +0,0 @@
/*
* Copyright 2002-2017 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
*
* https://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.jdbc;
import java.util.Arrays;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.jdbc.core.JdbcTemplate;
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.ObjectIdentityImpl;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.ObjectIdentity;
import junit.framework.Assert;
/**
* Tests {@link BasicLookupStrategy} with Acl Class type id set to UUID.
*
* @author Paul Wheeler
*/
public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLookupStrategyTests {
private static final BasicLookupStrategyTestsDbHelper DATABASE_HELPER = new BasicLookupStrategyTestsDbHelper(true);
private BasicLookupStrategy uuidEnabledStrategy;
@Override
public JdbcTemplate getJdbcTemplate() {
return DATABASE_HELPER.getJdbcTemplate();
}
@Override
public DataSource getDataSource() {
return DATABASE_HELPER.getDataSource();
}
@BeforeClass
public static void createDatabase() throws Exception {
DATABASE_HELPER.createDatabase();
}
@AfterClass
public static void dropDatabase() {
DATABASE_HELPER.getDataSource().destroy();
}
@Before
public void initializeBeans() {
super.initializeBeans();
uuidEnabledStrategy = new BasicLookupStrategy(getDataSource(), aclCache(), aclAuthStrategy(),
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()));
uuidEnabledStrategy.setPermissionFactory(new DefaultPermissionFactory());
uuidEnabledStrategy.setAclClassIdSupported(true);
uuidEnabledStrategy.setConversionService(new DefaultConversionService());
}
@Before
public void populateDatabaseForAclClassTypeTests() {
String query = "INSERT INTO acl_class(ID,CLASS,CLASS_ID_TYPE) VALUES (3,'"
+ TARGET_CLASS_WITH_UUID
+ "', 'java.util.UUID');"
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,3,'"
+ OBJECT_IDENTITY_UUID.toString() + "',null,1,1);"
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (5,3,'"
+ OBJECT_IDENTITY_LONG_AS_UUID + "',null,1,1);"
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,8,0,0,0);"
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (6,5,0,1,8,0,0,0);";
DATABASE_HELPER.getJdbcTemplate().execute(query);
}
@Test
public void testReadObjectIdentityUsingUuidType() {
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, OBJECT_IDENTITY_UUID);
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
Assert.assertEquals(1, foundAcls.size());
Assert.assertNotNull(foundAcls.get(oid));
}
@Test
public void testReadObjectIdentityUsingLongTypeWithConversionServiceEnabled() {
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
Assert.assertEquals(1, foundAcls.size());
Assert.assertNotNull(foundAcls.get(oid));
}
@Test(expected = ConversionFailedException.class)
public void testReadObjectIdentityUsingNonUuidInDatabase() {
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, OBJECT_IDENTITY_LONG_AS_UUID);
uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
}
}
@@ -36,7 +36,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.security.acls.domain.*;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.ObjectIdentity;
@@ -71,12 +71,12 @@ public class EhCacheBasedAclCacheTests {
new ConsoleAuditLogger()), new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_USER")));
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
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, 1L, aclAuthorizationStrategy,
acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy,
new ConsoleAuditLogger());
}
@@ -86,14 +86,14 @@ public class EhCacheBasedAclCacheTests {
}
@Test(expected = IllegalArgumentException.class)
public void constructorRejectsNullParameters() {
public void constructorRejectsNullParameters() throws Exception {
new EhCacheBasedAclCache(null, new DefaultPermissionGrantingStrategy(
new ConsoleAuditLogger()), new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_USER")));
}
@Test
public void methodsRejectNullParameters() {
public void methodsRejectNullParameters() throws Exception {
try {
Serializable id = null;
myCache.evictFromCache(id);
@@ -154,22 +154,22 @@ public class EhCacheBasedAclCacheTests {
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy",
retrieved);
assertThat(retrieved1).isNull();
assertThat(retrieved1).isEqualTo(null);
Object retrieved2 = FieldUtils.getProtectedFieldValue(
"permissionGrantingStrategy", retrieved);
assertThat(retrieved2).isNull();
assertThat(retrieved2).isEqualTo(null);
}
@Test
public void clearCache() {
public void clearCache() throws Exception {
myCache.clearCache();
verify(cache).removeAll();
}
@Test
public void putInCache() {
public void putInCache() throws Exception {
myCache.putInCache(acl);
verify(cache, times(2)).put(element.capture());
@@ -181,18 +181,18 @@ public class EhCacheBasedAclCacheTests {
}
@Test
public void putInCacheAclWithParent() {
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,
2L);
Long.valueOf(2));
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
MutableAcl parentAcl = new AclImpl(identityParent, 2L,
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2),
aclAuthorizationStrategy, new ConsoleAuditLogger());
acl.setParent(parentAcl);
@@ -216,14 +216,14 @@ public class EhCacheBasedAclCacheTests {
}
@Test
public void getFromCacheSerializable() {
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() {
public void getFromCacheSerializablePopulatesTransient() throws Exception {
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(), acl));
myCache.putInCache(acl);
@@ -240,14 +240,14 @@ public class EhCacheBasedAclCacheTests {
}
@Test
public void getFromCacheObjectIdentity() {
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() {
public void getFromCacheObjectIdentityPopulatesTransient() throws Exception {
when(cache.get(acl.getObjectIdentity()))
.thenReturn(new Element(acl.getId(), acl));
@@ -265,7 +265,7 @@ public class EhCacheBasedAclCacheTests {
}
@Test
public void evictCacheSerializable() {
public void evictCacheSerializable() throws Exception {
when(cache.get(acl.getObjectIdentity()))
.thenReturn(new Element(acl.getId(), acl));
@@ -276,7 +276,7 @@ public class EhCacheBasedAclCacheTests {
}
@Test
public void evictCacheObjectIdentity() {
public void evictCacheObjectIdentity() throws Exception {
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(), acl));
myCache.evictFromCache(acl.getId());
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
@@ -15,16 +15,21 @@
*/
package org.springframework.security.acls.jdbc;
import org.junit.After;
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.junit.MockitoJUnitRunner;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
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;
@@ -32,168 +37,31 @@ import org.springframework.security.acls.model.NotFoundException;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Sid;
import javax.sql.DataSource;
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
/**
* Unit and Integration tests the ACL JdbcAclService using an
* in-memory database.
*
* @author Nena Raab
*/
@RunWith(MockitoJUnitRunner.class)
public class JdbcAclServiceTests {
private EmbeddedDatabase embeddedDatabase;
@Mock
private DataSource dataSource;
@Mock
private LookupStrategy lookupStrategy;
@Mock
JdbcOperations jdbcOperations;
private JdbcAclService aclServiceIntegration;
private JdbcAclService aclService;
@Before
public void setUp() {
aclService = new JdbcAclService(jdbcOperations, lookupStrategy);
aclServiceIntegration = new JdbcAclService(embeddedDatabase, lookupStrategy);
}
@Before
public void setUpEmbeddedDatabase() {
embeddedDatabase = new EmbeddedDatabaseBuilder()//
.addScript("createAclSchemaWithAclClassIdType.sql")
.addScript("db/sql/test_data_hierarchy.sql")
.build();
}
@After
public void tearDownEmbeddedDatabase() {
embeddedDatabase.shutdown();
aclService = new JdbcAclService(dataSource, lookupStrategy);
}
// SEC-1898
@Test(expected = NotFoundException.class)
public void readAclByIdMissingAcl() {
Map<ObjectIdentity, Acl> result = new HashMap<>();
Map<ObjectIdentity, Acl> result = new HashMap<ObjectIdentity, Acl>();
when(
lookupStrategy.readAclsById(anyList(),
anyList())).thenReturn(result);
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"));
List<Sid> sids = Arrays.<Sid> asList(new PrincipalSid("user"));
aclService.readAclById(objectIdentity, sids);
}
@Test
public void findOneChildren() {
List<ObjectIdentity> result = new ArrayList<>();
result.add(new ObjectIdentityImpl(Object.class, "5577"));
Object[] args = {"1", "org.springframework.security.acls.jdbc.JdbcAclServiceTests$MockLongIdDomainObject"};
when(
jdbcOperations.query(anyString(),
aryEq(args), any(RowMapper.class))).thenReturn(result);
ObjectIdentity objectIdentity = new ObjectIdentityImpl(MockLongIdDomainObject.class, 1L);
List<ObjectIdentity> objectIdentities = aclService.findChildren(objectIdentity);
assertThat(objectIdentities.size()).isEqualTo(1);
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo("5577");
}
@Test
public void findNoChildren() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl(MockLongIdDomainObject.class, 1L);
List<ObjectIdentity> objectIdentities = aclService.findChildren(objectIdentity);
assertThat(objectIdentities).isNull();
}
// ~ Some integration tests
// ========================================================================================================
@Test
public void findChildrenWithoutIdType() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl(MockLongIdDomainObject.class, 4711L);
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
assertThat(objectIdentities.size()).isEqualTo(1);
assertThat(objectIdentities.get(0).getType()).isEqualTo(MockUntypedIdDomainObject.class.getName());
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo(5000L);
}
@Test
public void findChildrenForUnknownObject() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl(Object.class, 33);
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
assertThat(objectIdentities).isNull();
}
@Test
public void findChildrenOfIdTypeLong() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl("location", "US-PAL");
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
assertThat(objectIdentities.size()).isEqualTo(2);
assertThat(objectIdentities.get(0).getType()).isEqualTo(MockLongIdDomainObject.class.getName());
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo(4711L);
assertThat(objectIdentities.get(1).getType()).isEqualTo(MockLongIdDomainObject.class.getName());
assertThat(objectIdentities.get(1).getIdentifier()).isEqualTo(4712L);
}
@Test
public void findChildrenOfIdTypeString() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl("location", "US");
aclServiceIntegration.setAclClassIdSupported(true);
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
assertThat(objectIdentities.size()).isEqualTo(1);
assertThat(objectIdentities.get(0).getType()).isEqualTo("location");
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo("US-PAL");
}
@Test
public void findChildrenOfIdTypeUUID() {
ObjectIdentity objectIdentity = new ObjectIdentityImpl(MockUntypedIdDomainObject.class, 5000L);
aclServiceIntegration.setAclClassIdSupported(true);
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
assertThat(objectIdentities.size()).isEqualTo(1);
assertThat(objectIdentities.get(0).getType()).isEqualTo("costcenter");
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
}
private class MockLongIdDomainObject {
private Object id;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
}
private class MockUntypedIdDomainObject {
private Object id;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2004, 2005, 2006, 2017 Acegi Technology Pty Limited
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,11 +78,11 @@ public class JdbcMutableAclServiceTests extends
// ================================================================================================
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS,
100L);
Long.valueOf(100));
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS,
101L);
Long.valueOf(101));
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS,
102L);
Long.valueOf(102));
@Autowired
private JdbcMutableAclService jdbcMutableAclService;
@@ -98,30 +98,10 @@ public class JdbcMutableAclServiceTests extends
// ~ Methods
// ========================================================================================================
protected String getSqlClassPathResource() {
return "createAclSchema.sql";
}
protected ObjectIdentity getTopParentOid() {
return topParentOid;
}
protected ObjectIdentity getMiddleParentOid() {
return middleParentOid;
}
protected ObjectIdentity getChildOid() {
return childOid;
}
protected String getTargetClass() {
return TARGET_CLASS;
}
@BeforeTransaction
public void createTables() throws Exception {
try {
new DatabaseSeeder(dataSource, new ClassPathResource(getSqlClassPathResource()));
new DatabaseSeeder(dataSource, new ClassPathResource("createAclSchema.sql"));
// new DatabaseSeeder(dataSource, new
// ClassPathResource("createAclSchemaPostgres.sql"));
}
@@ -132,7 +112,7 @@ public class JdbcMutableAclServiceTests extends
}
@AfterTransaction
public void clearContextAndData() {
public void clearContextAndData() throws Exception {
SecurityContextHolder.clearContext();
jdbcTemplate.execute("drop table acl_entry");
jdbcTemplate.execute("drop table acl_object_identity");
@@ -146,9 +126,9 @@ public class JdbcMutableAclServiceTests extends
public void testLifecycle() {
SecurityContextHolder.getContext().setAuthentication(auth);
MutableAcl topParent = jdbcMutableAclService.createAcl(getTopParentOid());
MutableAcl middleParent = jdbcMutableAclService.createAcl(getMiddleParentOid());
MutableAcl child = jdbcMutableAclService.createAcl(getChildOid());
MutableAcl topParent = jdbcMutableAclService.createAcl(topParentOid);
MutableAcl middleParent = jdbcMutableAclService.createAcl(middleParentOid);
MutableAcl child = jdbcMutableAclService.createAcl(childOid);
// Specify the inheritance hierarchy
middleParent.setParent(topParent);
@@ -167,13 +147,13 @@ public class JdbcMutableAclServiceTests extends
// Let's check if we can read them back correctly
Map<ObjectIdentity, Acl> map = jdbcMutableAclService.readAclsById(Arrays.asList(
getTopParentOid(), getMiddleParentOid(), getChildOid()));
topParentOid, middleParentOid, childOid));
assertThat(map).hasSize(3);
// Replace our current objects with their retrieved versions
topParent = (MutableAcl) map.get(getTopParentOid());
middleParent = (MutableAcl) map.get(getMiddleParentOid());
child = (MutableAcl) map.get(getChildOid());
topParent = (MutableAcl) map.get(topParentOid);
middleParent = (MutableAcl) map.get(middleParentOid);
child = (MutableAcl) map.get(childOid);
// Check the retrieved versions has IDs
assertThat(topParent.getId()).isNotNull();
@@ -182,8 +162,8 @@ public class JdbcMutableAclServiceTests extends
// Check their parents were correctly persisted
assertThat(topParent.getParentAcl()).isNull();
assertThat(middleParent.getParentAcl().getObjectIdentity()).isEqualTo(getTopParentOid());
assertThat(child.getParentAcl().getObjectIdentity()).isEqualTo(getMiddleParentOid());
assertThat(middleParent.getParentAcl().getObjectIdentity()).isEqualTo(topParentOid);
assertThat(child.getParentAcl().getObjectIdentity()).isEqualTo(middleParentOid);
// Check their ACEs were correctly persisted
assertThat(topParent.getEntries()).hasSize(2);
@@ -217,7 +197,7 @@ public class JdbcMutableAclServiceTests extends
// Next change the child so it doesn't inherit permissions from above
child.setEntriesInheriting(false);
jdbcMutableAclService.updateAcl(child);
child = (MutableAcl) jdbcMutableAclService.readAclById(getChildOid());
child = (MutableAcl) jdbcMutableAclService.readAclById(childOid);
assertThat(child.isEntriesInheriting()).isFalse();
// Check the child permissions no longer inherit
@@ -248,7 +228,7 @@ public class JdbcMutableAclServiceTests extends
// Save the changed child
jdbcMutableAclService.updateAcl(child);
child = (MutableAcl) jdbcMutableAclService.readAclById(getChildOid());
child = (MutableAcl) jdbcMutableAclService.readAclById(childOid);
assertThat(child.getEntries()).hasSize(3);
// Output permissions
@@ -285,45 +265,45 @@ public class JdbcMutableAclServiceTests extends
*/
@Test
@Transactional
public void deleteAclAlsoDeletesChildren() {
public void deleteAclAlsoDeletesChildren() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
jdbcMutableAclService.createAcl(getTopParentOid());
MutableAcl middleParent = jdbcMutableAclService.createAcl(getMiddleParentOid());
MutableAcl child = jdbcMutableAclService.createAcl(getChildOid());
jdbcMutableAclService.createAcl(topParentOid);
MutableAcl middleParent = jdbcMutableAclService.createAcl(middleParentOid);
MutableAcl child = jdbcMutableAclService.createAcl(childOid);
child.setParent(middleParent);
jdbcMutableAclService.updateAcl(middleParent);
jdbcMutableAclService.updateAcl(child);
// Check the childOid really is a child of middleParentOid
Acl childAcl = jdbcMutableAclService.readAclById(getChildOid());
Acl childAcl = jdbcMutableAclService.readAclById(childOid);
assertThat(childAcl.getParentAcl().getObjectIdentity()).isEqualTo(getMiddleParentOid());
assertThat(childAcl.getParentAcl().getObjectIdentity()).isEqualTo(middleParentOid);
// Delete the mid-parent and test if the child was deleted, as well
jdbcMutableAclService.deleteAcl(getMiddleParentOid(), true);
jdbcMutableAclService.deleteAcl(middleParentOid, true);
try {
jdbcMutableAclService.readAclById(getMiddleParentOid());
jdbcMutableAclService.readAclById(middleParentOid);
fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
}
try {
jdbcMutableAclService.readAclById(getChildOid());
jdbcMutableAclService.readAclById(childOid);
fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
}
Acl acl = jdbcMutableAclService.readAclById(getTopParentOid());
Acl acl = jdbcMutableAclService.readAclById(topParentOid);
assertThat(acl).isNotNull();
assertThat(getTopParentOid()).isEqualTo(acl.getObjectIdentity());
assertThat(topParentOid).isEqualTo(((MutableAcl) acl).getObjectIdentity());
}
@Test
public void constructorRejectsNullParameters() {
public void constructorRejectsNullParameters() throws Exception {
try {
new JdbcMutableAclService(null, lookupStrategy, aclCache);
fail("It should have thrown IllegalArgumentException");
@@ -347,7 +327,7 @@ public class JdbcMutableAclServiceTests extends
}
@Test
public void createAclRejectsNullParameter() {
public void createAclRejectsNullParameter() throws Exception {
try {
jdbcMutableAclService.createAcl(null);
fail("It should have thrown IllegalArgumentException");
@@ -358,10 +338,10 @@ public class JdbcMutableAclServiceTests extends
@Test
@Transactional
public void createAclForADuplicateDomainObject() {
public void createAclForADuplicateDomainObject() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity duplicateOid = new ObjectIdentityImpl(TARGET_CLASS,
100L);
Long.valueOf(100));
jdbcMutableAclService.createAcl(duplicateOid);
// Try to add the same object second time
try {
@@ -374,7 +354,7 @@ public class JdbcMutableAclServiceTests extends
@Test
@Transactional
public void deleteAclRejectsNullParameters() {
public void deleteAclRejectsNullParameters() throws Exception {
try {
jdbcMutableAclService.deleteAcl(null, true);
fail("It should have thrown IllegalArgumentException");
@@ -385,10 +365,10 @@ public class JdbcMutableAclServiceTests extends
@Test
@Transactional
public void deleteAclWithChildrenThrowsException() {
public void deleteAclWithChildrenThrowsException() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
MutableAcl parent = jdbcMutableAclService.createAcl(getTopParentOid());
MutableAcl child = jdbcMutableAclService.createAcl(getMiddleParentOid());
MutableAcl parent = jdbcMutableAclService.createAcl(topParentOid);
MutableAcl child = jdbcMutableAclService.createAcl(middleParentOid);
// Specify the inheritance hierarchy
child.setParent(parent);
@@ -398,7 +378,7 @@ public class JdbcMutableAclServiceTests extends
jdbcMutableAclService.setForeignKeysInDatabase(false); // switch on FK
// checking in the
// class, not database
jdbcMutableAclService.deleteAcl(getTopParentOid(), false);
jdbcMutableAclService.deleteAcl(topParentOid, false);
fail("It should have thrown ChildrenExistException");
}
catch (ChildrenExistException expected) {
@@ -411,36 +391,36 @@ public class JdbcMutableAclServiceTests extends
@Test
@Transactional
public void deleteAclRemovesRowsFromDatabase() {
public void deleteAclRemovesRowsFromDatabase() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
MutableAcl child = jdbcMutableAclService.createAcl(getChildOid());
MutableAcl child = jdbcMutableAclService.createAcl(childOid);
child.insertAce(0, BasePermission.DELETE, new PrincipalSid(auth), false);
jdbcMutableAclService.updateAcl(child);
// Remove the child and check all related database rows were removed accordingly
jdbcMutableAclService.deleteAcl(getChildOid(), false);
jdbcMutableAclService.deleteAcl(childOid, false);
assertThat(
jdbcTemplate.queryForList(SELECT_ALL_CLASSES,
new Object[] { getTargetClass() })).hasSize(1);
new Object[] { TARGET_CLASS })).hasSize(1);
assertThat(jdbcTemplate.queryForList("select * from acl_object_identity")
).isEmpty();
assertThat(jdbcTemplate.queryForList("select * from acl_entry")).isEmpty();
// Check the cache
assertThat(aclCache.getFromCache(getChildOid())).isNull();
assertThat(aclCache.getFromCache(102L)).isNull();
assertThat(aclCache.getFromCache(childOid)).isNull();
assertThat(aclCache.getFromCache(Long.valueOf(102))).isNull();
}
/** SEC-1107 */
@Test
@Transactional
public void identityWithIntegerIdIsSupportedByCreateAcl() {
public void identityWithIntegerIdIsSupportedByCreateAcl() throws Exception {
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 101);
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(101));
jdbcMutableAclService.createAcl(oid);
assertThat(jdbcMutableAclService.readAclById(new ObjectIdentityImpl(
TARGET_CLASS, 101L))).isNotNull();
TARGET_CLASS, Long.valueOf(101)))).isNotNull();
}
/**
@@ -448,14 +428,14 @@ public class JdbcMutableAclServiceTests extends
*/
@Test
@Transactional
public void childrenAreClearedFromCacheWhenParentIsUpdated() {
public void childrenAreClearedFromCacheWhenParentIsUpdated() throws Exception {
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
"ROLE_ADMINISTRATOR");
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity parentOid = new ObjectIdentityImpl(TARGET_CLASS, 104L);
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 105L);
ObjectIdentity parentOid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(104));
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(105));
MutableAcl parent = jdbcMutableAclService.createAcl(parentOid);
MutableAcl child = jdbcMutableAclService.createAcl(childOid);
@@ -486,16 +466,16 @@ public class JdbcMutableAclServiceTests extends
*/
@Test
@Transactional
public void childrenAreClearedFromCacheWhenParentisUpdated2() {
public void childrenAreClearedFromCacheWhenParentisUpdated2() throws Exception {
Authentication auth = new TestingAuthenticationToken("system", "secret",
"ROLE_IGNORED");
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentityImpl rootObject = new ObjectIdentityImpl(TARGET_CLASS,
1L);
Long.valueOf(1));
MutableAcl parent = jdbcMutableAclService.createAcl(rootObject);
MutableAcl child = jdbcMutableAclService.createAcl(new ObjectIdentityImpl(
TARGET_CLASS, 2L));
TARGET_CLASS, Long.valueOf(2)));
child.setParent(parent);
jdbcMutableAclService.updateAcl(child);
@@ -507,7 +487,7 @@ public class JdbcMutableAclServiceTests extends
jdbcMutableAclService.updateAcl(parent);
child = (MutableAcl) jdbcMutableAclService.readAclById(new ObjectIdentityImpl(
TARGET_CLASS, 2L));
TARGET_CLASS, Long.valueOf(2)));
parent = (MutableAcl) child.getParentAcl();
@@ -528,7 +508,7 @@ public class JdbcMutableAclServiceTests extends
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS,
110L);
Long.valueOf(110));
MutableAcl topParent = jdbcMutableAclService.createAcl(topParentOid);
// Add an ACE permission entry
@@ -593,11 +573,4 @@ public class JdbcMutableAclServiceTests extends
}
}
protected Authentication getAuth() {
return auth;
}
protected JdbcMutableAclService getJdbcMutableAclService() {
return jdbcMutableAclService;
}
}
@@ -1,83 +0,0 @@
/*
* Copyright 2002-2017 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
*
* https://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.jdbc;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.UUID;
import org.junit.Test;
import org.springframework.security.acls.TargetObjectWithUUID;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;
/**
* Integration tests the ACL system using ACL class id type of UUID and using an in-memory database.
* @author Paul Wheeler
*/
@ContextConfiguration(locations = {"/jdbcMutableAclServiceTestsWithAclClass-context.xml"})
public class JdbcMutableAclServiceTestsWithAclClassId extends JdbcMutableAclServiceTests {
private static final String TARGET_CLASS_WITH_UUID = TargetObjectWithUUID.class.getName();
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
UUID.randomUUID());
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
UUID.randomUUID());
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
UUID.randomUUID());
@Override
protected String getSqlClassPathResource() {
return "createAclSchemaWithAclClassIdType.sql";
}
@Override
protected ObjectIdentity getTopParentOid() {
return topParentOid;
}
@Override
protected ObjectIdentity getMiddleParentOid() {
return middleParentOid;
}
@Override
protected ObjectIdentity getChildOid() {
return childOid;
}
@Override
protected String getTargetClass() {
return TARGET_CLASS_WITH_UUID;
}
@Test
@Transactional
public void identityWithUuidIdIsSupportedByCreateAcl() {
SecurityContextHolder.getContext().setAuthentication(getAuth());
UUID id = UUID.randomUUID();
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, id);
getJdbcMutableAclService().createAcl(oid);
assertThat(getJdbcMutableAclService().readAclById(new ObjectIdentityImpl(
TARGET_CLASS_WITH_UUID, id))).isNotNull();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2016 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.
@@ -65,16 +65,16 @@ public class SpringCacheBasedAclCacheTests {
}
@Test(expected = IllegalArgumentException.class)
public void constructorRejectsNullParameters() {
public void constructorRejectsNullParameters() throws Exception {
new SpringCacheBasedAclCache(null, null, null);
}
@SuppressWarnings("rawtypes")
@Test
public void cacheOperationsAclWithoutParent() {
public void cacheOperationsAclWithoutParent() throws Exception {
Cache cache = getCache();
Map realCache = (Map) cache.getNativeCache();
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
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"));
@@ -84,37 +84,37 @@ public class SpringCacheBasedAclCacheTests {
auditLogger);
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache,
permissionGrantingStrategy, aclAuthorizationStrategy);
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy,
auditLogger);
assertThat(realCache).isEmpty();
myCache.putInCache(acl);
// Check we can get from cache the same objects we put in
assertThat(acl).isEqualTo(myCache.getFromCache(1L));
assertThat(acl).isEqualTo(myCache.getFromCache(Long.valueOf(1)));
assertThat(acl).isEqualTo(myCache.getFromCache(identity));
// Put another object in cache
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, 101L);
MutableAcl acl2 = new AclImpl(identity2, 2L,
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(3L);
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, 102L));
assertThat(realCache).hasSize(4);
myCache.evictFromCache(Long.valueOf(3));
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
assertThat(4).isEqualTo(realCache.size());
myCache.evictFromCache(1L);
assertThat(realCache).hasSize(2);
myCache.evictFromCache(Long.valueOf(1));
assertThat(2).isEqualTo(realCache.size());
// Check the second object inserted
assertThat(acl2).isEqualTo(myCache.getFromCache(2L));
assertThat(acl2).isEqualTo(myCache.getFromCache(Long.valueOf(2)));
assertThat(acl2).isEqualTo(myCache.getFromCache(identity2));
myCache.evictFromCache(identity2);
assertThat(realCache).isEmpty();
assertThat(0).isEqualTo(realCache.size());
}
@SuppressWarnings("rawtypes")
@@ -128,9 +128,9 @@ public class SpringCacheBasedAclCacheTests {
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 1L);
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(1));
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS,
2L);
Long.valueOf(2));
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
@@ -141,9 +141,9 @@ public class SpringCacheBasedAclCacheTests {
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache,
permissionGrantingStrategy, aclAuthorizationStrategy);
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy,
auditLogger);
MutableAcl parentAcl = new AclImpl(identityParent, 2L,
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2),
aclAuthorizationStrategy, auditLogger);
acl.setParent(parentAcl);
@@ -153,7 +153,7 @@ public class SpringCacheBasedAclCacheTests {
assertThat(4).isEqualTo(realCache.size());
// Check we can get from cache the same objects we put in
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(1L);
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(1));
assertThat(aclFromCache).isEqualTo(acl);
// SEC-951 check transient fields are set on parent
assertThat(FieldUtils.getFieldValue(aclFromCache.getParentAcl(),
@@ -162,7 +162,7 @@ public class SpringCacheBasedAclCacheTests {
"permissionGrantingStrategy")).isNotNull();
assertThat(myCache.getFromCache(identity)).isEqualTo(acl);
assertThat(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy")).isNotNull();
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(2L);
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(2));
assertThat(parentAclFromCache).isEqualTo(parentAcl);
assertThat(FieldUtils.getFieldValue(parentAclFromCache,
"aclAuthorizationStrategy")).isNotNull();
@@ -46,7 +46,7 @@ public class SidRetrievalStrategyTests {
// ========================================================================================================
@Test
public void correctSidsAreRetrieved() {
public void correctSidsAreRetrieved() throws Exception {
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
List<Sid> sids = retrStrategy.getSids(authentication);
@@ -66,7 +66,7 @@ public class SidRetrievalStrategyTests {
}
@Test
public void roleHierarchyIsUsedWhenSet() {
public void roleHierarchyIsUsedWhenSet() throws Exception {
RoleHierarchy rh = mock(RoleHierarchy.class);
List rhAuthorities = AuthorityUtils.createAuthorityList("D");
when(rh.getReachableGrantedAuthorities(anyCollection()))
@@ -22,22 +22,17 @@ import org.junit.Test;
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.AbstractAuthenticationToken;
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;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
import java.util.Collections;
public class SidTests {
// ~ Methods
// ========================================================================================================
@Test
public void testPrincipalSidConstructorsRequiredFields() {
public void testPrincipalSidConstructorsRequiredFields() throws Exception {
// Check one String-argument constructor
try {
String string = null;
@@ -82,7 +77,7 @@ public class SidTests {
}
@Test
public void testGrantedAuthoritySidConstructorsRequiredFields() {
public void testGrantedAuthoritySidConstructorsRequiredFields() throws Exception {
// Check one String-argument constructor
try {
String string = null;
@@ -139,7 +134,7 @@ public class SidTests {
}
@Test
public void testPrincipalSidEquals() {
public void testPrincipalSidEquals() throws Exception {
Authentication authentication = new TestingAuthenticationToken("johndoe",
"password");
Sid principalSid = new PrincipalSid(authentication);
@@ -157,7 +152,7 @@ public class SidTests {
}
@Test
public void testGrantedAuthoritySidEquals() {
public void testGrantedAuthoritySidEquals() throws Exception {
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
Sid gaSid = new GrantedAuthoritySid(ga);
@@ -174,7 +169,7 @@ public class SidTests {
}
@Test
public void testPrincipalSidHashCode() {
public void testPrincipalSidHashCode() throws Exception {
Authentication authentication = new TestingAuthenticationToken("johndoe",
"password");
Sid principalSid = new PrincipalSid(authentication);
@@ -189,7 +184,7 @@ public class SidTests {
}
@Test
public void testGrantedAuthoritySidHashCode() {
public void testGrantedAuthoritySidHashCode() throws Exception {
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
Sid gaSid = new GrantedAuthoritySid(ga);
@@ -203,7 +198,7 @@ public class SidTests {
}
@Test
public void testGetters() {
public void testGetters() throws Exception {
Authentication authentication = new TestingAuthenticationToken("johndoe",
"password");
PrincipalSid principalSid = new PrincipalSid(authentication);
@@ -216,65 +211,4 @@ public class SidTests {
assertThat("ROLE_TEST".equals(gaSid.getGrantedAuthority())).isTrue();
assertThat("ROLE_TEST2".equals(gaSid.getGrantedAuthority())).isFalse();
}
@Test
public void getPrincipalWhenPrincipalInstanceOfUserDetailsThenReturnsUsername() {
User user = new User("user", "password", Collections.singletonList(new SimpleGrantedAuthority("ROLE_TEST")));
Authentication authentication = new TestingAuthenticationToken(user, "password");
PrincipalSid principalSid = new PrincipalSid(authentication);
assertThat("user").isEqualTo(principalSid.getPrincipal());
}
@Test
public void getPrincipalWhenPrincipalNotInstanceOfUserDetailsThenReturnsPrincipalName() {
Authentication authentication = new TestingAuthenticationToken("token", "password");
PrincipalSid principalSid = new PrincipalSid(authentication);
assertThat("token").isEqualTo(principalSid.getPrincipal());
}
@Test
public void getPrincipalWhenCustomAuthenticationPrincipalThenReturnsPrincipalName() {
Authentication authentication = new CustomAuthenticationToken(new CustomToken("token"), null);
PrincipalSid principalSid = new PrincipalSid(authentication);
assertThat("token").isEqualTo(principalSid.getPrincipal());
}
static class CustomAuthenticationToken extends AbstractAuthenticationToken {
private CustomToken principal;
CustomAuthenticationToken(CustomToken principal, Collection<GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public CustomToken getPrincipal() {
return this.principal;
}
@Override
public String getName() {
return principal.getName();
}
}
static class CustomToken {
private String name;
CustomToken(String name) {
this.name = name;
}
String getName() {
return name;
}
}
}
@@ -1,17 +0,0 @@
--- insert ACL data
INSERT INTO ACL_SID (ID, PRINCIPAL, SID) VALUES
(10, true, 'user');
INSERT INTO acl_class (id, class, class_id_type) VALUES
(20,'location','java.lang.String'),
(21,'org.springframework.security.acls.jdbc.JdbcAclServiceTests$MockLongIdDomainObject','java.lang.Long'),
(22,'org.springframework.security.acls.jdbc.JdbcAclServiceTests$MockUntypedIdDomainObject',''),
(23,'costcenter','java.util.UUID');
INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES
(1,20,'US',NULL,10,false),
(2,20,'US-PAL',1,10,true),
(3,21,'4711',2,10,true),
(4,21,'4712',2,10,true),
(5,22,'5000',3,10,true),
(6,23,'25d93b3f-c3aa-4814-9d5e-c7c96ced7762',5,10,true);
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://www.springframework.org/dtd/spring-beans.dtd">
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
- Application context containing business beans.
@@ -17,10 +17,7 @@
<constructor-arg>
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<!-- This context is used in two tests so accept existing cache manager as the context will be reused -->
<property name="acceptExisting" value="true"/>
</bean>
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</property>
<property name="cacheName" value="aclCache"/>
</bean>
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="jdbcMutableAclServiceTests-context.xml"/>
<bean id="conversionService" class="org.springframework.core.convert.support.DefaultConversionService"/>
<!-- Overridden bean definitions -->
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
<property name="aclClassIdSupported" value="true"/>
<property name="conversionService" ref="conversionService"/>
</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>
<property name="aclClassIdSupported" value="true"/>
<property name="conversionService" ref="conversionService"/>
</bean>
</beans>
+6 -7
View File
@@ -1,15 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</appender>
<logger name="org.springframework.security" level="${sec.log.level:-WARN}"/>
<logger name="org.springframework.security" level="${sec.log.level}:-WARN"/>
<root level="${root.level:-WARN}">
<root level="${root.level}:-WARN">
<appender-ref ref="STDOUT" />
</root>
</root>
</configuration>
+10
View File
@@ -0,0 +1,10 @@
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"
}
+144
View File
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" 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>4.1.5.RELEASE</version>
<name>spring-security-aspects</name>
<description>spring-security-aspects</description>
<url>https://spring.io/spring-security</url>
<organization>
<name>spring.io</name>
<url>https://spring.io/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>https://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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.14.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<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.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.4</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>1.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
-25
View File
@@ -1,25 +0,0 @@
apply plugin: 'io.spring.convention.spring-module'
apply plugin: 'io.freefair.aspectj'
dependencies {
compile "org.aspectj:aspectjrt"
compile project(':spring-security-core')
compile 'org.springframework:spring-beans'
compile 'org.springframework:spring-context'
compile 'org.springframework:spring-core'
testCompile 'org.springframework:spring-aop'
testAspect sourceSets.main.output
}
sourceSets.main.aspectj.srcDir "src/main/java"
sourceSets.main.java.srcDirs = files()
sourceSets.test.aspectj.srcDir "src/test/java"
sourceSets.test.java.srcDirs = files()
compileAspectj.ajcOptions.outxmlfile = "META-INF/aop.xml"
aspectj {
version = aspectjVersion
}
@@ -72,7 +72,11 @@ public aspect AnnotationSecurityAspect implements InitializingBean {
return proceed();
}
AspectJCallback callback = () -> proceed();
AspectJCallback callback = new AspectJCallback() {
public Object proceedWithObject() {
return proceed();
}
};
return this.securityInterceptor.invoke(thisJoinPoint, callback);
}
@@ -81,7 +85,7 @@ public aspect AnnotationSecurityAspect implements InitializingBean {
this.securityInterceptor = securityInterceptor;
}
public void afterPropertiesSet() {
public void afterPropertiesSet() throws Exception {
if (this.securityInterceptor == null) {
throw new IllegalArgumentException("securityInterceptor required");
}
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!--
AspectJ load-time weaving config file to install common Spring
aspects.
-->
<aspectj>
<!--
<weaver options="-showWeaveInfo"/>
-->
<aspects>
<aspect
name="org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect" />
</aspects>
</aspectj>
@@ -67,7 +67,7 @@ public class AnnotationSecurityAspectTests {
private PrePostSecured prePostSecured = new PrePostSecured();
@Before
public final void setUp() {
public final void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
interceptor = new AspectJMethodSecurityInterceptor();
AccessDecisionVoter[] voters = new AccessDecisionVoter[] {
@@ -90,17 +90,17 @@ public class AnnotationSecurityAspectTests {
}
@Test
public void securedInterfaceMethodAllowsAllAccess() {
public void securedInterfaceMethodAllowsAllAccess() throws Exception {
secured.securedMethod();
}
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void securedClassMethodDeniesUnauthenticatedAccess() {
public void securedClassMethodDeniesUnauthenticatedAccess() throws Exception {
secured.securedClassMethod();
}
@Test
public void securedClassMethodAllowsAccessToRoleA() {
public void securedClassMethodAllowsAccessToRoleA() throws Exception {
SecurityContextHolder.getContext().setAuthentication(anne);
secured.securedClassMethod();
}
@@ -119,28 +119,28 @@ public class AnnotationSecurityAspectTests {
}
@Test(expected = AccessDeniedException.class)
public void protectedMethodIsIntercepted() {
public void protectedMethodIsIntercepted() throws Exception {
SecurityContextHolder.getContext().setAuthentication(anne);
secured.protectedMethod();
}
@Test
public void overriddenProtectedMethodIsNotIntercepted() {
public void overriddenProtectedMethodIsNotIntercepted() throws Exception {
// AspectJ doesn't inherit annotations
securedSub.protectedMethod();
}
// SEC-1262
@Test(expected = AccessDeniedException.class)
public void denyAllPreAuthorizeDeniesAccess() {
public void denyAllPreAuthorizeDeniesAccess() throws Exception {
configureForElAnnotations();
SecurityContextHolder.getContext().setAuthentication(anne);
prePostSecured.denyAllMethod();
}
@Test
public void postFilterIsApplied() {
public void postFilterIsApplied() throws Exception {
configureForElAnnotations();
SecurityContextHolder.getContext().setAuthentication(anne);
List<String> objects = prePostSecured.postFilterMethod();
@@ -206,7 +206,7 @@ class PrePostSecured {
@PostFilter("filterObject.startsWith('a')")
public List<String> postFilterMethod() {
ArrayList<String> objects = new ArrayList<>();
ArrayList<String> objects = new ArrayList<String>();
objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine",
"orange" }));
return objects;
@@ -1,15 +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>
+9
View File
@@ -0,0 +1,9 @@
apply plugin: 'maven-bom'
apply from: "$rootDir/gradle/maven-deployment.gradle"
generatePom.enabled = false
sonarqube.skipProject = true
mavenBom {
projects = coreModuleProjects
}
-11
View File
@@ -1,11 +0,0 @@
apply plugin: 'io.spring.convention.bom'
sonarqube.skipProject = true
project.rootProject.allprojects.each { p ->
p.plugins.withType(io.spring.gradle.convention.SpringMavenPlugin) {
if (!project.name.equals(p.name)) {
project.mavenBom.projects.add(p)
}
}
}
+175 -54
View File
@@ -1,67 +1,188 @@
buildscript {
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module('org.apache.xerces:xercesImpl') with module('xerces:xercesImpl:2.9.1')
substitute module('org.apache.xerces:resolver') with module('xerces:resolver:2.9.1')
repositories {
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
classpath("io.spring.gradle:spring-io-plugin:0.0.4.RELEASE")
classpath("com.bmuschko:gradle-tomcat-plugin:2.2.4")
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
classpath('org.asciidoctor:asciidoctor-gradle-plugin:1.5.1')
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")
}
}
plugins {
id "org.sonarqube" version "1.2"
}
apply plugin: 'base'
description = 'Spring Security'
allprojects {
apply plugin: 'idea'
apply plugin: 'eclipse'
ext.releaseBuild = version.endsWith('RELEASE')
ext.snapshotBuild = version.endsWith('SNAPSHOT')
ext.springVersion = '4.3.14.RELEASE'
ext.springLdapVersion = '2.2.0.RELEASE'
group = 'org.springframework.security'
repositories {
mavenCentral()
maven { url "https://repo.spring.io/libs-snapshot" }
maven { url "https://repo.spring.io/plugins-release" }
maven { url "https://repo.terracotta.org/maven2/" }
}
eclipse.project.name = "${project.name}-4.1.x"
}
sonarqube {
properties {
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.projectName", "Spring Security"
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
property "sonar.links.homepage", 'https://www.springsource.org/spring-security'
property "sonar.links.ci", 'https://build.springsource.org/browse/SEC-B32X'
property "sonar.links.issue", 'https://jira.springsource.org/browse/SEC'
property "sonar.links.scm", 'https://github.com/SpringSource/spring-security'
property "sonar.links.scm_dev", 'https://github.com/SpringSource/spring-security.git'
property "sonar.java.coveragePlugin", "jacoco"
}
}
// Set up different subproject lists for individual configuration
ext.javaProjects = subprojects.findAll { project -> project.name != 'docs' && project.name != 'manual' && project.name != 'guides' && project.name != 'spring-security-bom' }
ext.sampleProjects = subprojects.findAll { project -> project.name.startsWith('spring-security-samples') }
ext.itestProjects = subprojects.findAll { project -> project.name.startsWith('itest') }
ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-xml-aspectj'), project(':spring-security-samples-javaconfig-aspectj')]
configure(allprojects - javaProjects) {
task afterEclipseImport {
ext.srcFile = file('.classpath')
inputs.file srcFile
outputs.dir srcFile
onlyIf { !srcFile.exists() }
doLast {
srcFile << """<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
"""
}
}
}
configure(subprojects - coreModuleProjects - project(':spring-security-samples-javaconfig-messages') - project(':spring-security-bom')) {
tasks.findByPath("artifactoryPublish")?.enabled = false
sonarqube {
skipProject = true
}
}
configure(javaProjects) {
ext.TOMCAT_GRADLE = "$rootDir/gradle/tomcat.gradle"
ext.WAR_SAMPLE_GRADLE = "$rootDir/gradle/war-sample.gradle"
ext.BOOT_SAMPLE_GRADLE = "$rootDir/gradle/boot-sample.gradle"
apply from: "$rootDir/gradle/javaprojects.gradle"
if(!project.name.contains('gae')) {
apply from: "$rootDir/gradle/checkstyle.gradle"
}
apply from: "$rootDir/gradle/ide.gradle"
apply from: "$rootDir/gradle/release-checks.gradle"
apply from: "$rootDir/gradle/maven-deployment.gradle"
}
configure(coreModuleProjects) {
apply plugin: 'emma'
apply plugin: 'spring-io'
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : '2.0.1.RELEASE'
configurations {
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
}
dependencyManagement {
springIoTestRuntime {
imports {
mavenBom "io.spring.platform:platform-bom:${springIoVersion}"
}
}
}
dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.23.4.RELEASE'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
classpath 'io.spring.nohttp:nohttp-gradle:0.0.10'
classpath "io.freefair.gradle:aspectj-plugin:4.0.2"
jacoco "org.jacoco:org.jacoco.agent:0.7.5.201505241946:runtime"
}
repositories {
maven {
url = 'https://repo.spring.io/plugins-snapshot'
if (project.hasProperty('artifactoryUsername')) {
credentials {
username "$artifactoryUsername"
password "$artifactoryPassword"
test {
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
}
integrationTest {
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
}
}
configure (aspectjProjects) {
apply plugin: 'java'
apply plugin: 'aspectj'
}
task coreBuild {
dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'build' }
}
task coreInstall {
dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'install' }
}
// Task for creating the distro zip
task dist(type: Zip) {
dependsOn { subprojects*.tasks*.matching { task -> task.name.endsWith('generatePom') } }
classifier = 'dist'
evaluationDependsOn(':docs')
evaluationDependsOn(':docs:manual')
def zipRootDir = "${project.name}-$version"
into(zipRootDir) {
from(rootDir) {
include '*.adoc'
include '*.txt'
}
into('docs') {
with(project(':docs').apiSpec)
with(project(':docs:manual').spec)
with(project(':docs:guides').spec)
}
project.coreModuleProjects*.tasks*.withType(AbstractArchiveTask).flatten().each{ archiveTask ->
if(archiveTask!=dist){
into("$zipRootDir/dist") {
from archiveTask.outputs.files
}
}
}
maven { url 'https://plugins.gradle.org/m2/' }
}
}
apply plugin: 'io.spring.nohttp'
apply plugin: 'io.spring.convention.root'
group = 'org.springframework.security'
description = 'Spring Security'
ext.snapshotBuild = version.contains("SNAPSHOT")
ext.releaseBuild = version.contains("SNAPSHOT")
ext.milestoneBuild = !(snapshotBuild || releaseBuild)
dependencyManagementExport.projects = subprojects.findAll { !it.name.contains('-boot') }
repositories {
mavenCentral()
}
subprojects {
plugins.withType(JavaPlugin) {
project.sourceCompatibility='1.8'
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
}
if (project.hasProperty('artifactoryUsername')) {
allprojects { project ->
project.repositories { repos ->
all { repo ->
if (!repo.url.toString().startsWith("https://repo.spring.io/")) {
return;
}
repo.credentials {
username = artifactoryUsername
password = artifactoryPassword
sampleProjects.each { project->
into("$zipRootDir/samples/$project.name") {
from(project.projectDir) {
include "src/main/**"
include "pom.xml"
}
}
}
}
}
artifacts {
archives dist
archives project(':docs').docsZip
archives project(':docs').schemaZip
}
+24 -11
View File
@@ -1,21 +1,34 @@
apply plugin: "java-gradle-plugin"
apply plugin: 'groovy'
repositories {
mavenCentral()
}
gradlePlugin {
plugins {
trang {
id = "trang"
implementationClass = "trang.TrangPlugin"
}
maven {
name = 'SpringSource Enterprise Release'
url = 'https://repository.springsource.com/maven/bundles/release'
}
maven {
name = 'SpringSource Enterprise External'
url = 'https://repository.springsource.com/maven/bundles/external'
}
}
dependencies {
compile 'com.thaiopensource:trang:20091111'
compile 'net.sourceforge.saxon:saxon:9.1.0.8'
compile gradleApi()
}
// GAE
dependencies {
compile 'com.google.appengine:appengine-tools-sdk:1.4.2'
}
dependencies{
compile "emma:emma:2.0.5312"
}
// Trang
dependencies {
compile 'com.thaiopensource:trang:20091111',
'net.sourceforge.saxon:saxon:9.1.0.8'
}
task ide(type: Copy) {
@@ -0,0 +1,19 @@
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.*
import org.gradle.api.tasks.*
import org.gradle.api.tasks.TaskAction
public class MavenBomPlugin implements Plugin<Project> {
static String MAVEN_BOM_TASK_NAME = "mavenBom"
public void apply(Project project) {
project.plugins.apply(JavaPlugin)
project.plugins.apply(MavenPlugin)
project.task(MAVEN_BOM_TASK_NAME, type: MavenBomTask, group: 'Generate', description: 'Configures the pom as a Maven Build of Materials (BOM)')
project.install.dependsOn project.mavenBom
}
}
@@ -0,0 +1,55 @@
import groovy.xml.MarkupBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.tasks.*
public class MavenBomTask extends DefaultTask {
Set<Project> projects
File bomFile
public MavenBomTask() {
this.group = "Generate"
this.description = "Generates a Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies"
this.projects = project.subprojects
this.bomFile = project.file("${->project.buildDir}/maven-bom/${->project.name}-${->project.version}.txt")
}
@TaskAction
public void configureBom() {
project.configurations.archives.artifacts.clear()
bomFile.parentFile.mkdirs()
bomFile.write("Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies")
project.artifacts {
// work around GRADLE-2406 by attaching text artifact
archives(bomFile)
}
project.install {
repositories.mavenInstaller {
pom.whenConfigured {
packaging = "pom"
withXml {
asNode().children().last() + {
delegate.dependencyManagement {
delegate.dependencies {
projects.sort { dep -> "$dep.group:$dep.name" }.each { p ->
delegate.dependency {
delegate.groupId(p.group)
delegate.artifactId(p.name)
delegate.version(p.version)
}
}
}
}
}
}
}
}
}
}
}
@@ -0,0 +1,121 @@
package aspectj
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.tasks.TaskAction
import org.gradle.api.logging.LogLevel
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.SourceSet
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.plugins.JavaPlugin
import org.gradle.plugins.ide.eclipse.GenerateEclipseProject
import org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath
import org.gradle.plugins.ide.eclipse.EclipsePlugin
import org.gradle.plugins.ide.eclipse.model.BuildCommand
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
/**
*
* @author Luke Taylor
*/
class AspectJPlugin implements Plugin<Project> {
void apply(Project project) {
project.plugins.apply(JavaPlugin)
if (!project.hasProperty('aspectjVersion')) {
throw new GradleException("You must set the property 'aspectjVersion' before applying the aspectj plugin")
}
if (project.configurations.findByName('ajtools') == null) {
project.configurations.create('ajtools')
project.dependencies {
ajtools "org.aspectj:aspectjtools:${project.aspectjVersion}"
optional "org.aspectj:aspectjrt:${project.aspectjVersion}"
}
}
if (project.configurations.findByName('aspectpath') == null) {
project.configurations.create('aspectpath')
}
project.tasks.create(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
dependsOn project.processResources
sourceSet = project.sourceSets.main
inputs.files(sourceSet.allSource)
outputs.dir(sourceSet.output.classesDir)
aspectPath = project.configurations.aspectpath
}
project.tasks.compileJava.deleteAllActions()
project.tasks.compileJava.dependsOn project.tasks.compileAspect
project.tasks.create(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
dependsOn project.processTestResources, project.compileJava, project.jar
sourceSet = project.sourceSets.test
inputs.files(sourceSet.allSource)
outputs.dir(sourceSet.output.classesDir)
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
}
project.tasks.compileTestJava.deleteAllActions()
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
project.tasks.withType(GenerateEclipseProject) {
project.eclipse.project.file.whenMerged { p ->
p.natures.add(0, 'org.eclipse.ajdt.ui.ajnature')
p.buildCommands = [new BuildCommand('org.eclipse.ajdt.core.ajbuilder')]
}
}
project.tasks.withType(GenerateEclipseClasspath) {
project.eclipse.classpath.file.whenMerged { classpath ->
def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
def projectPath = entry.path.replaceAll('/','')
project.rootProject.allprojects.find{ p->
if(p.plugins.findPlugin(EclipsePlugin)) {
return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
}
false
}
}
entries.each { entry->
entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
}
}
}
}
}
class Ajc extends DefaultTask {
SourceSet sourceSet
FileCollection aspectPath
Ajc() {
logging.captureStandardOutput(LogLevel.INFO)
}
@TaskAction
def compile() {
logger.info("="*30)
logger.info("="*30)
logger.info("Running ajc ...")
logger.info("classpath: ${sourceSet.compileClasspath.asPath}")
logger.info("srcDirs $sourceSet.java.srcDirs")
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.output.classesDir.absolutePath,
source: project.convention.plugins.java.sourceCompatibility,
target: project.convention.plugins.java.targetCompatibility,
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
sourceroots {
sourceSet.java.srcDirs.each {
logger.info(" sourceRoot $it")
pathelement(location: it.absolutePath)
}
}
}
}
}
@@ -0,0 +1,114 @@
package emma;
import org.gradle.api.*
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.Input
import com.vladium.emma.instr.InstrProcessor
import com.vladium.emma.report.ReportProcessor
import org.gradle.api.tasks.InputFiles
import com.vladium.util.XProperties;
/**
*
* @author Luke Taylor
*/
class EmmaPlugin implements Plugin<Project> {
void apply(Project project) {
Project rootProject = project.rootProject
def emmaMetaDataFile = "${rootProject.buildDir}/emma/emma.em"
def emmaCoverageFile = "${rootProject.buildDir}/emma/emma.ec"
if (project.configurations.findByName('emma_rt') == null) {
project.configurations.create('emma_rt')
project.dependencies {
emma_rt 'emma:emma:2.0.5312'
}
}
project.task('emmaInstrument') {
dependsOn project.classes
doFirst {
InstrProcessor processor = InstrProcessor.create ();
String[] classesDirPath = [project.sourceSets.main.output.classesDir.absolutePath]
processor.setInstrPath(classesDirPath, false);
processor.setOutMode(InstrProcessor.OutMode.OUT_MODE_COPY);
processor.setInstrOutDir("${project.buildDir}/emma/classes");
processor.setMetaOutFile(emmaMetaDataFile);
processor.setMetaOutMerge(true);
//processor.setInclExclFilter (null);
processor.run();
}
}
// Modify test tasks in the project to generate coverage data
project.afterEvaluate {
if (project.hasProperty('coverage') && ['on','true'].contains(project.properties.coverage)) {
project.tasks.withType(Test.class).each { task ->
task.dependsOn project.emmaInstrument
task.configure() {
jvmArgs '-Dsec.log.level=DEBUG', "-Demma.coverage.out.file=$emmaCoverageFile"
jvmArgs '-Demma.verbosity.level=quiet'
}
task.doFirst {
classpath = project.files("${project.buildDir}/emma/classes") + project.configurations.emma_rt + classpath
}
}
}
}
List<Task> reportTasks = rootProject.getTasksByName('coverageReport', false) as List;
CoverageReport task;
if (reportTasks.isEmpty()) {
task = rootProject.tasks.create('coverageReport', CoverageReport.class);
task.dataPath = [emmaMetaDataFile, emmaCoverageFile];
} else {
task = reportTasks[0];
}
task.modules.add(project);
}
}
class CoverageReport extends DefaultTask {
@Input
List<Project> modules = [];
@Input
String[] dataPath;
@TaskAction
void generateReport() {
def buildDir = project.rootProject.buildDir
if (!buildDir.exists()) {
throw new GradleException("No coverage data. Run gradle with -Pcoverage=on if using coverageReport");
}
ReportProcessor processor = ReportProcessor.create ();
processor.setDataPath(dataPath)
def srcPath = []
modules.each {module->
module.sourceSets.main.java.srcDirs.each {
srcPath.add(it.absolutePath)
}
}
processor.setSourcePath(srcPath as String[]);
def types = ['txt', 'html']
processor.setReportTypes(types as String[]);
XProperties properties = new XProperties();
properties.setProperty('report.html.out.file', "$buildDir/emma/coverage.html");
properties.setProperty('report.txt.out.file', "$buildDir/emma/coverage.txt");
processor.setPropertyOverrides(properties)
processor.run()
}
}
@@ -0,0 +1,59 @@
package trang;
import com.thaiopensource.relaxng.translate.Driver
import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamSource
import javax.xml.transform.stream.StreamResult
import org.gradle.api.*;
import org.gradle.api.tasks.*
import org.gradle.api.file.FileCollection
/**
* Used for converting .rnc files to .xsd files.
* @author Rob Winch
*/
class TrangPlugin implements Plugin<Project> {
public void apply(Project project) {
Task rncToXsd = project.tasks.create('rncToXsd', RncToXsd.class)
rncToXsd.description = 'Converts .rnc to .xsd'
rncToXsd.group = 'Build'
}
}
/**
* Converts .rnc files to .xsd files using trang and then applies an xsl file to cleanup the results.
*/
public class RncToXsd extends DefaultTask {
@InputDirectory
File rncDir
@InputFile
File xslFile
@OutputDirectory
File xsdDir
@TaskAction
public final void transform() {
String xslPath = xslFile.absolutePath
rncDir.listFiles( { dir, file -> file.endsWith('.rnc')} as FilenameFilter).each { rncFile ->
File xsdFile = new File(xsdDir, rncFile.name.replace('.rnc', '.xsd'))
String xsdOutputPath = xsdFile.absolutePath
new Driver().run([rncFile.absolutePath, xsdOutputPath] as String[]);
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl()
Transformer transformer =
tFactory.newTransformer(new StreamSource(xslPath))
File temp = File.createTempFile("gradle-trang-" + xsdFile.name, ".xsd")
xsdFile.withInputStream { is ->
temp << is
}
StreamSource xmlSource = new StreamSource(temp)
transformer.transform(xmlSource, new StreamResult(xsdFile))
temp.delete()
}
}
}
@@ -1,83 +0,0 @@
package trang;
import com.thaiopensource.relaxng.translate.Driver;
import net.sf.saxon.TransformerFactoryImpl;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
/**
* Converts .rnc files to .xsd files using trang and then applies an xsl file to cleanup the results.
*/
public class RncToXsd extends DefaultTask {
private File rncDir;
private File xslFile;
private File xsdDir;
@InputDirectory
public File getRncDir() {
return rncDir;
}
public void setRncDir(File rncDir) {
this.rncDir = rncDir;
}
@InputFile
public File getXslFile() {
return xslFile;
}
public void setXslFile(File xslFile) {
this.xslFile = xslFile;
}
@OutputDirectory
public File getXsdDir() {
return xsdDir;
}
public void setXsdDir(File xsdDir) {
this.xsdDir = xsdDir;
}
@TaskAction
public final void transform() throws IOException, TransformerException {
String xslPath = xslFile.getAbsolutePath();
File[] files = rncDir.listFiles((dir, file) -> file.endsWith(".rnc"));
if(files != null) {
for (File rncFile : files) {
File xsdFile = new File(xsdDir, rncFile.getName().replace(".rnc", ".xsd"));
String xsdOutputPath = xsdFile.getAbsolutePath();
new Driver().run(new String[]{rncFile.getAbsolutePath(), xsdOutputPath});
TransformerFactory tFactory = new TransformerFactoryImpl();
Transformer transformer = tFactory.newTransformer(new StreamSource(xslPath));
File temp = File.createTempFile("gradle-trang-" + xsdFile.getName(), ".xsd");
Files.copy(xsdFile.toPath(), temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
StreamSource xmlSource = new StreamSource(temp);
transformer.transform(xmlSource, new StreamResult(xsdFile));
temp.delete();
}
}
}
}
@@ -1,18 +0,0 @@
package trang;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
/**
* Used for converting .rnc files to .xsd files.
* @author Rob Winch
*/
public class TrangPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().register("rncToXsd", RncToXsd.class, rncToXsd -> {
rncToXsd.setDescription("Converts .rnc to .xsd");
rncToXsd.setGroup("Build");
});
}
}
@@ -1,49 +0,0 @@
package versions;
import org.codehaus.groovy.runtime.ResourceGroovyMethods;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Properties;
public class VersionsResourceTasks extends DefaultTask {
private final RegularFileProperty versionsFile = getProject().getObjects().fileProperty();
private final MapProperty<String, String> versions = getProject().getObjects().mapProperty(String.class, String.class);
@OutputFile
public RegularFileProperty getVersionsFile() {
return versionsFile;
}
@Input
public MapProperty<String, String> getVersions() {
return versions;
}
@TaskAction
void generateVersions() throws IOException {
File file = versionsFile.getAsFile().get();
File parentFile = versionsFile.getAsFile().get().getParentFile();
if (parentFile.isDirectory() || parentFile.mkdirs()) {
Properties properties = new Properties();
properties.putAll(getVersions().get());
try (Writer writer = ResourceGroovyMethods.newWriter(file)) {
properties.store(writer, null);
}
}
else {
throw new IOException(parentFile + " does not exist and cannot be created");
}
}
}
@@ -0,0 +1 @@
implementation-class=aspectj.AspectJPlugin
@@ -0,0 +1 @@
implementation-class=emma.EmmaPlugin
@@ -0,0 +1 @@
implementation-class=MavenBomPlugin
@@ -0,0 +1 @@
implementation-class=trang.TrangPlugin
+14
View File
@@ -0,0 +1,14 @@
dependencies {
compile project(':spring-security-core'),
project(':spring-security-web'),
springCoreDependency,
"org.springframework:spring-context:$springVersion",
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-web:$springVersion",
"org.jasig.cas.client:cas-client-core:$casClientVersion"
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
}
+156
View File
@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.1.5.RELEASE</version>
<name>spring-security-cas</name>
<description>spring-security-cas</description>
<url>https://spring.io/spring-security</url>
<organization>
<name>spring.io</name>
<url>https://spring.io/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>https://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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.14.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.4.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
-18
View File
@@ -1,18 +0,0 @@
apply plugin: 'io.spring.convention.spring-module'
dependencies {
compile project(':spring-security-core')
compile project(':spring-security-web')
compile 'org.jasig.cas.client:cas-client-core'
compile 'org.springframework:spring-beans'
compile 'org.springframework:spring-context'
compile 'org.springframework:spring-core'
compile 'org.springframework:spring-web'
optional 'com.fasterxml.jackson.core:jackson-databind'
optional 'net.sf.ehcache:ehcache'
provided 'javax.servlet:javax.servlet-api'
testCompile 'org.skyscreamer:jsonassert'
}
@@ -50,7 +50,7 @@ public class ServiceProperties implements InitializingBean {
// ~ Methods
// ========================================================================================================
public void afterPropertiesSet() {
public void afterPropertiesSet() throws Exception {
Assert.hasLength(this.service, "service cannot be empty.");
Assert.hasLength(this.artifactParameter, "artifactParameter cannot be empty.");
Assert.hasLength(this.serviceParameter, "serviceParameter cannot be empty.");
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
/**
@@ -36,7 +37,7 @@ public final class CasAssertionAuthenticationToken extends AbstractAuthenticatio
private final String ticket;
public CasAssertionAuthenticationToken(final Assertion assertion, final String ticket) {
super(new ArrayList<>());
super(new ArrayList<GrantedAuthority>());
this.assertion = assertion;
this.ticket = ticket;
@@ -77,7 +77,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
// ~ Methods
// ========================================================================================================
public void afterPropertiesSet() {
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.authenticationUserDetailsService,
"An authenticationUserDetailsService must be set");
Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
@@ -24,7 +24,6 @@ import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;
/**
* Represents a successful CAS <code>Authentication</code>.
@@ -51,54 +50,29 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
/**
* Constructor.
*
* @param key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
*
* @throws IllegalArgumentException if a <code>null</code> was passed
*/
public CasAuthenticationToken(final String key, final Object principal,
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
this(extractKeyHash(key), principal, credentials, authorities, userDetails, assertion);
}
/**
* Private constructor for Jackson Deserialization support
*
* @param keyHash hashCode of provided key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
* @throws IllegalArgumentException if a <code>null</code> was passed
* @since 4.2
*/
private CasAuthenticationToken(final Integer keyHash, final Object principal,
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
super(authorities);
if ((principal == null)
if ((key == null) || ("".equals(key)) || (principal == null)
|| "".equals(principal) || (credentials == null)
|| "".equals(credentials) || (authorities == null)
|| (userDetails == null) || (assertion == null)) {
@@ -106,7 +80,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
"Cannot pass null or empty values to constructor");
}
this.keyHash = keyHash;
this.keyHash = key.hashCode();
this.principal = principal;
this.credentials = credentials;
this.userDetails = userDetails;
@@ -117,12 +91,6 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
// ~ Methods
// ========================================================================================================
private static Integer extractKeyHash(String key) {
Assert.hasLength(key, "key cannot be null or empty");
return key.hashCode();
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
@@ -145,18 +113,6 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
return false;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + this.credentials.hashCode();
result = 31 * result + this.principal.hashCode();
result = 31 * result + this.userDetails.hashCode();
result = 31 * result + this.keyHash;
result = 31 * result + (this.assertion != null ? this.assertion.hashCode() : 0);
return result;
}
@Override
public Object getCredentials() {
return this.credentials;
}
@@ -165,7 +121,6 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
return this.keyHash;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@@ -178,7 +133,6 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
return userDetails;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString());
@@ -26,7 +26,7 @@ import org.springframework.util.Assert;
/**
* Caches tickets using a Spring IoC defined <a
* href="https://www.ehcache.org/">EHCACHE</a>.
* href="http://ehcache.sourceforge.net">EHCACHE</a>.
*
* @author Ben Alex
*/
@@ -44,7 +44,7 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, Initializi
// ~ Methods
// ========================================================================================================
public void afterPropertiesSet() {
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache mandatory");
}
@@ -42,7 +42,7 @@ public class SpringCacheBasedTicketCache implements StatelessTicketCache {
// ~ Constructors
// ===================================================================================================
public SpringCacheBasedTicketCache(Cache cache) {
public SpringCacheBasedTicketCache(Cache cache) throws Exception {
Assert.notNull(cache, "cache mandatory");
this.cache = cache;
}
@@ -1,62 +0,0 @@
/*
* Copyright 2015-2016 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
*
* https://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.cas.jackson2;
import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.authentication.AttributePrincipal;
import java.util.Date;
import java.util.Map;
/**
* Helps in jackson deserialization of class {@link org.jasig.cas.client.validation.AssertionImpl}, which is
* used with {@link org.springframework.security.cas.authentication.CasAuthenticationToken}.
* To use this class we need to register with {@link com.fasterxml.jackson.databind.ObjectMapper}. Type information
* will be stored in @class property.
* <p>
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY,
getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
class AssertionImplMixin {
/**
* Mixin Constructor helps in deserialize {@link org.jasig.cas.client.validation.AssertionImpl}
*
* @param principal the Principal to associate with the Assertion.
* @param validFromDate when the assertion is valid from.
* @param validUntilDate when the assertion is valid to.
* @param authenticationDate when the assertion is authenticated.
* @param attributes the key/value pairs for this attribute.
*/
@JsonCreator
AssertionImplMixin(@JsonProperty("principal") AttributePrincipal principal,
@JsonProperty("validFromDate") Date validFromDate, @JsonProperty("validUntilDate") Date validUntilDate,
@JsonProperty("authenticationDate") Date authenticationDate, @JsonProperty("attributes") Map<String, Object> attributes){
}
}
@@ -1,58 +0,0 @@
/*
* Copyright 2015-2016 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
*
* https://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.cas.jackson2;
import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.proxy.ProxyRetriever;
import java.util.Map;
/**
* Helps in deserialize {@link org.jasig.cas.client.authentication.AttributePrincipalImpl} which is used with
* {@link org.springframework.security.cas.authentication.CasAuthenticationToken}. Type information will be stored
* in property named @class.
* <p>
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
class AttributePrincipalImplMixin {
/**
* Mixin Constructor helps in deserialize {@link org.jasig.cas.client.authentication.AttributePrincipalImpl}
*
* @param name the unique identifier for the principal.
* @param attributes the key/value pairs for this principal.
* @param proxyGrantingTicket the ticket associated with this principal.
* @param proxyRetriever the ProxyRetriever implementation to call back to the CAS server.
*/
@JsonCreator
AttributePrincipalImplMixin(@JsonProperty("name") String name, @JsonProperty("attributes") Map<String, Object> attributes,
@JsonProperty("proxyGrantingTicket") String proxyGrantingTicket,
@JsonProperty("proxyRetriever") ProxyRetriever proxyRetriever) {
}
}
@@ -1,77 +0,0 @@
/*
* Copyright 2015-2016 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
*
* https://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.cas.jackson2;
import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* Mixin class which helps in deserialize {@link org.springframework.security.cas.authentication.CasAuthenticationToken}
* using jackson. Two more dependent classes needs to register along with this mixin class.
* <ol>
* <li>{@link org.springframework.security.cas.jackson2.AssertionImplMixin}</li>
* <li>{@link org.springframework.security.cas.jackson2.AttributePrincipalImplMixin}</li>
* </ol>
*
* <p>
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
getterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY)
@JsonIgnoreProperties(ignoreUnknown = true)
class CasAuthenticationTokenMixin {
/**
* Mixin Constructor helps in deserialize {@link CasAuthenticationToken}
*
* @param keyHash hashCode of provided key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
*/
@JsonCreator
CasAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash, @JsonProperty("principal") Object principal,
@JsonProperty("credentials") Object credentials,
@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities,
@JsonProperty("userDetails") UserDetails userDetails, @JsonProperty("assertion") Assertion assertion) {
}
}

Some files were not shown because too many files have changed in this diff Show More