Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e694b1304 | |||
| 3ddcbde466 | |||
| cd326df659 | |||
| 4c530661e7 | |||
| 2df411fed0 | |||
| ede969384d | |||
| d3840c262d | |||
| 7bd7843c65 | |||
| 7a4b6d8301 | |||
| 43f92b9da4 | |||
| 3f630bd19b | |||
| 3ea9b7043b | |||
| d428b7c674 | |||
| e4a46bea8b | |||
| 55eb2f7e16 | |||
| c932143f6f | |||
| f49dbf9704 | |||
| 2b531ce9fa | |||
| 8682e20cc9 | |||
| a3234cbdc6 | |||
| cd8c3d006b | |||
| 169ad0b24d | |||
| 8eedb062c4 | |||
| 1843580f03 | |||
| 45e6ab3fc6 | |||
| 9d3a20c331 | |||
| cf8043a90c | |||
| 83953249a9 | |||
| 97e549a27a | |||
| 105517fc82 | |||
| 40a0655627 | |||
| 48f617ab00 | |||
| 4141ddbde2 | |||
| 80081b0500 | |||
| 3c95c08106 | |||
| 091cbe5458 | |||
| 04f8a7974e | |||
| 66f30cf606 | |||
| e23e738cfe | |||
| 54e7aace6d | |||
| 4c1fdbf290 | |||
| 759c378eeb | |||
| 9f514753d5 | |||
| 16d5566cd6 | |||
| 7633fbfd8a | |||
| 51f905cb89 | |||
| 007ee7652b | |||
| 0aaaaf9f2f | |||
| be7d2a3c41 | |||
| e6aa141260 | |||
| e6bb9bfdca | |||
| 548dc4496c | |||
| 7f2f12c428 | |||
| 6dfad970d4 | |||
| 114e00f1dd | |||
| a0e541eb70 | |||
| 477a5a7cd3 | |||
| 8918a7e693 | |||
| bf33f9acef | |||
| f1598b985c | |||
| cc1ab2c368 | |||
| aac4525737 | |||
| eeb099a04f | |||
| 3e90c7663f | |||
| cfec514082 | |||
| 80b123bf36 | |||
| ee6f9e0b92 | |||
| 2625de9c23 | |||
| a145653030 | |||
| 8bc0ef86da | |||
| a02d6ad2a4 | |||
| acdd9ba1db | |||
| e218ac2e40 | |||
| dd859c4a6e | |||
| 5d85a1c9d8 | |||
| 49167458d2 | |||
| 6b4edacde2 | |||
| b7cebee89e | |||
| 01787ea168 | |||
| e3e9758da7 | |||
| 46012d62af | |||
| 6eb8129173 | |||
| 55dd732443 | |||
| 45cbdc03ba | |||
| d99c7dbfd1 | |||
| d8de4d06f7 | |||
| be2f0f0fae | |||
| 920d5ca6ad | |||
| 6dcf5a27b1 | |||
| c2166c4207 | |||
| 1542835268 | |||
| ae471e1456 | |||
| 853c54eecb | |||
| 10f6d10f81 | |||
| 02d844d528 | |||
| c0849ba891 | |||
| db145fa03f | |||
| 42b8b794a8 | |||
| 8014114225 | |||
| a742c0c3f2 | |||
| 1cec4fe3ac | |||
| 8655caa2de | |||
| dc5f5f348d | |||
| 35e05780ea | |||
| a461abcf32 | |||
| ba1f5f3873 | |||
| 5478b74116 | |||
| dc4aa3d017 | |||
| 2bc156ed19 | |||
| 0270994340 | |||
| a557a324c0 | |||
| 73022059d4 | |||
| 165cbcb723 | |||
| d99ecc2a7b | |||
| ccd2664e6c | |||
| b87ff3c00f | |||
| 8971777908 | |||
| 3d618d78ac | |||
| 697b8cd734 | |||
| cf03faf58e | |||
| 13159e9f88 | |||
| 41b7c74928 | |||
| 0a4ac4dbfc | |||
| 1eb56f46a5 | |||
| cfc3c25304 | |||
| 03a3a3b770 |
+6
-6
@@ -9,14 +9,14 @@ trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
|
||||
[*.{java,xml}]
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
charset = latin1
|
||||
continuation_indent_size = 8
|
||||
|
||||
ij_smart_tabs = false
|
||||
ij_java_align_multiline_parameters = false
|
||||
|
||||
[*.gradle]
|
||||
[*.xml]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
charset = latin1
|
||||
continuation_indent_size = 8
|
||||
|
||||
@@ -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.
|
||||
@@ -3,7 +3,5 @@ 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 #).
|
||||
-->
|
||||
|
||||
+1
-5
@@ -8,7 +8,7 @@ target/
|
||||
.project
|
||||
.DS_Store
|
||||
.settings/
|
||||
.idea/*
|
||||
.idea/
|
||||
out/
|
||||
bin/
|
||||
intellij/
|
||||
@@ -23,7 +23,3 @@ atlassian-ide-plugin.xml
|
||||
!etc/eclipse/.checkstyle
|
||||
.checkstyle
|
||||
s101plugin.state
|
||||
.attach_pid*
|
||||
|
||||
!.idea/checkstyle-idea.xml
|
||||
!.idea/externalDependencies.xml
|
||||
|
||||
Generated
-19
@@ -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>
|
||||
Generated
-7
@@ -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>
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
- oraclejdk8
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
+2
-14
@@ -33,18 +33,6 @@ Not sure what a pull request is, or how to submit one? Take a look at GitHub's e
|
||||
# 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.
|
||||
|
||||
@@ -72,7 +60,7 @@ 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
|
||||
|
||||
@@ -137,7 +125,7 @@ Update the [RELAX NG](https://relaxng.org/) schema `spring-security-x.y.rnc` ins
|
||||
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: https://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:
|
||||
|
||||
Vendored
+9
-46
@@ -13,11 +13,8 @@ try {
|
||||
stage('Check') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
sh "./gradlew clean check --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
sh "./gradlew clean check --refresh-dependencies --no-daemon --stacktrace"
|
||||
} catch(Exception e) {
|
||||
currentBuild.result = 'FAILED: check'
|
||||
throw e
|
||||
@@ -31,15 +28,12 @@ try {
|
||||
stage('Sonar') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
withCredentials([string(credentialsId: 'spring-sonar.login', variable: 'SONAR_LOGIN')]) {
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
if ("master" == env.BRANCH_NAME) {
|
||||
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
|
||||
} else {
|
||||
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.projectKey='spring-security-${env.BRANCH_NAME}' -Dsonar.projectName='spring-security-${env.BRANCH_NAME}' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
if ("master" == env.BRANCH_NAME) {
|
||||
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
|
||||
} else {
|
||||
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.projectKey='spring-security-${env.BRANCH_NAME}' -Dsonar.projectName='spring-security-${env.BRANCH_NAME}' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
} catch(Exception e) {
|
||||
currentBuild.result = 'FAILED: sonar'
|
||||
@@ -53,11 +47,8 @@ try {
|
||||
stage('Snapshot Tests') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
sh "./gradlew clean test -PforceMavenRepositories=snapshot -PspringVersion='5.2.+' -PreactorVersion=Dysprosium-BUILD-SNAPSHOT -PspringDataVersion=Lovelace-BUILD-SNAPSHOT --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
sh "./gradlew clean test -PforceMavenRepositories=snapshot -PspringVersion='5.+' -PreactorVersion=Californium-BUILD-SNAPSHOT -PspringDataVersion=Lovelace-BUILD-SNAPSHOT --refresh-dependencies --no-daemon --stacktrace"
|
||||
} catch(Exception e) {
|
||||
currentBuild.result = 'FAILED: snapshots'
|
||||
throw e
|
||||
@@ -69,7 +60,6 @@ try {
|
||||
stage('JDK 9') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk9' }"]) {
|
||||
sh "./gradlew clean test --refresh-dependencies --no-daemon --stacktrace"
|
||||
@@ -85,7 +75,6 @@ try {
|
||||
stage('JDK 10') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk10' }"]) {
|
||||
sh "./gradlew clean test --refresh-dependencies --no-daemon --stacktrace"
|
||||
@@ -101,7 +90,6 @@ try {
|
||||
stage('JDK 11') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk11' }"]) {
|
||||
sh "./gradlew clean test --refresh-dependencies --no-daemon --stacktrace"
|
||||
@@ -112,22 +100,6 @@ try {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
jdk12: {
|
||||
stage('JDK 12') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${ tool 'openjdk12' }"]) {
|
||||
sh "./gradlew clean test --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
} catch(Exception e) {
|
||||
currentBuild.result = 'FAILED: jdk12'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentBuild.result == 'SUCCESS') {
|
||||
@@ -135,14 +107,11 @@ try {
|
||||
stage('Deploy Artifacts') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
withCredentials([file(credentialsId: 'spring-signing-secring.gpg', variable: 'SIGNING_KEYRING_FILE')]) {
|
||||
withCredentials([string(credentialsId: 'spring-gpg-passphrase', variable: 'SIGNING_PASSWORD')]) {
|
||||
withCredentials([usernamePassword(credentialsId: 'oss-token', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USERNAME')]) {
|
||||
withCredentials([usernamePassword(credentialsId: '02bd1690-b54f-4c9f-819d-a77cb7a9822c', usernameVariable: 'ARTIFACTORY_USERNAME', passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
sh "./gradlew deployArtifacts finalizeDeployArtifacts -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE -Psigning.keyId=$SPRING_SIGNING_KEYID -Psigning.password='$SIGNING_PASSWORD' -PossrhUsername=$OSSRH_USERNAME -PossrhPassword=$OSSRH_PASSWORD -PartifactoryUsername=$ARTIFACTORY_USERNAME -PartifactoryPassword=$ARTIFACTORY_PASSWORD --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
sh "./gradlew deployArtifacts finalizeDeployArtifacts -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE -Psigning.keyId=$SPRING_SIGNING_KEYID -Psigning.password='$SIGNING_PASSWORD' -PossrhUsername=$OSSRH_USERNAME -PossrhPassword=$OSSRH_PASSWORD -PartifactoryUsername=$ARTIFACTORY_USERNAME -PartifactoryPassword=$ARTIFACTORY_PASSWORD --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,11 +123,8 @@ try {
|
||||
stage('Deploy Docs') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
sh "./gradlew deployDocs -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
sh "./gradlew deployDocs -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,11 +133,8 @@ try {
|
||||
stage('Deploy Schema') {
|
||||
node {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) {
|
||||
withEnv(["JAVA_HOME=${ tool 'jdk8' }"]) {
|
||||
sh "./gradlew deploySchema -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
sh "./gradlew deploySchema -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ See https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-
|
||||
|
||||
== 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].
|
||||
Extensive JavaDoc for the Spring Security code is also available in the https://docs.spring.io/spring-security/site/docs/current/apidocs/[Spring Security API Documentation].
|
||||
|
||||
== Quick Start
|
||||
We recommend you visit https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/[Spring Security Reference] and read the "Getting Started" page.
|
||||
@@ -59,7 +59,7 @@ Check out the https://stackoverflow.com/questions/tagged/spring-security[Spring
|
||||
https://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.
|
||||
https://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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+5
-4
@@ -100,7 +100,7 @@ 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),
|
||||
@@ -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
|
||||
|
||||
+2
-23
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -152,9 +152,11 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
||||
*/
|
||||
@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
|
||||
|
||||
@@ -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,7 +49,12 @@ 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,17 +18,11 @@ 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
|
||||
@@ -41,16 +35,7 @@ class AclClassIdUtils {
|
||||
|
||||
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;
|
||||
public AclClassIdUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +59,7 @@ class AclClassIdUtils {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
private boolean hasValidClassIdType(ResultSet resultSet) {
|
||||
private boolean hasValidClassIdType(ResultSet resultSet) throws SQLException {
|
||||
boolean hasClassIdType = false;
|
||||
try {
|
||||
hasClassIdType = classIdTypeFrom(resultSet) != null;
|
||||
@@ -101,13 +86,17 @@ class AclClassIdUtils {
|
||||
}
|
||||
|
||||
private <T> boolean canConvertFromStringTo(Class<T> targetType) {
|
||||
return conversionService.canConvert(String.class, targetType);
|
||||
return hasConversionService() && conversionService.canConvert(String.class, targetType);
|
||||
}
|
||||
|
||||
private <T extends Serializable> T convertFromStringTo(String identifier, Class<T> targetType) {
|
||||
return conversionService.convert(identifier, targetType);
|
||||
}
|
||||
|
||||
private boolean hasConversionService() {
|
||||
return conversionService != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a {@link Long}, attempting to use the {@link ConversionService} if available.
|
||||
* @param identifier The identifier
|
||||
@@ -118,7 +107,7 @@ class AclClassIdUtils {
|
||||
*/
|
||||
private Long convertToLong(Serializable identifier) {
|
||||
Long idAsLong;
|
||||
if (canConvertFromStringTo(Long.class)) {
|
||||
if (hasConversionService()) {
|
||||
idAsLong = conversionService.convert(identifier, Long.class);
|
||||
} else {
|
||||
idAsLong = Long.valueOf(identifier.toString());
|
||||
@@ -131,31 +120,6 @@ class AclClassIdUtils {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -30,8 +31,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;
|
||||
@@ -246,12 +247,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));
|
||||
|
||||
@@ -379,20 +382,22 @@ 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();
|
||||
|
||||
// Inject values
|
||||
ps.setString((2 * i) + 1, identifier);
|
||||
ps.setString((2 * i) + 2, type);
|
||||
i++;
|
||||
// Inject values
|
||||
ps.setString((2 * i) + 1, identifier);
|
||||
ps.setString((2 * i) + 2, type);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}, new ProcessResultSet(acls, sids));
|
||||
|
||||
@@ -449,7 +454,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
|
||||
@@ -548,8 +553,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
public final void setConversionService(ConversionService conversionService) {
|
||||
this.aclClassIdUtils = new AclClassIdUtils(conversionService);
|
||||
public final void setAclClassIdUtils(AclClassIdUtils aclClassIdUtils) {
|
||||
this.aclClassIdUtils = aclClassIdUtils;
|
||||
}
|
||||
|
||||
// ~ Inner Classes
|
||||
@@ -559,7 +564,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
|
||||
@@ -587,15 +592,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
|
||||
@@ -621,7 +626,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
||||
*/
|
||||
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);
|
||||
@@ -639,7 +644,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
||||
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 +661,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 +688,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, 2017 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.
|
||||
@@ -16,6 +16,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 +26,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;
|
||||
@@ -65,7 +66,7 @@ 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;
|
||||
@@ -75,13 +76,9 @@ public class JdbcAclService implements AclService {
|
||||
// ===================================================================================================
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -90,13 +87,17 @@ public class JdbcAclService implements AclService {
|
||||
// ========================================================================================================
|
||||
|
||||
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");
|
||||
Serializable identifier = (Serializable) rs.getObject("obj_id");
|
||||
identifier = aclClassIdUtils.identifierFrom(identifier, rs);
|
||||
|
||||
return new ObjectIdentityImpl(javaType, identifier);
|
||||
}
|
||||
});
|
||||
|
||||
if (objects.size() == 0) {
|
||||
@@ -112,7 +113,7 @@ public class JdbcAclService implements AclService {
|
||||
Assert.isTrue(map.containsKey(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 {
|
||||
@@ -153,7 +154,7 @@ public class JdbcAclService implements AclService {
|
||||
public void setAclClassIdSupported(boolean aclClassIdSupported) {
|
||||
this.aclClassIdSupported = aclClassIdSupported;
|
||||
if (aclClassIdSupported) {
|
||||
// Change the default children select if it hasn't been overridden
|
||||
// Change the default insert 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 {
|
||||
@@ -162,8 +163,8 @@ public class JdbcAclService implements AclService {
|
||||
}
|
||||
}
|
||||
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.aclClassIdUtils = new AclClassIdUtils(conversionService);
|
||||
public void setAclClassIdUtils(AclClassIdUtils aclClassIdUtils) {
|
||||
this.aclClassIdUtils = aclClassIdUtils;
|
||||
}
|
||||
|
||||
protected boolean isAclClassIdSupported() {
|
||||
|
||||
+20
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004, 2005, 2006, 2017, 2018 Acegi Technology Pty Limited
|
||||
* Copyright 2004, 2005, 2006, 2017 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.
|
||||
@@ -135,7 +135,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 +146,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());
|
||||
@@ -169,7 +170,7 @@ 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,
|
||||
jdbcTemplate.update(insertObjectIdentity, classId, object.getIdentifier(), sidId,
|
||||
Boolean.TRUE);
|
||||
}
|
||||
|
||||
@@ -183,7 +184,7 @@ 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,
|
||||
List<Long> classIds = jdbcTemplate.queryForList(selectClassPrimaryKey,
|
||||
new Object[] { type }, Long.class);
|
||||
|
||||
if (!classIds.isEmpty()) {
|
||||
@@ -192,13 +193,13 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
|
||||
if (allowCreate) {
|
||||
if (!isAclClassIdSupported()) {
|
||||
jdbcOperations.update(insertClass, type);
|
||||
jdbcTemplate.update(insertClass, type);
|
||||
} else {
|
||||
jdbcOperations.update(insertClass, type, idType.getCanonicalName());
|
||||
jdbcTemplate.update(insertClass, type, idType.getCanonicalName());
|
||||
}
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
|
||||
"Transaction must be running");
|
||||
return jdbcOperations.queryForObject(classIdentityQuery, Long.class);
|
||||
return jdbcTemplate.queryForObject(classIdentityQuery, Long.class);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -247,18 +248,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 +311,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 +325,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 +339,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 +409,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");
|
||||
|
||||
@@ -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(
|
||||
"............................****");
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+10
-8
@@ -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.
|
||||
@@ -26,6 +26,8 @@ import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AclService;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@@ -37,18 +39,18 @@ import org.springframework.security.core.Authentication;
|
||||
public class AclPermissionEvaluatorTests {
|
||||
|
||||
@Test
|
||||
public void hasPermissionReturnsTrueIfAclGrantsPermission() {
|
||||
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);
|
||||
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyList())).thenReturn(acl);
|
||||
when(acl.isGranted(anyList(), anyList(), eq(false))).thenReturn(true);
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyListOf(Sid.class))).thenReturn(acl);
|
||||
when(acl.isGranted(anyListOf(Permission.class), anyListOf(Sid.class), eq(false))).thenReturn(true);
|
||||
|
||||
assertThat(pe.hasPermission(mock(Authentication.class), new Object(), "READ")).isTrue();
|
||||
}
|
||||
@@ -62,13 +64,13 @@ 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);
|
||||
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyList())).thenReturn(acl);
|
||||
when(acl.isGranted(anyList(), anyList(), eq(false))).thenReturn(true);
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyListOf(Sid.class))).thenReturn(acl);
|
||||
when(acl.isGranted(anyListOf(Permission.class), anyListOf(Sid.class), eq(false))).thenReturn(true);
|
||||
|
||||
assertThat(pe.hasPermission(mock(Authentication.class), new Object(), "write")).isTrue();
|
||||
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ 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(
|
||||
@@ -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,7 +75,7 @@ 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)));
|
||||
|
||||
+4
-4
@@ -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");
|
||||
@@ -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);
|
||||
@@ -131,7 +131,7 @@ 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)));
|
||||
|
||||
+11
-11
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,7 +232,7 @@ 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");
|
||||
@@ -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,
|
||||
@@ -503,33 +501,34 @@ public class AclImplTests {
|
||||
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(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,39 +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();
|
||||
}
|
||||
|
||||
// ~ 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 {
|
||||
|
||||
+13
-13
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -65,14 +65,14 @@ public class AuditLoggerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() {
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
when(ace.isAuditSuccess()).thenReturn(false);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertThat(bytes.size()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() {
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
|
||||
when(ace.isAuditSuccess()).thenReturn(true);
|
||||
|
||||
logger.logIfNeeded(true, ace);
|
||||
@@ -80,14 +80,14 @@ public class AuditLoggerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() {
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
when(ace.isAuditFailure()).thenReturn(false);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertThat(bytes.size()).isZero();
|
||||
}
|
||||
|
||||
@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");
|
||||
|
||||
+23
-23
@@ -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).isNotEqualTo(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2)));
|
||||
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);
|
||||
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()).isNotEqualTo(obj2.hashCode());
|
||||
}
|
||||
|
||||
@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,9 +172,9 @@ 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);
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertThat(obj).isNotEqualTo(obj2);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+21
-21
@@ -129,10 +129,10 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101L);
|
||||
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, 102);
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, Integer.valueOf(102));
|
||||
|
||||
Map<ObjectIdentity, Acl> map = this.strategy
|
||||
.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
@@ -141,9 +141,9 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
|
||||
@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);
|
||||
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);
|
||||
@@ -158,9 +158,9 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
|
||||
@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);
|
||||
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
|
||||
@@ -171,7 +171,7 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
}
|
||||
|
||||
private void checkEntries(ObjectIdentity topParentOid, ObjectIdentity middleParentOid, ObjectIdentity childOid,
|
||||
Map<ObjectIdentity, Acl> map) {
|
||||
Map<ObjectIdentity, Acl> map) throws Exception {
|
||||
assertThat(map).hasSize(3);
|
||||
|
||||
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
|
||||
@@ -238,14 +238,14 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParentsAreRetrievedWhenChildIsLoaded() {
|
||||
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 (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);
|
||||
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);
|
||||
@@ -266,7 +266,7 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
* Test created from SEC-590.
|
||||
*/
|
||||
@Test
|
||||
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() {
|
||||
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 (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);"
|
||||
@@ -274,10 +274,10 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
+ "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);
|
||||
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
|
||||
@@ -317,7 +317,7 @@ public abstract class AbstractBasicLookupStrategyTests {
|
||||
|
||||
getJdbcTemplate().execute(query);
|
||||
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 104L);
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
|
||||
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,20 +16,21 @@
|
||||
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 static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
import java.io.Serializable;
|
||||
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;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
||||
/**
|
||||
* Tests for {@link AclClassIdUtils}.
|
||||
@@ -45,23 +46,40 @@ public class AclClassIdUtilsTest {
|
||||
private ResultSet resultSet;
|
||||
@Mock
|
||||
private ConversionService conversionService;
|
||||
|
||||
@InjectMocks
|
||||
private AclClassIdUtils aclClassIdUtils;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
aclClassIdUtils = new AclClassIdUtils();
|
||||
public void setUp() throws Exception {
|
||||
given(conversionService.canConvert(String.class, Long.class)).willReturn(true);
|
||||
given(conversionService.convert(DEFAULT_IDENTIFIER, Long.class)).willReturn(new Long(DEFAULT_IDENTIFIER));
|
||||
given(conversionService.convert(DEFAULT_IDENTIFIER_AS_STRING, Long.class)).willReturn(new Long(DEFAULT_IDENTIFIER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLongIfIdentifierIsLong() throws SQLException {
|
||||
public void shouldReturnLongIfIdentifierIsNotStringAndNoConversionService() throws SQLException {
|
||||
// given
|
||||
AclClassIdUtils aclClassIdUtilsWithoutConversionSvc = new AclClassIdUtils();
|
||||
|
||||
// when
|
||||
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER, resultSet);
|
||||
Serializable newIdentifier = aclClassIdUtilsWithoutConversionSvc.identifierFrom(DEFAULT_IDENTIFIER, resultSet);
|
||||
|
||||
// then
|
||||
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLongIfIdentifierIsNotString() throws SQLException {
|
||||
// given
|
||||
Long prevIdentifier = 999L;
|
||||
|
||||
// when
|
||||
Serializable newIdentifier = aclClassIdUtils.identifierFrom(prevIdentifier, resultSet);
|
||||
|
||||
// then
|
||||
assertThat(newIdentifier).isEqualTo(prevIdentifier);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLongIfClassIdTypeIsNull() throws SQLException {
|
||||
// given
|
||||
@@ -99,11 +117,10 @@ public class AclClassIdUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLongEvenIfCustomConversionServiceDoesNotSupportLongConversion() throws SQLException {
|
||||
public void shouldReturnLongIfTypeClassCannotBeConverted() 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);
|
||||
@@ -128,7 +145,10 @@ public class AclClassIdUtilsTest {
|
||||
public void shouldReturnUUIDWhenUUIDClassIdType() throws SQLException {
|
||||
// given
|
||||
UUID identifier = UUID.randomUUID();
|
||||
String identifierAsString = identifier.toString();
|
||||
given(resultSet.getString("class_id_type")).willReturn("java.util.UUID");
|
||||
given(conversionService.canConvert(String.class, UUID.class)).willReturn(true);
|
||||
given(conversionService.convert(identifierAsString, UUID.class)).willReturn(UUID.fromString(identifierAsString));
|
||||
|
||||
// when
|
||||
Serializable newIdentifier = aclClassIdUtils.identifierFrom(identifier.toString(), resultSet);
|
||||
@@ -137,28 +157,4 @@ public class AclClassIdUtilsTest {
|
||||
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
-1
@@ -37,7 +37,7 @@ public class BasicLookupStrategyTests extends AbstractBasicLookupStrategyTests {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() {
|
||||
public static void dropDatabase() throws Exception {
|
||||
DATABASE_HELPER.getDataSource().destroy();
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -63,18 +63,20 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() {
|
||||
public static void dropDatabase() throws Exception {
|
||||
DATABASE_HELPER.getDataSource().destroy();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeBeans() {
|
||||
super.initializeBeans();
|
||||
AclClassIdUtils aclClassIdUtils = new AclClassIdUtils();
|
||||
aclClassIdUtils.setConversionService(new DefaultConversionService());
|
||||
uuidEnabledStrategy = new BasicLookupStrategy(getDataSource(), aclCache(), aclAuthStrategy(),
|
||||
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()));
|
||||
uuidEnabledStrategy.setPermissionFactory(new DefaultPermissionFactory());
|
||||
uuidEnabledStrategy.setAclClassIdSupported(true);
|
||||
uuidEnabledStrategy.setConversionService(new DefaultConversionService());
|
||||
uuidEnabledStrategy.setAclClassIdUtils(aclClassIdUtils);
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -101,7 +103,7 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
||||
|
||||
@Test
|
||||
public void testReadObjectIdentityUsingLongTypeWithConversionServiceEnabled() {
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
Assert.assertEquals(1, foundAcls.size());
|
||||
Assert.assertNotNull(foundAcls.get(oid));
|
||||
|
||||
+15
-15
@@ -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);
|
||||
@@ -162,14 +162,14 @@ public class EhCacheBasedAclCacheTests {
|
||||
}
|
||||
|
||||
@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());
|
||||
|
||||
+15
-147
@@ -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.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
@@ -32,54 +37,19 @@ 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
|
||||
@@ -87,113 +57,11 @@ public class JdbcAclServiceTests {
|
||||
public void readAclByIdMissingAcl() {
|
||||
Map<ObjectIdentity, Acl> result = new HashMap<>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -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;
|
||||
@@ -132,7 +132,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");
|
||||
@@ -285,7 +285,7 @@ public class JdbcMutableAclServiceTests extends
|
||||
*/
|
||||
@Test
|
||||
@Transactional
|
||||
public void deleteAclAlsoDeletesChildren() {
|
||||
public void deleteAclAlsoDeletesChildren() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
jdbcMutableAclService.createAcl(getTopParentOid());
|
||||
@@ -319,11 +319,11 @@ public class JdbcMutableAclServiceTests extends
|
||||
|
||||
Acl acl = jdbcMutableAclService.readAclById(getTopParentOid());
|
||||
assertThat(acl).isNotNull();
|
||||
assertThat(getTopParentOid()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(getTopParentOid()).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 +347,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 +358,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 +374,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,7 +385,7 @@ 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());
|
||||
@@ -411,7 +411,7 @@ public class JdbcMutableAclServiceTests extends
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void deleteAclRemovesRowsFromDatabase() {
|
||||
public void deleteAclRemovesRowsFromDatabase() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
MutableAcl child = jdbcMutableAclService.createAcl(getChildOid());
|
||||
child.insertAce(0, BasePermission.DELETE, new PrincipalSid(auth), false);
|
||||
@@ -428,19 +428,19 @@ public class JdbcMutableAclServiceTests extends
|
||||
|
||||
// Check the cache
|
||||
assertThat(aclCache.getFromCache(getChildOid())).isNull();
|
||||
assertThat(aclCache.getFromCache(102L)).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 +448,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 +486,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 +507,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 +528,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
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class JdbcMutableAclServiceTestsWithAclClassId extends JdbcMutableAclServ
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void identityWithUuidIdIsSupportedByCreateAcl() {
|
||||
public void identityWithUuidIdIsSupportedByCreateAcl() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(getAuth());
|
||||
|
||||
UUID id = UUID.randomUUID();
|
||||
|
||||
+17
-17
@@ -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,33 +84,33 @@ 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));
|
||||
myCache.evictFromCache(Long.valueOf(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
|
||||
assertThat(realCache).hasSize(4);
|
||||
|
||||
myCache.evictFromCache(1L);
|
||||
myCache.evictFromCache(Long.valueOf(1));
|
||||
assertThat(realCache).hasSize(2);
|
||||
|
||||
// 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);
|
||||
@@ -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();
|
||||
|
||||
+2
-2
@@ -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);
|
||||
@@ -5,8 +5,11 @@
|
||||
|
||||
<import resource="jdbcMutableAclServiceTests-context.xml"/>
|
||||
|
||||
<bean id="conversionService" class="org.springframework.core.convert.support.DefaultConversionService"/>
|
||||
|
||||
<bean id="aclClassIdUtils" class="org.springframework.security.acls.jdbc.AclClassIdUtils">
|
||||
<property name="conversionService">
|
||||
<bean class="org.springframework.core.convert.support.DefaultConversionService"/>
|
||||
</property>
|
||||
</bean>
|
||||
<!-- Overridden bean definitions -->
|
||||
|
||||
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
|
||||
@@ -14,7 +17,7 @@
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<property name="aclClassIdSupported" value="true"/>
|
||||
<property name="conversionService" ref="conversionService"/>
|
||||
<property name="aclClassIdUtils" ref="aclClassIdUtils"/>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
|
||||
@@ -25,6 +28,6 @@
|
||||
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
<property name="aclClassIdSupported" value="true"/>
|
||||
<property name="conversionService" ref="conversionService"/>
|
||||
<property name="aclClassIdUtils" ref="aclClassIdUtils"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
apply plugin: 'io.spring.convention.spring-module'
|
||||
apply plugin: 'io.freefair.aspectj'
|
||||
apply plugin: '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
|
||||
}
|
||||
|
||||
+6
-2
@@ -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>
|
||||
+8
-8
@@ -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();
|
||||
|
||||
+1
-12
@@ -1,16 +1,13 @@
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath 'io.spring.gradle:spring-build-conventions:0.0.23.RELEASE'
|
||||
classpath 'io.spring.gradle:spring-build-conventions:0.0.25.RELEASE'
|
||||
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
|
||||
classpath 'io.spring.nohttp:nohttp-gradle:0.0.2.RELEASE'
|
||||
classpath "io.freefair.gradle:aspectj-plugin:4.0.2"
|
||||
}
|
||||
repositories {
|
||||
maven { url 'https://repo.spring.io/plugins-snapshot' }
|
||||
maven { url 'https://plugins.gradle.org/m2/' }
|
||||
}
|
||||
}
|
||||
apply plugin: 'io.spring.nohttp'
|
||||
apply plugin: 'io.spring.convention.root'
|
||||
|
||||
group = 'org.springframework.security'
|
||||
@@ -22,16 +19,8 @@ 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"
|
||||
}
|
||||
}
|
||||
|
||||
+15
-10
@@ -1,21 +1,26 @@
|
||||
apply plugin: "java-gradle-plugin"
|
||||
apply plugin: 'groovy'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
trang {
|
||||
id = "trang"
|
||||
implementationClass = "trang.TrangPlugin"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
compile gradleApi()
|
||||
}
|
||||
|
||||
// GAE
|
||||
dependencies {
|
||||
compile 'com.thaiopensource:trang:20091111'
|
||||
compile 'net.sourceforge.saxon:saxon:9.1.0.8'
|
||||
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,126 @@
|
||||
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.*
|
||||
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.api.tasks.compile.JavaCompile
|
||||
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.configurations.findByName('ajtools') == null) {
|
||||
project.configurations.create('ajtools')
|
||||
project.dependencies {
|
||||
ajtools "org.aspectj:aspectjtools"
|
||||
optional "org.aspectj:aspectjrt"
|
||||
}
|
||||
}
|
||||
|
||||
if (project.configurations.findByName('aspectpath') == null) {
|
||||
project.configurations.create('aspectpath')
|
||||
}
|
||||
|
||||
project.afterEvaluate {
|
||||
setupAspectJ(project)
|
||||
}
|
||||
}
|
||||
|
||||
void setupAspectJ(Project project) {
|
||||
project.tasks.withType(JavaCompile) { javaCompileTask ->
|
||||
def javaCompileTaskName = javaCompileTask.name
|
||||
def ajCompileTask = project.tasks.create(name: javaCompileTaskName + 'Aspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
||||
inputs.files(javaCompileTask.inputs.files)
|
||||
inputs.properties(javaCompileTask.inputs.properties)
|
||||
|
||||
sourceRoots.addAll(project.sourceSets.main.java.srcDirs)
|
||||
if(javaCompileTaskName.contains("Test")) {
|
||||
sourceRoots.addAll(project.sourceSets.test.java.srcDirs)
|
||||
}
|
||||
compileClasspath = javaCompileTask.classpath
|
||||
destinationDir = javaCompileTask.destinationDir
|
||||
aspectPath = project.configurations.aspectpath
|
||||
}
|
||||
|
||||
javaCompileTask.deleteAllActions()
|
||||
javaCompileTask.dependsOn ajCompileTask
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
Set<File> sourceRoots = []
|
||||
FileCollection compileClasspath
|
||||
File destinationDir
|
||||
FileCollection aspectPath
|
||||
|
||||
Ajc() {
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
def compile() {
|
||||
logger.info("="*30)
|
||||
logger.info("="*30)
|
||||
logger.info("Running ajc ...")
|
||||
logger.info("classpath: ${compileClasspath?.files}")
|
||||
logger.info("srcDirs ${sourceRoots}")
|
||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
|
||||
if(sourceRoots.empty) {
|
||||
return
|
||||
}
|
||||
ant.iajc(classpath: compileClasspath.asPath, fork: 'true', destDir: destinationDir.absolutePath,
|
||||
source: project.convention.plugins.java.sourceCompatibility,
|
||||
target: project.convention.plugins.java.targetCompatibility,
|
||||
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
|
||||
sourceroots {
|
||||
sourceRoots.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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 versions
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class VersionsResourceTasks extends DefaultTask {
|
||||
@OutputFile
|
||||
File versionsFile;
|
||||
|
||||
@Input
|
||||
Closure<Map<String,String>> versions;
|
||||
|
||||
void setVersions(Map<String,String> versions) {
|
||||
this.versions = { versions };
|
||||
}
|
||||
|
||||
void setVersions(Closure<Map<String,String>> versions) {
|
||||
this.versions = versions
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void generateVersions() {
|
||||
versionsFile.parentFile.mkdirs()
|
||||
versionsFile.createNewFile()
|
||||
Properties versionsProperties = new Properties()
|
||||
versionsProperties.putAll(versions.call())
|
||||
versionsProperties.store(versionsFile.newWriter(), null)
|
||||
}
|
||||
}
|
||||
@@ -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=trang.TrangPlugin
|
||||
@@ -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.");
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, Initializi
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(cache, "cache mandatory");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ class AssertionImplMixin {
|
||||
* @param attributes the key/value pairs for this attribute.
|
||||
*/
|
||||
@JsonCreator
|
||||
AssertionImplMixin(@JsonProperty("principal") AttributePrincipal principal,
|
||||
public AssertionImplMixin(@JsonProperty("principal") AttributePrincipal principal,
|
||||
@JsonProperty("validFromDate") Date validFromDate, @JsonProperty("validUntilDate") Date validUntilDate,
|
||||
@JsonProperty("authenticationDate") Date authenticationDate, @JsonProperty("attributes") Map<String, Object> attributes){
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -51,8 +51,8 @@ class AttributePrincipalImplMixin {
|
||||
* @param proxyRetriever the ProxyRetriever implementation to call back to the CAS server.
|
||||
*/
|
||||
@JsonCreator
|
||||
AttributePrincipalImplMixin(@JsonProperty("name") String name, @JsonProperty("attributes") Map<String, Object> attributes,
|
||||
public AttributePrincipalImplMixin(@JsonProperty("name") String name, @JsonProperty("attributes") Map<String, Object> attributes,
|
||||
@JsonProperty("proxyGrantingTicket") String proxyGrantingTicket,
|
||||
@JsonProperty("proxyRetriever") ProxyRetriever proxyRetriever) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -69,7 +69,7 @@ class CasAuthenticationTokenMixin {
|
||||
* principal and how to obtain a proxy ticket for the user.
|
||||
*/
|
||||
@JsonCreator
|
||||
CasAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash, @JsonProperty("principal") Object principal,
|
||||
public 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) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.cas.jackson2;
|
||||
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
|
||||
import org.jasig.cas.client.validation.AssertionImpl;
|
||||
@@ -47,7 +48,7 @@ public class CasJackson2Module extends SimpleModule {
|
||||
|
||||
@Override
|
||||
public void setupModule(SetupContext context) {
|
||||
SecurityJackson2Modules.enableDefaultTyping(context.getOwner());
|
||||
SecurityJackson2Modules.enableDefaultTyping((ObjectMapper) context.getOwner());
|
||||
context.setMixInAnnotations(AssertionImpl.class, AssertionImplMixin.class);
|
||||
context.setMixInAnnotations(AttributePrincipalImpl.class, AttributePrincipalImplMixin.class);
|
||||
context.setMixInAnnotations(CasAuthenticationToken.class, CasAuthenticationTokenMixin.class);
|
||||
|
||||
+4
-2
@@ -18,6 +18,7 @@ package org.springframework.security.cas.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -64,7 +65,7 @@ public class CasAuthenticationEntryPoint implements AuthenticationEntryPoint,
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasLength(this.loginUrl, "loginUrl must be specified");
|
||||
Assert.notNull(this.serviceProperties, "serviceProperties must be specified");
|
||||
Assert.notNull(this.serviceProperties.getService(),
|
||||
@@ -73,7 +74,8 @@ public class CasAuthenticationEntryPoint implements AuthenticationEntryPoint,
|
||||
|
||||
public final void commence(final HttpServletRequest servletRequest,
|
||||
final HttpServletResponse response,
|
||||
final AuthenticationException authenticationException) throws IOException {
|
||||
final AuthenticationException authenticationException) throws IOException,
|
||||
ServletException {
|
||||
|
||||
final String urlEncodedService = createServiceUrl(servletRequest, response);
|
||||
final String redirectUrl = createRedirectUrl(urlEncodedService);
|
||||
|
||||
@@ -415,7 +415,7 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
|
||||
private class CasAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
||||
private final AuthenticationFailureHandler serviceTicketFailureHandler;
|
||||
|
||||
CasAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
public CasAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
Assert.notNull(failureHandler, "failureHandler");
|
||||
this.serviceTicketFailureHandler = failureHandler;
|
||||
}
|
||||
@@ -432,4 +432,4 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class ServiceAuthenticationDetailsSource implements
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified ServiceProperties and the default
|
||||
* Creates an implementation that uses the specified ServiceProperites and the default
|
||||
* CAS artifactParameterName.
|
||||
*
|
||||
* @param serviceProperties The ServiceProperties to use to construct the serviceUrl.
|
||||
|
||||
+4
-2
@@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.jasig.cas.client.validation.Assertion;
|
||||
import org.jasig.cas.client.validation.AssertionImpl;
|
||||
import org.jasig.cas.client.validation.TicketValidationException;
|
||||
import org.jasig.cas.client.validation.TicketValidator;
|
||||
import org.junit.*;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
@@ -413,11 +414,12 @@ public class CasAuthenticationProviderTests {
|
||||
private class MockTicketValidator implements TicketValidator {
|
||||
private boolean returnTicket;
|
||||
|
||||
MockTicketValidator(boolean returnTicket) {
|
||||
public MockTicketValidator(boolean returnTicket) {
|
||||
this.returnTicket = returnTicket;
|
||||
}
|
||||
|
||||
public Assertion validate(final String ticket, final String service) {
|
||||
public Assertion validate(final String ticket, final String service)
|
||||
throws TicketValidationException {
|
||||
if (returnTicket) {
|
||||
return new AssertionImpl("rod");
|
||||
}
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ public class CasAuthenticationTokenMixinTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeCasAuthenticationTest() throws IOException {
|
||||
public void deserializeCasAuthenticationTest() throws IOException, JSONException {
|
||||
CasAuthenticationToken token = mapper.readValue(CAS_TOKEN_JSON, CasAuthenticationToken.class);
|
||||
assertThat(token).isNotNull();
|
||||
assertThat(token.getPrincipal()).isNotNull().isInstanceOf(User.class);
|
||||
|
||||
+9
-3
@@ -67,7 +67,11 @@ public class CasAuthenticationFilterTests {
|
||||
request.addParameter("ticket", "ST-0-ER94xMJmn6pha35CQRoZ");
|
||||
|
||||
CasAuthenticationFilter filter = new CasAuthenticationFilter();
|
||||
filter.setAuthenticationManager(a -> a);
|
||||
filter.setAuthenticationManager(new AuthenticationManager() {
|
||||
public Authentication authenticate(Authentication a) {
|
||||
return a;
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(filter.requiresAuthentication(request, new MockHttpServletResponse())).isTrue();
|
||||
|
||||
@@ -79,8 +83,10 @@ public class CasAuthenticationFilterTests {
|
||||
@Test(expected = AuthenticationException.class)
|
||||
public void testNullServiceTicketHandledGracefully() throws Exception {
|
||||
CasAuthenticationFilter filter = new CasAuthenticationFilter();
|
||||
filter.setAuthenticationManager(a -> {
|
||||
throw new BadCredentialsException("Rejected");
|
||||
filter.setAuthenticationManager(new AuthenticationManager() {
|
||||
public Authentication authenticate(Authentication a) {
|
||||
throw new BadCredentialsException("Rejected");
|
||||
}
|
||||
});
|
||||
|
||||
filter.attemptAuthentication(new MockHttpServletRequest(),
|
||||
|
||||
@@ -11,17 +11,14 @@ dependencies {
|
||||
|
||||
optional project(':spring-security-ldap')
|
||||
optional project(':spring-security-messaging')
|
||||
optional project(':spring-security-saml2-service-provider')
|
||||
optional project(':spring-security-oauth2-client')
|
||||
optional project(':spring-security-oauth2-jose')
|
||||
optional project(':spring-security-oauth2-resource-server')
|
||||
optional project(':spring-security-openid')
|
||||
optional project(':spring-security-rsocket')
|
||||
optional project(':spring-security-web')
|
||||
optional 'io.projectreactor:reactor-core'
|
||||
optional 'org.aspectj:aspectjweaver'
|
||||
optional 'org.springframework:spring-jdbc'
|
||||
optional 'org.springframework:spring-messaging'
|
||||
optional 'org.springframework:spring-tx'
|
||||
optional 'org.springframework:spring-webmvc'
|
||||
optional'org.springframework:spring-web'
|
||||
@@ -35,7 +32,6 @@ dependencies {
|
||||
testCompile project(':spring-security-test')
|
||||
testCompile project(path : ':spring-security-core', configuration : 'tests')
|
||||
testCompile project(path : ':spring-security-oauth2-client', configuration : 'tests')
|
||||
testCompile project(path : ':spring-security-oauth2-resource-server', configuration : 'tests')
|
||||
testCompile project(path : ':spring-security-web', configuration : 'tests')
|
||||
testCompile apachedsDependencies
|
||||
testCompile powerMock2Dependencies
|
||||
@@ -43,7 +39,6 @@ dependencies {
|
||||
testCompile 'com.squareup.okhttp3:mockwebserver'
|
||||
testCompile 'ch.qos.logback:logback-classic'
|
||||
testCompile 'io.projectreactor.netty:reactor-netty'
|
||||
testCompile 'io.rsocket:rsocket-transport-netty'
|
||||
testCompile 'javax.annotation:jsr250-api:1.0'
|
||||
testCompile 'javax.xml.bind:jaxb-api'
|
||||
testCompile 'ldapsdk:ldapsdk:4.1'
|
||||
@@ -78,6 +73,9 @@ dependencies {
|
||||
testRuntime 'org.hsqldb:hsqldb'
|
||||
}
|
||||
|
||||
test {
|
||||
inputs.file file("$rootDir/docs/manual/src/docbook/appendix-namespace.xml")
|
||||
}
|
||||
|
||||
rncToXsd {
|
||||
rncDir = file('src/main/resources/org/springframework/security/config/')
|
||||
|
||||
+10
-1
@@ -99,8 +99,17 @@ public class LdapServerBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
private int getDefaultPort() throws IOException {
|
||||
try (ServerSocket server = new ServerSocket(0)) {
|
||||
ServerSocket server = null;
|
||||
try {
|
||||
server = new ServerSocket(0);
|
||||
return server.getLocalPort();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
server.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -59,7 +59,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanClassNamesAreCorrect() {
|
||||
public void beanClassNamesAreCorrect() throws Exception {
|
||||
assertThat(FilterBasedLdapUserSearch.class.getName()).isEqualTo(LDAP_SEARCH_CLASS);
|
||||
assertThat(PersonContextMapper.class.getName()).isEqualTo(PERSON_MAPPER_CLASS);
|
||||
assertThat(InetOrgPersonContextMapper.class.getName()).isEqualTo(INET_ORG_PERSON_MAPPER_CLASS);
|
||||
@@ -69,12 +69,12 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalConfigurationIsParsedOk() {
|
||||
public void minimalConfigurationIsParsedOk() throws Exception {
|
||||
setContext("<ldap-user-service user-search-filter='(uid={0})' /><ldap-server ldif='classpath:test-server.ldif' url='ldap://127.0.0.1:343/dc=springframework,dc=org' />");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userServiceReturnsExpectedData() {
|
||||
public void userServiceReturnsExpectedData() throws Exception {
|
||||
setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
|
||||
|
||||
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
|
||||
@@ -86,7 +86,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentUserSearchBaseWorksAsExpected() {
|
||||
public void differentUserSearchBaseWorksAsExpected() throws Exception {
|
||||
setContext("<ldap-user-service id='ldapUDS' "
|
||||
+ " user-search-base='ou=otherpeople' "
|
||||
+ " user-search-filter='(cn={0})' "
|
||||
@@ -99,7 +99,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rolePrefixIsSupported() {
|
||||
public void rolePrefixIsSupported() throws Exception {
|
||||
setContext("<ldap-user-service id='ldapUDS' "
|
||||
+ " user-search-filter='(uid={0})' "
|
||||
+ " group-search-filter='member={0}' role-prefix='PREFIX_'/>"
|
||||
@@ -117,7 +117,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentGroupRoleAttributeWorksAsExpected() {
|
||||
public void differentGroupRoleAttributeWorksAsExpected() throws Exception {
|
||||
setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
|
||||
|
||||
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
|
||||
|
||||
@@ -53,8 +53,6 @@ public abstract class BeanIds {
|
||||
+ "methodSecurityMetadataSourceAdvisor";
|
||||
public static final String EMBEDDED_APACHE_DS = PREFIX
|
||||
+ "apacheDirectoryServerContainer";
|
||||
public static final String EMBEDDED_UNBOUNDID = PREFIX
|
||||
+ "unboundidServerContainer";
|
||||
public static final String CONTEXT_SOURCE = PREFIX + "securityContextSource";
|
||||
|
||||
public static final String DEBUG_FILTER = PREFIX + "debugFilter";
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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.config;
|
||||
|
||||
/**
|
||||
* Callback interface that accepts a single input argument and returns no result.
|
||||
*
|
||||
* @author Eleftheria Stein
|
||||
* @param <T> the type of the input to the operation
|
||||
* @since 5.2
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Customizer<T> {
|
||||
|
||||
/**
|
||||
* Performs the customizations on the input argument.
|
||||
*
|
||||
* @param t the input argument
|
||||
*/
|
||||
void customize(T t);
|
||||
|
||||
/**
|
||||
* Returns a {@link Customizer} that does not alter the input argument.
|
||||
*
|
||||
* @return a {@link Customizer} that does not alter the input argument.
|
||||
*/
|
||||
static <T> Customizer<T> withDefaults() {
|
||||
return t -> {};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -86,7 +86,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
if (!namespaceMatchesVersion(element)) {
|
||||
pc.getReaderContext()
|
||||
.fatal("You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
|
||||
+ "with Spring Security 5.2. Please update your schema declarations to the 5.2 schema.",
|
||||
+ "with Spring Security 4.2. Please update your schema declarations to the 4.2 schema.",
|
||||
element);
|
||||
}
|
||||
String name = pc.getDelegate().getLocalName(element);
|
||||
@@ -221,7 +221,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
private boolean matchesVersionInternal(Element element) {
|
||||
String schemaLocation = element.getAttributeNS(
|
||||
"http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
|
||||
return schemaLocation.matches("(?m).*spring-security-5\\.2.*.xsd.*")
|
||||
return schemaLocation.matches("(?m).*spring-security-4\\.2.*.xsd.*")
|
||||
|| schemaLocation.matches("(?m).*spring-security.xsd.*")
|
||||
|| !schemaLocation.matches("(?m).*spring-security.*");
|
||||
}
|
||||
|
||||
+9
-8
@@ -55,10 +55,10 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
extends AbstractSecurityBuilder<O> {
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<>();
|
||||
private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<>();
|
||||
private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>>();
|
||||
private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<SecurityConfigurer<O, B>>();
|
||||
|
||||
private final Map<Class<?>, Object> sharedObjects = new HashMap<>();
|
||||
private final Map<Class<? extends Object>, Object> sharedObjects = new HashMap<Class<? extends Object>, Object>();
|
||||
|
||||
private final boolean allowConfigurersOfSameType;
|
||||
|
||||
@@ -174,7 +174,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
* Gets the shared objects
|
||||
* @return the shared Objects
|
||||
*/
|
||||
public Map<Class<?>, Object> getSharedObjects() {
|
||||
public Map<Class<? extends Object>, Object> getSharedObjects() {
|
||||
return Collections.unmodifiableMap(this.sharedObjects);
|
||||
}
|
||||
|
||||
@@ -183,9 +183,10 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
* {@link SecurityConfigurer#init(SecurityBuilder)} immediately if necessary.
|
||||
*
|
||||
* @param configurer the {@link SecurityConfigurer} to add
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <C extends SecurityConfigurer<O, B>> void add(C configurer) {
|
||||
private <C extends SecurityConfigurer<O, B>> void add(C configurer) throws Exception {
|
||||
Assert.notNull(configurer, "configurer cannot be null");
|
||||
|
||||
Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer
|
||||
@@ -198,7 +199,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
List<SecurityConfigurer<O, B>> configs = allowConfigurersOfSameType ? this.configurers
|
||||
.get(clazz) : null;
|
||||
if (configs == null) {
|
||||
configs = new ArrayList<>(1);
|
||||
configs = new ArrayList<SecurityConfigurer<O, B>>(1);
|
||||
}
|
||||
configs.add(configurer);
|
||||
this.configurers.put(clazz, configs);
|
||||
@@ -385,7 +386,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
}
|
||||
|
||||
private Collection<SecurityConfigurer<O, B>> getConfigurers() {
|
||||
List<SecurityConfigurer<O, B>> result = new ArrayList<>();
|
||||
List<SecurityConfigurer<O, B>> result = new ArrayList<SecurityConfigurer<O, B>>();
|
||||
for (List<SecurityConfigurer<O, B>> configs : this.configurers.values()) {
|
||||
result.addAll(configs);
|
||||
}
|
||||
@@ -408,7 +409,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
|
||||
* @author Rob Winch
|
||||
* @since 3.2
|
||||
*/
|
||||
private enum BuildState {
|
||||
private static enum BuildState {
|
||||
/**
|
||||
* This is the state before the {@link Builder#build()} is invoked
|
||||
*/
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
|
||||
* Initialize the {@link SecurityBuilder}. Here only shared state should be created
|
||||
* and modified, but not properties on the {@link SecurityBuilder} used for building
|
||||
* the object. This ensures that the {@link #configure(SecurityBuilder)} method uses
|
||||
* the correct shared objects when building. Configurers should be applied here.
|
||||
* the correct shared objects when building.
|
||||
*
|
||||
* @param builder
|
||||
* @throws Exception
|
||||
|
||||
+4
-3
@@ -16,6 +16,7 @@
|
||||
package org.springframework.security.config.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
@@ -110,7 +111,7 @@ public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>>
|
||||
*/
|
||||
private static final class CompositeObjectPostProcessor implements
|
||||
ObjectPostProcessor<Object> {
|
||||
private List<ObjectPostProcessor<?>> postProcessors = new ArrayList<>();
|
||||
private List<ObjectPostProcessor<? extends Object>> postProcessors = new ArrayList<ObjectPostProcessor<?>>();
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public Object postProcess(Object object) {
|
||||
@@ -131,9 +132,9 @@ public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>>
|
||||
* @return true if the {@link ObjectPostProcessor} was added, else false
|
||||
*/
|
||||
private boolean addObjectPostProcessor(
|
||||
ObjectPostProcessor<?> objectPostProcessor) {
|
||||
ObjectPostProcessor<? extends Object> objectPostProcessor) {
|
||||
boolean result = this.postProcessors.add(objectPostProcessor);
|
||||
postProcessors.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
Collections.sort(postProcessors, AnnotationAwareOrderComparator.INSTANCE);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -287,6 +287,6 @@ public class AuthenticationManagerBuilder
|
||||
private <C extends UserDetailsAwareConfigurer<AuthenticationManagerBuilder, ? extends UserDetailsService>> C apply(
|
||||
C configurer) throws Exception {
|
||||
this.defaultUserDetailsService = configurer.getUserDetailsService();
|
||||
return super.apply(configurer);
|
||||
return (C) super.apply(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,15 +15,21 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.authentication.configuration;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
import org.springframework.aop.target.LazyInitTargetSource;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -43,12 +49,6 @@ import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Exports the authentication {@link Configuration}
|
||||
*
|
||||
@@ -56,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @since 3.2
|
||||
*
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Configuration
|
||||
@Import(ObjectPostProcessorConfiguration.class)
|
||||
public class AuthenticationConfiguration {
|
||||
|
||||
@@ -106,7 +106,8 @@ public class AuthenticationConfiguration {
|
||||
if (this.authenticationManagerInitialized) {
|
||||
return this.authenticationManager;
|
||||
}
|
||||
AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean(AuthenticationManagerBuilder.class);
|
||||
AuthenticationManagerBuilder authBuilder = authenticationManagerBuilder(
|
||||
this.objectPostProcessor, this.applicationContext);
|
||||
if (this.buildingAuthenticationManager.getAndSet(true)) {
|
||||
return new AuthenticationManagerDelegator(authBuilder);
|
||||
}
|
||||
@@ -127,8 +128,8 @@ public class AuthenticationConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setGlobalAuthenticationConfigurers(
|
||||
List<GlobalAuthenticationConfigurerAdapter> configurers) {
|
||||
configurers.sort(AnnotationAwareOrderComparator.INSTANCE);
|
||||
List<GlobalAuthenticationConfigurerAdapter> configurers) throws Exception {
|
||||
Collections.sort(configurers, AnnotationAwareOrderComparator.INSTANCE);
|
||||
this.globalAuthConfigurers = configurers;
|
||||
}
|
||||
|
||||
@@ -150,20 +151,10 @@ public class AuthenticationConfiguration {
|
||||
if (beanNamesForType.length == 0) {
|
||||
return null;
|
||||
}
|
||||
String beanName;
|
||||
if (beanNamesForType.length > 1) {
|
||||
List<String> primaryBeanNames = getPrimaryBeanNames(beanNamesForType);
|
||||
|
||||
Assert.isTrue(primaryBeanNames.size() != 0, () -> "Found " + beanNamesForType.length
|
||||
+ " beans for type " + interfaceName + ", but none marked as primary");
|
||||
Assert.isTrue(primaryBeanNames.size() == 1, () -> "Found " + primaryBeanNames.size()
|
||||
+ " beans for type " + interfaceName + " marked as primary");
|
||||
beanName = primaryBeanNames.get(0);
|
||||
} else {
|
||||
beanName = beanNamesForType[0];
|
||||
}
|
||||
|
||||
lazyTargetSource.setTargetBeanName(beanName);
|
||||
Assert.isTrue(beanNamesForType.length == 1,
|
||||
() -> "Expecting to only find a single bean for type " + interfaceName
|
||||
+ ", but found " + Arrays.asList(beanNamesForType));
|
||||
lazyTargetSource.setTargetBeanName(beanNamesForType[0]);
|
||||
lazyTargetSource.setBeanFactory(applicationContext);
|
||||
ProxyFactoryBean proxyFactory = new ProxyFactoryBean();
|
||||
proxyFactory = objectPostProcessor.postProcess(proxyFactory);
|
||||
@@ -171,20 +162,6 @@ public class AuthenticationConfiguration {
|
||||
return (T) proxyFactory.getObject();
|
||||
}
|
||||
|
||||
private List<String> getPrimaryBeanNames(String[] beanNamesForType) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
for (String beanName : beanNamesForType) {
|
||||
if (((ConfigurableApplicationContext) applicationContext).getBeanFactory()
|
||||
.getBeanDefinition(beanName).isPrimary()) {
|
||||
list.add(beanName);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private AuthenticationManager getAuthenticationManagerBean() {
|
||||
return lazyBean(AuthenticationManager.class);
|
||||
}
|
||||
@@ -203,7 +180,7 @@ public class AuthenticationConfiguration {
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(EnableGlobalAuthenticationAutowiredConfigurer.class);
|
||||
|
||||
EnableGlobalAuthenticationAutowiredConfigurer(ApplicationContext context) {
|
||||
public EnableGlobalAuthenticationAutowiredConfigurer(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -42,7 +42,7 @@ class InitializeAuthenticationProviderBeanManagerConfigurer
|
||||
/**
|
||||
* @param context the ApplicationContext to look up beans.
|
||||
*/
|
||||
InitializeAuthenticationProviderBeanManagerConfigurer(
|
||||
public InitializeAuthenticationProviderBeanManagerConfigurer(
|
||||
ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class InitializeAuthenticationProviderBeanManagerConfigurer
|
||||
class InitializeUserDetailsManagerConfigurer
|
||||
extends GlobalAuthenticationConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(AuthenticationManagerBuilder auth) {
|
||||
public void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
if (auth.isConfigured()) {
|
||||
return;
|
||||
}
|
||||
@@ -83,4 +83,4 @@ class InitializeAuthenticationProviderBeanManagerConfigurer
|
||||
.getBean(userDetailsBeanNames[0], type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -43,7 +43,7 @@ class InitializeUserDetailsBeanManagerConfigurer
|
||||
/**
|
||||
* @param context
|
||||
*/
|
||||
InitializeUserDetailsBeanManagerConfigurer(ApplicationContext context) {
|
||||
public InitializeUserDetailsBeanManagerConfigurer(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class InitializeUserDetailsBeanManagerConfigurer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a bean of the requested class if there's just a single registered component, null otherwise.
|
||||
* @return
|
||||
*/
|
||||
private <T> T getBeanOrNull(Class<T> type) {
|
||||
String[] userDetailsBeanNames = InitializeUserDetailsBeanManagerConfigurer.this.context
|
||||
|
||||
+19
-7
@@ -64,8 +64,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
*
|
||||
* @param dataSource the {@link DataSource} to be used. Cannot be null.
|
||||
* @return The {@link JdbcUserDetailsManagerConfigurer} used for additional customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> dataSource(DataSource dataSource) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> dataSource(DataSource dataSource)
|
||||
throws Exception {
|
||||
this.dataSource = dataSource;
|
||||
getUserDetailsService().setDataSource(dataSource);
|
||||
return this;
|
||||
@@ -81,8 +83,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
* is enabled by username. Must contain a single parameter for the username.
|
||||
* @return The {@link JdbcUserDetailsManagerConfigurer} used for additional
|
||||
* customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> usersByUsernameQuery(String query) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> usersByUsernameQuery(String query)
|
||||
throws Exception {
|
||||
getUserDetailsService().setUsersByUsernameQuery(query);
|
||||
return this;
|
||||
}
|
||||
@@ -99,8 +103,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
* Must contain a single parameter for the username.
|
||||
* @return The {@link JdbcUserDetailsManagerConfigurer} used for additional
|
||||
* customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> authoritiesByUsernameQuery(String query) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> authoritiesByUsernameQuery(String query)
|
||||
throws Exception {
|
||||
getUserDetailsService().setAuthoritiesByUsernameQuery(query);
|
||||
return this;
|
||||
}
|
||||
@@ -121,8 +127,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
* a single parameter for the username.
|
||||
* @return The {@link JdbcUserDetailsManagerConfigurer} used for additional
|
||||
* customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> groupAuthoritiesByUsername(String query) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> groupAuthoritiesByUsername(String query)
|
||||
throws Exception {
|
||||
JdbcUserDetailsManager userDetailsService = getUserDetailsService();
|
||||
userDetailsService.setEnableGroups(true);
|
||||
userDetailsService.setGroupAuthoritiesByUsernameQuery(query);
|
||||
@@ -135,8 +143,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
*
|
||||
* @param rolePrefix
|
||||
* @return The {@link JdbcUserDetailsManagerConfigurer} used for additional customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> rolePrefix(String rolePrefix) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> rolePrefix(String rolePrefix)
|
||||
throws Exception {
|
||||
getUserDetailsService().setRolePrefix(rolePrefix);
|
||||
return this;
|
||||
}
|
||||
@@ -146,8 +156,10 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
*
|
||||
* @param userCache the {@link UserCache} to use
|
||||
* @return the {@link JdbcUserDetailsManagerConfigurer} for further customizations
|
||||
* @throws Exception
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<B> userCache(UserCache userCache) {
|
||||
public JdbcUserDetailsManagerConfigurer<B> userCache(UserCache userCache)
|
||||
throws Exception {
|
||||
getUserDetailsService().setUserCache(userCache);
|
||||
return this;
|
||||
}
|
||||
@@ -179,7 +191,7 @@ public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B
|
||||
|
||||
protected DatabasePopulator getDatabasePopulator() {
|
||||
ResourceDatabasePopulator dbp = new ResourceDatabasePopulator();
|
||||
dbp.setScripts(initScripts.toArray(new Resource[0]));
|
||||
dbp.setScripts(initScripts.toArray(new Resource[initScripts.size()]));
|
||||
return dbp;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ final class AutowireBeanFactoryObjectPostProcessor
|
||||
private final List<DisposableBean> disposableBeans = new ArrayList<>();
|
||||
private final List<SmartInitializingSingleton> smartSingletons = new ArrayList<>();
|
||||
|
||||
AutowireBeanFactoryObjectPostProcessor(
|
||||
public AutowireBeanFactoryObjectPostProcessor(
|
||||
AutowireCapableBeanFactory autowireBeanFactory) {
|
||||
Assert.notNull(autowireBeanFactory, "autowireBeanFactory cannot be null");
|
||||
this.autowireBeanFactory = autowireBeanFactory;
|
||||
@@ -97,7 +97,7 @@ final class AutowireBeanFactoryObjectPostProcessor
|
||||
*
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
public void destroy() throws Exception {
|
||||
for (DisposableBean disposable : this.disposableBeans) {
|
||||
try {
|
||||
disposable.destroy();
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +16,8 @@
|
||||
package org.springframework.security.config.annotation.configuration;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
@@ -35,12 +33,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
||||
* @author Rob Winch
|
||||
* @since 3.2
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@Configuration
|
||||
public class ObjectPostProcessorConfiguration {
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public ObjectPostProcessor<Object> objectPostProcessor(
|
||||
AutowireCapableBeanFactory beanFactory) {
|
||||
return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
|
||||
|
||||
+17
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* 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.
|
||||
@@ -29,8 +29,10 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
@@ -80,8 +82,7 @@ import org.springframework.util.Assert;
|
||||
* @since 3.2
|
||||
* @see EnableGlobalMethodSecurity
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@Configuration
|
||||
public class GlobalMethodSecurityConfiguration
|
||||
implements ImportAware, SmartInitializingSingleton, BeanFactoryAware {
|
||||
private static final Log logger = LogFactory
|
||||
@@ -109,6 +110,7 @@ public class GlobalMethodSecurityConfiguration
|
||||
* <li>{@link #accessDecisionManager()}</li>
|
||||
* <li>{@link #afterInvocationManager()}</li>
|
||||
* <li>{@link #authenticationManager()}</li>
|
||||
* <li>{@link #methodSecurityMetadataSource()}</li>
|
||||
* <li>{@link #runAsManager()}</li>
|
||||
*
|
||||
* </ul>
|
||||
@@ -117,19 +119,19 @@ public class GlobalMethodSecurityConfiguration
|
||||
* Subclasses can override this method to provide a different
|
||||
* {@link MethodInterceptor}.
|
||||
* </p>
|
||||
* @param methodSecurityMetadataSource the default {@link MethodSecurityMetadataSource}.
|
||||
*
|
||||
* @return the {@link MethodInterceptor}.
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public MethodInterceptor methodSecurityInterceptor(MethodSecurityMetadataSource methodSecurityMetadataSource) {
|
||||
public MethodInterceptor methodSecurityInterceptor() throws Exception {
|
||||
this.methodSecurityInterceptor = isAspectJ()
|
||||
? new AspectJMethodSecurityInterceptor()
|
||||
: new MethodSecurityInterceptor();
|
||||
methodSecurityInterceptor.setAccessDecisionManager(accessDecisionManager());
|
||||
methodSecurityInterceptor.setAfterInvocationManager(afterInvocationManager());
|
||||
methodSecurityInterceptor
|
||||
.setSecurityMetadataSource(methodSecurityMetadataSource);
|
||||
.setSecurityMetadataSource(methodSecurityMetadataSource());
|
||||
RunAsManager runAsManager = runAsManager();
|
||||
if (runAsManager != null) {
|
||||
methodSecurityInterceptor.setRunAsManager(runAsManager);
|
||||
@@ -195,8 +197,8 @@ public class GlobalMethodSecurityConfiguration
|
||||
|
||||
/**
|
||||
* Provide a custom {@link AfterInvocationManager} for the default implementation of
|
||||
* {@link #methodSecurityInterceptor(MethodSecurityMetadataSource)}. The default is null
|
||||
* if pre post is not enabled. Otherwise, it returns a {@link AfterInvocationProviderManager}.
|
||||
* {@link #methodSecurityInterceptor()}. The default is null if pre post is not
|
||||
* enabled. Otherwise, it returns a {@link AfterInvocationProviderManager}.
|
||||
*
|
||||
* <p>
|
||||
* Subclasses should override this method to provide a custom
|
||||
@@ -222,7 +224,7 @@ public class GlobalMethodSecurityConfiguration
|
||||
|
||||
/**
|
||||
* Provide a custom {@link RunAsManager} for the default implementation of
|
||||
* {@link #methodSecurityInterceptor(MethodSecurityMetadataSource)}. The default is null.
|
||||
* {@link #methodSecurityInterceptor()}. The default is null.
|
||||
*
|
||||
* @return the {@link RunAsManager} to use
|
||||
*/
|
||||
@@ -243,24 +245,17 @@ public class GlobalMethodSecurityConfiguration
|
||||
* @return the {@link AccessDecisionManager} to use
|
||||
*/
|
||||
protected AccessDecisionManager accessDecisionManager() {
|
||||
List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
|
||||
List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<AccessDecisionVoter<? extends Object>>();
|
||||
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
|
||||
expressionAdvice.setExpressionHandler(getExpressionHandler());
|
||||
if (prePostEnabled()) {
|
||||
ExpressionBasedPreInvocationAdvice expressionAdvice =
|
||||
new ExpressionBasedPreInvocationAdvice();
|
||||
expressionAdvice.setExpressionHandler(getExpressionHandler());
|
||||
decisionVoters
|
||||
.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
|
||||
}
|
||||
if (jsr250Enabled()) {
|
||||
decisionVoters.add(new Jsr250Voter());
|
||||
}
|
||||
RoleVoter roleVoter = new RoleVoter();
|
||||
GrantedAuthorityDefaults grantedAuthorityDefaults =
|
||||
getSingleBeanOrNull(GrantedAuthorityDefaults.class);
|
||||
if (grantedAuthorityDefaults != null) {
|
||||
roleVoter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
decisionVoters.add(roleVoter);
|
||||
decisionVoters.add(new RoleVoter());
|
||||
decisionVoters.add(new AuthenticatedVoter());
|
||||
return new AffirmativeBased(decisionVoters);
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
final class GlobalMethodSecuritySelector implements ImportSelector {
|
||||
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
Class<EnableGlobalMethodSecurity> annoType = EnableGlobalMethodSecurity.class;
|
||||
Map<String, Object> annotationAttributes = importingClassMetadata
|
||||
.getAnnotationAttributes(annoType.getName(), false);
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 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,18 +15,14 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.method.configuration;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@Configuration
|
||||
class Jsr250MetadataSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public Jsr250MethodSecurityMetadataSource jsr250MethodSecurityMetadataSource() {
|
||||
return new Jsr250MethodSecurityMetadataSource();
|
||||
}
|
||||
|
||||
+6
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.security.config.annotation.method.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -29,24 +28,20 @@ import org.springframework.security.access.method.AbstractMethodSecurityMetadata
|
||||
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
|
||||
import org.springframework.security.access.prepost.PrePostAdviceReactiveMethodInterceptor;
|
||||
import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource;
|
||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @author Tadaya Tsuyukubo
|
||||
* @since 5.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Configuration
|
||||
class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
private int advisorOrder;
|
||||
|
||||
private GrantedAuthorityDefaults grantedAuthorityDefaults;
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source) {
|
||||
public MethodSecurityMetadataSourceAdvisor methodSecurityInterceptor(AbstractMethodSecurityMetadataSource source) throws Exception {
|
||||
MethodSecurityMetadataSourceAdvisor advisor = new MethodSecurityMetadataSourceAdvisor(
|
||||
"securityMethodInterceptor", source, "methodMetadataSource");
|
||||
advisor.setOrder(advisorOrder);
|
||||
@@ -54,10 +49,9 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public DelegatingMethodSecurityMetadataSource methodMetadataSource(MethodSecurityExpressionHandler methodSecurityExpressionHandler) {
|
||||
public DelegatingMethodSecurityMetadataSource methodMetadataSource() {
|
||||
ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(
|
||||
methodSecurityExpressionHandler);
|
||||
new DefaultMethodSecurityExpressionHandler());
|
||||
PrePostAnnotationSecurityMetadataSource prePostSource = new PrePostAnnotationSecurityMetadataSource(
|
||||
attributeFactory);
|
||||
return new DelegatingMethodSecurityMetadataSource(Arrays.asList(prePostSource));
|
||||
@@ -75,23 +69,12 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler() {
|
||||
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
|
||||
if (this.grantedAuthorityDefaults != null) {
|
||||
handler.setDefaultRolePrefix(this.grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
return handler;
|
||||
return new DefaultMethodSecurityExpressionHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.advisorOrder = (int) importMetadata.getAnnotationAttributes(EnableReactiveMethodSecurity.class.getName()).get("order");
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) {
|
||||
this.grantedAuthorityDefaults = grantedAuthorityDefaults;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -48,6 +48,6 @@ class ReactiveMethodSecuritySelector extends
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(AutoProxyRegistrar.class.getName());
|
||||
result.add(ReactiveMethodSecurityConfiguration.class.getName());
|
||||
return result.toArray(new String[0]);
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.config.annotation.rsocket;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Add this annotation to a {@code Configuration} class to have Spring Security
|
||||
* {@link RSocketSecurity} support added.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.2
|
||||
* @see RSocketSecurity
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Import({ RSocketSecurityConfiguration.class, SecuritySocketAcceptorInterceptorConfiguration.class })
|
||||
public @interface EnableRSocketSecurity { }
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.config.annotation.rsocket;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
||||
|
||||
/**
|
||||
* The standard order for {@link PayloadInterceptor} to be
|
||||
* sorted. The actual values might change, so users should use the {@link #getOrder()} method to
|
||||
* calculate the position dynamically rather than copy values.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.2
|
||||
*/
|
||||
public enum PayloadInterceptorOrder implements Ordered {
|
||||
/**
|
||||
* Where basic authentication is placed.
|
||||
* @see RSocketSecurity#basicAuthentication(Customizer)
|
||||
*/
|
||||
BASIC_AUTHENTICATION,
|
||||
/**
|
||||
* Where JWT based authentication is performed.
|
||||
* @see RSocketSecurity#jwt(Customizer)
|
||||
*/
|
||||
JWT_AUTHENTICATION,
|
||||
/**
|
||||
* A generic placeholder for other types of authentication.
|
||||
* @see org.springframework.security.rsocket.authentication.AuthenticationPayloadInterceptor
|
||||
*/
|
||||
AUTHENTICATION,
|
||||
/**
|
||||
* Where anonymous authentication is placed.
|
||||
*/
|
||||
ANONYMOUS,
|
||||
/**
|
||||
* Where authorization is placed.
|
||||
* @see org.springframework.security.rsocket.authorization.AuthorizationPayloadInterceptor
|
||||
*/
|
||||
AUTHORIZATION;
|
||||
|
||||
private static final int INTERVAL = 100;
|
||||
|
||||
private int order;
|
||||
|
||||
PayloadInterceptorOrder() {
|
||||
this.order = ordinal() * INTERVAL;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
}
|
||||
-378
@@ -1,378 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.config.annotation.rsocket;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
||||
import org.springframework.security.authentication.ReactiveAuthenticationManager;
|
||||
import org.springframework.security.authorization.AuthenticatedReactiveAuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorityReactiveAuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
||||
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
||||
import org.springframework.security.rsocket.core.PayloadSocketAcceptorInterceptor;
|
||||
import org.springframework.security.rsocket.authentication.AnonymousPayloadInterceptor;
|
||||
import org.springframework.security.rsocket.authentication.AuthenticationPayloadInterceptor;
|
||||
import org.springframework.security.rsocket.authentication.BearerPayloadExchangeConverter;
|
||||
import org.springframework.security.rsocket.authorization.AuthorizationPayloadInterceptor;
|
||||
import org.springframework.security.rsocket.authorization.PayloadExchangeMatcherReactiveAuthorizationManager;
|
||||
import org.springframework.security.rsocket.util.matcher.PayloadExchangeAuthorizationContext;
|
||||
import org.springframework.security.rsocket.util.matcher.PayloadExchangeMatcher;
|
||||
import org.springframework.security.rsocket.util.matcher.PayloadExchangeMatcherEntry;
|
||||
import org.springframework.security.rsocket.util.matcher.PayloadExchangeMatchers;
|
||||
import org.springframework.security.rsocket.util.matcher.RoutePayloadExchangeMatcher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Allows configuring RSocket based security.
|
||||
*
|
||||
* A minimal example can be found below:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @EnableRSocketSecurity
|
||||
* public class SecurityConfig {
|
||||
* // @formatter:off
|
||||
* @Bean
|
||||
* PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity rsocket) {
|
||||
* rsocket
|
||||
* .authorizePayload(authorize ->
|
||||
* authorize
|
||||
* .anyRequest().authenticated()
|
||||
* );
|
||||
* return rsocket.build();
|
||||
* }
|
||||
* // @formatter:on
|
||||
*
|
||||
* // @formatter:off
|
||||
* @Bean
|
||||
* public MapReactiveUserDetailsService userDetailsService() {
|
||||
* UserDetails user = User.withDefaultPasswordEncoder()
|
||||
* .username("user")
|
||||
* .password("password")
|
||||
* .roles("USER")
|
||||
* .build();
|
||||
* return new MapReactiveUserDetailsService(user);
|
||||
* }
|
||||
* // @formatter:on
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* A more advanced configuration can be seen below:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @EnableRSocketSecurity
|
||||
* public class SecurityConfig {
|
||||
* // @formatter:off
|
||||
* @Bean
|
||||
* PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity rsocket) {
|
||||
* rsocket
|
||||
* .authorizePayload(authorize ->
|
||||
* authorize
|
||||
* // must have ROLE_SETUP to make connection
|
||||
* .setup().hasRole("SETUP")
|
||||
* // must have ROLE_ADMIN for routes starting with "admin."
|
||||
* .route("admin.*").hasRole("ADMIN")
|
||||
* // any other request must be authenticated for
|
||||
* .anyRequest().authenticated()
|
||||
* );
|
||||
* return rsocket.build();
|
||||
* }
|
||||
* // @formatter:on
|
||||
* }
|
||||
* </pre>
|
||||
* @author Rob Winch
|
||||
* @author Jesús Ascama Arias
|
||||
* @author Luis Felipe Vega
|
||||
* @author Manuel Tejeda
|
||||
* @author Ebert Toribio
|
||||
* @since 5.2
|
||||
*/
|
||||
public class RSocketSecurity {
|
||||
|
||||
private List<PayloadInterceptor> payloadInterceptors = new ArrayList<>();
|
||||
|
||||
private BasicAuthenticationSpec basicAuthSpec;
|
||||
|
||||
private JwtSpec jwtSpec;
|
||||
|
||||
private AuthorizePayloadsSpec authorizePayload;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private ReactiveAuthenticationManager authenticationManager;
|
||||
|
||||
/**
|
||||
* Adds a {@link PayloadInterceptor} to be used. This is typically only used
|
||||
* when using the DSL does not meet a users needs. In order to ensure the
|
||||
* {@link PayloadInterceptor} is done in the proper order the {@link PayloadInterceptor} should
|
||||
* either implement {@link org.springframework.core.Ordered} or be annotated with
|
||||
* {@link org.springframework.core.annotation.Order}.
|
||||
*
|
||||
* @param interceptor
|
||||
* @return the builder for additional customizations
|
||||
* @see PayloadInterceptorOrder
|
||||
*/
|
||||
public RSocketSecurity addPayloadInterceptor(PayloadInterceptor interceptor) {
|
||||
this.payloadInterceptors.add(interceptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RSocketSecurity authenticationManager(ReactiveAuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RSocketSecurity basicAuthentication(Customizer<BasicAuthenticationSpec> basic) {
|
||||
if (this.basicAuthSpec == null) {
|
||||
this.basicAuthSpec = new BasicAuthenticationSpec();
|
||||
}
|
||||
basic.customize(this.basicAuthSpec);
|
||||
return this;
|
||||
}
|
||||
|
||||
public class BasicAuthenticationSpec {
|
||||
private ReactiveAuthenticationManager authenticationManager;
|
||||
|
||||
public BasicAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
private ReactiveAuthenticationManager getAuthenticationManager() {
|
||||
if (this.authenticationManager == null) {
|
||||
return RSocketSecurity.this.authenticationManager;
|
||||
}
|
||||
return this.authenticationManager;
|
||||
}
|
||||
|
||||
protected AuthenticationPayloadInterceptor build() {
|
||||
ReactiveAuthenticationManager manager = getAuthenticationManager();
|
||||
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
|
||||
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
|
||||
return result;
|
||||
}
|
||||
|
||||
private BasicAuthenticationSpec() {}
|
||||
}
|
||||
|
||||
public RSocketSecurity jwt(Customizer<JwtSpec> jwt) {
|
||||
if (this.jwtSpec == null) {
|
||||
this.jwtSpec = new JwtSpec();
|
||||
}
|
||||
jwt.customize(this.jwtSpec);
|
||||
return this;
|
||||
}
|
||||
|
||||
public class JwtSpec {
|
||||
private ReactiveAuthenticationManager authenticationManager;
|
||||
|
||||
public JwtSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
private ReactiveAuthenticationManager getAuthenticationManager() {
|
||||
if (this.authenticationManager != null) {
|
||||
return this.authenticationManager;
|
||||
}
|
||||
ReactiveJwtDecoder jwtDecoder = getBeanOrNull(ReactiveJwtDecoder.class);
|
||||
if (jwtDecoder != null) {
|
||||
this.authenticationManager = new JwtReactiveAuthenticationManager(jwtDecoder);
|
||||
return this.authenticationManager;
|
||||
}
|
||||
return RSocketSecurity.this.authenticationManager;
|
||||
}
|
||||
|
||||
protected AuthenticationPayloadInterceptor build() {
|
||||
ReactiveAuthenticationManager manager = getAuthenticationManager();
|
||||
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
|
||||
result.setAuthenticationConverter(new BearerPayloadExchangeConverter());
|
||||
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
|
||||
return result;
|
||||
}
|
||||
|
||||
private JwtSpec() {}
|
||||
}
|
||||
|
||||
public RSocketSecurity authorizePayload(Customizer<AuthorizePayloadsSpec> authorize) {
|
||||
if (this.authorizePayload == null) {
|
||||
this.authorizePayload = new AuthorizePayloadsSpec();
|
||||
}
|
||||
authorize.customize(this.authorizePayload);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PayloadSocketAcceptorInterceptor build() {
|
||||
PayloadSocketAcceptorInterceptor interceptor = new PayloadSocketAcceptorInterceptor(
|
||||
payloadInterceptors());
|
||||
RSocketMessageHandler handler = getBean(RSocketMessageHandler.class);
|
||||
interceptor.setDefaultDataMimeType(handler.getDefaultDataMimeType());
|
||||
interceptor.setDefaultMetadataMimeType(handler.getDefaultMetadataMimeType());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
private List<PayloadInterceptor> payloadInterceptors() {
|
||||
List<PayloadInterceptor> result = new ArrayList<>(this.payloadInterceptors);
|
||||
|
||||
if (this.basicAuthSpec != null) {
|
||||
result.add(this.basicAuthSpec.build());
|
||||
}
|
||||
if (this.jwtSpec != null) {
|
||||
result.add(this.jwtSpec.build());
|
||||
}
|
||||
result.add(anonymous());
|
||||
|
||||
if (this.authorizePayload != null) {
|
||||
result.add(this.authorizePayload.build());
|
||||
}
|
||||
AnnotationAwareOrderComparator.sort(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private AnonymousPayloadInterceptor anonymous() {
|
||||
AnonymousPayloadInterceptor result = new AnonymousPayloadInterceptor("anonymousUser");
|
||||
result.setOrder(PayloadInterceptorOrder.ANONYMOUS.getOrder());
|
||||
return result;
|
||||
}
|
||||
|
||||
public class AuthorizePayloadsSpec {
|
||||
|
||||
private PayloadExchangeMatcherReactiveAuthorizationManager.Builder authzBuilder =
|
||||
PayloadExchangeMatcherReactiveAuthorizationManager.builder();
|
||||
|
||||
public Access setup() {
|
||||
return matcher(PayloadExchangeMatchers.setup());
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches if {@link org.springframework.security.rsocket.api.PayloadExchangeType#isRequest()} is true, else
|
||||
* not a match
|
||||
* @return the Access to set up the authorization rule.
|
||||
*/
|
||||
public Access anyRequest() {
|
||||
return matcher(PayloadExchangeMatchers.anyRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Always matches
|
||||
* @return the Access to set up the authorization rule.
|
||||
*/
|
||||
public Access anyExchange() {
|
||||
return matcher(PayloadExchangeMatchers.anyExchange());
|
||||
}
|
||||
|
||||
protected AuthorizationPayloadInterceptor build() {
|
||||
AuthorizationPayloadInterceptor result = new AuthorizationPayloadInterceptor(this.authzBuilder.build());
|
||||
result.setOrder(PayloadInterceptorOrder.AUTHORIZATION.getOrder());
|
||||
return result;
|
||||
}
|
||||
|
||||
public Access route(String pattern) {
|
||||
RSocketMessageHandler handler = getBean(RSocketMessageHandler.class);
|
||||
PayloadExchangeMatcher matcher = new RoutePayloadExchangeMatcher(
|
||||
handler.getMetadataExtractor(),
|
||||
handler.getRouteMatcher(),
|
||||
pattern);
|
||||
return matcher(matcher);
|
||||
}
|
||||
|
||||
public Access matcher(PayloadExchangeMatcher matcher) {
|
||||
return new Access(matcher);
|
||||
}
|
||||
|
||||
public class Access {
|
||||
|
||||
private final PayloadExchangeMatcher matcher;
|
||||
|
||||
private Access(PayloadExchangeMatcher matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec authenticated() {
|
||||
return access(AuthenticatedReactiveAuthorizationManager.authenticated());
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec hasAuthority(String authority) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasAuthority(authority));
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec hasRole(String role) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasRole(role));
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec hasAnyRole(String... roles) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasAnyRole(roles));
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec permitAll() {
|
||||
return access((a, ctx) -> Mono
|
||||
.just(new AuthorizationDecision(true)));
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec hasAnyAuthority(String... authorities) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasAnyAuthority(authorities));
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec access(
|
||||
ReactiveAuthorizationManager<PayloadExchangeAuthorizationContext> authorization) {
|
||||
AuthorizePayloadsSpec.this.authzBuilder.add(new PayloadExchangeMatcherEntry<>(this.matcher, authorization));
|
||||
return AuthorizePayloadsSpec.this;
|
||||
}
|
||||
|
||||
public AuthorizePayloadsSpec denyAll() {
|
||||
return access((a, ctx) -> Mono
|
||||
.just(new AuthorizationDecision(false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getBean(Class<T> beanClass) {
|
||||
if (this.context == null) {
|
||||
return null;
|
||||
}
|
||||
return this.context.getBean(beanClass);
|
||||
}
|
||||
|
||||
private <T> T getBeanOrNull(Class<T> beanClass) {
|
||||
return getBeanOrNull(ResolvableType.forClass(beanClass));
|
||||
}
|
||||
|
||||
private <T> T getBeanOrNull(ResolvableType type) {
|
||||
if (this.context == null) {
|
||||
return null;
|
||||
}
|
||||
String[] names = this.context.getBeanNamesForType(type);
|
||||
if (names.length == 1) {
|
||||
return (T) this.context.getBean(names[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.config.annotation.rsocket;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.security.authentication.ReactiveAuthenticationManager;
|
||||
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager;
|
||||
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.2
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class RSocketSecurityConfiguration {
|
||||
|
||||
private static final String BEAN_NAME_PREFIX = "org.springframework.security.config.annotation.rsocket.RSocketSecurityConfiguration.";
|
||||
private static final String RSOCKET_SECURITY_BEAN_NAME = BEAN_NAME_PREFIX + "rsocketSecurity";
|
||||
|
||||
private ReactiveAuthenticationManager authenticationManager;
|
||||
|
||||
private ReactiveUserDetailsService reactiveUserDetailsService;
|
||||
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired(required = false)
|
||||
void setAuthenticationManager(
|
||||
ReactiveAuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
void setUserDetailsService(ReactiveUserDetailsService userDetailsService) {
|
||||
this.reactiveUserDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@Bean(name = RSOCKET_SECURITY_BEAN_NAME)
|
||||
@Scope("prototype")
|
||||
public RSocketSecurity rsocketSecurity(ApplicationContext context) {
|
||||
RSocketSecurity security = new RSocketSecurity()
|
||||
.authenticationManager(authenticationManager());
|
||||
security.setApplicationContext(context);
|
||||
return security;
|
||||
}
|
||||
|
||||
private ReactiveAuthenticationManager authenticationManager() {
|
||||
if (this.authenticationManager != null) {
|
||||
return this.authenticationManager;
|
||||
}
|
||||
if (this.reactiveUserDetailsService != null) {
|
||||
UserDetailsRepositoryReactiveAuthenticationManager manager =
|
||||
new UserDetailsRepositoryReactiveAuthenticationManager(this.reactiveUserDetailsService);
|
||||
if (this.passwordEncoder != null) {
|
||||
manager.setPasswordEncoder(this.passwordEncoder);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.config.annotation.rsocket;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.rsocket.core.PayloadSocketAcceptorInterceptor;
|
||||
import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor;
|
||||
import org.springframework.security.rsocket.util.matcher.PayloadExchangeMatcher.MatchResult;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.2
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SecuritySocketAcceptorInterceptorConfiguration {
|
||||
@Bean
|
||||
SecuritySocketAcceptorInterceptor securitySocketAcceptorInterceptor(
|
||||
ObjectProvider<PayloadSocketAcceptorInterceptor> rsocketInterceptor, ObjectProvider<RSocketSecurity> rsocketSecurity) {
|
||||
PayloadSocketAcceptorInterceptor delegate = rsocketInterceptor
|
||||
.getIfAvailable(() -> defaultInterceptor(rsocketSecurity));
|
||||
return new SecuritySocketAcceptorInterceptor(delegate);
|
||||
}
|
||||
|
||||
private PayloadSocketAcceptorInterceptor defaultInterceptor(
|
||||
ObjectProvider<RSocketSecurity> rsocketSecurity) {
|
||||
RSocketSecurity rsocket = rsocketSecurity.getIfAvailable();
|
||||
if (rsocket == null) {
|
||||
throw new NoSuchBeanDefinitionException("No RSocketSecurity defined");
|
||||
}
|
||||
rsocket
|
||||
.basicAuthentication(Customizer.withDefaults())
|
||||
.authorizePayload(authz ->
|
||||
authz
|
||||
.setup().authenticated()
|
||||
.anyRequest().authenticated()
|
||||
.matcher(e -> MatchResult.match()).permitAll()
|
||||
);
|
||||
return rsocket.build();
|
||||
}
|
||||
}
|
||||
+7
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -40,7 +40,6 @@ import java.util.List;
|
||||
* @param <C> The object that is returned or Chained after creating the RequestMatcher
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Ankur Pathak
|
||||
* @since 3.2
|
||||
*/
|
||||
public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
@@ -50,8 +49,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private boolean anyRequestConfigured = false;
|
||||
|
||||
protected final void setApplicationContext(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
@@ -71,10 +68,7 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C anyRequest() {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure anyRequest after itself");
|
||||
C configurer = requestMatchers(ANY_REQUEST);
|
||||
this.anyRequestConfigured = true;
|
||||
return configurer;
|
||||
return requestMatchers(ANY_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +98,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C antMatchers(HttpMethod method, String... antPatterns) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
|
||||
return chainRequestMatchers(RequestMatchers.antMatchers(method, antPatterns));
|
||||
}
|
||||
|
||||
@@ -119,7 +112,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C antMatchers(String... antPatterns) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
|
||||
return chainRequestMatchers(RequestMatchers.antMatchers(antPatterns));
|
||||
}
|
||||
|
||||
@@ -169,7 +161,7 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
*/
|
||||
protected final List<MvcRequestMatcher> createMvcMatchers(HttpMethod method,
|
||||
String... mvcPatterns) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure mvcMatchers after anyRequest");
|
||||
boolean isServlet30 = ClassUtils.isPresent("javax.servlet.ServletRegistration", getClass().getClassLoader());
|
||||
ObjectPostProcessor<Object> opp = this.context.getBean(ObjectPostProcessor.class);
|
||||
if (!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
throw new NoSuchBeanDefinitionException("A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type " + HandlerMappingIntrospector.class.getName()
|
||||
@@ -181,8 +173,9 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
mvcPatterns.length);
|
||||
for (String mvcPattern : mvcPatterns) {
|
||||
MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, mvcPattern);
|
||||
opp.postProcess(matcher);
|
||||
|
||||
if (isServlet30) {
|
||||
opp.postProcess(matcher);
|
||||
}
|
||||
if (method != null) {
|
||||
matcher.setMethod(method);
|
||||
}
|
||||
@@ -204,7 +197,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C regexMatchers(HttpMethod method, String... regexPatterns) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
|
||||
return chainRequestMatchers(RequestMatchers.regexMatchers(method, regexPatterns));
|
||||
}
|
||||
|
||||
@@ -219,7 +211,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C regexMatchers(String... regexPatterns) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
|
||||
return chainRequestMatchers(RequestMatchers.regexMatchers(regexPatterns));
|
||||
}
|
||||
|
||||
@@ -232,7 +223,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
* @return the object that is chained after creating the {@link RequestMatcher}
|
||||
*/
|
||||
public C requestMatchers(RequestMatcher... requestMatchers) {
|
||||
Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");
|
||||
return chainRequestMatchers(Arrays.asList(requestMatchers));
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user