diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 0000000..b3cf179
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,56 @@
+name: Java CI
+on:
+ push:
+ branches:
+ - '[5-9]+.[0-9]+.x'
+ pull_request:
+ branches:
+ - '[5-9]+.[0-9]+.x'
+ workflow_dispatch:
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ WORKSPACE: ${{ github.workspace }}
+ GRADLE_OPTS: -Xmx1500m -Dfile.encoding=UTF-8
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: 17
+ - name: Run Tests
+ if: github.event_name == 'pull_request'
+ id: tests
+ uses: gradle/gradle-build-action@v2
+ with:
+ arguments: check -Dgeb.env=chromeHeadless
+ - name: Run Build
+ if: github.event_name == 'push'
+ id: build
+ uses: gradle/gradle-build-action@v2
+ env:
+ GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
+ with:
+ arguments: build -Dgeb.env=chromeHeadless
+ - name: Publish Test Report
+ if: steps.build.outcome == 'failure' || steps.tests.outcome == 'failure'
+ uses: scacap/action-surefire-report@v1
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ report_paths: '**/build/test-results/test/TEST-*.xml'
+ - name: Publish to repo.grails.org
+ id: publish
+ uses: gradle/gradle-build-action@v2
+ if: steps.build.outcome == 'success' && github.event_name == 'push'
+ env:
+ ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
+ ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
+ with:
+ arguments: -Dorg.gradle.internal.publish.checksums.insecure=true publish
+ - name: Build Documentation
+ id: docs
+ uses: gradle/gradle-build-action@v2
+ with:
+ arguments: docs:docs
diff --git a/README.md b/README.md
index fd59714..63a82d9 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-[![Build Status](https://travis-ci.org/grails-plugins/grails-spring-security-acl.svg?branch=master)
-
Grails Spring Security ACL Plugin
==================================
diff --git a/build.gradle b/build.gradle
index 92fc468..04ae5bc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,10 +1,8 @@
subprojects {
configurations.configureEach {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
- if ((details.requested.group == 'org.codehaus.groovy' || details.requested.group == 'org.apache.groovy') && details.requested.name != 'groovy-bom') {
- String groovyVersion = findProperty('groovyVersion') ?: libs.versions.groovy.get()
- details.useTarget(group: 'org.apache.groovy', name: details.requested.name, version: groovyVersion)
- details.because "The dependency coordinates are changed in Apache Groovy 4, plus ensure version"
+ if (details.requested.group == 'org.seleniumhq.selenium') {
+ details.useVersion(seleniumVersion)
}
}
}
diff --git a/docs/build.gradle b/docs/build.gradle
index c8ac3e7..0a7c9b5 100644
--- a/docs/build.gradle
+++ b/docs/build.gradle
@@ -3,14 +3,17 @@ buildscript {
maven { url 'https://repo.grails.org/grails/core' }
}
dependencies {
- classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.6.1'
- classpath 'org.asciidoctor:asciidoctorj-epub3:2.1.3'
- classpath 'org.asciidoctor:asciidoctorj-pdf:2.3.18'
+ classpath 'org.asciidoctor:asciidoctor-gradle-jvm:4.0.3'
+ classpath "org.asciidoctor:asciidoctor-gradle-jvm-epub:4.0.3"
+ classpath "org.asciidoctor:asciidoctor-gradle-jvm-pdf:4.0.3"
+ classpath "org.asciidoctor:asciidoctor-gradle-jvm-gems:4.0.3"
}
}
-import org.apache.tools.ant.taskdefs.condition.Os
-apply plugin: 'org.asciidoctor.convert'
+apply plugin: "org.asciidoctor.jvm.gems"
+apply plugin: 'org.asciidoctor.jvm.convert'
+apply plugin: "org.asciidoctor.jvm.pdf"
+apply plugin: "org.asciidoctor.jvm.epub"
def asciidoctorAttributes = [
copyright : 'Apache License, Version 2.0',
@@ -34,28 +37,62 @@ def asciidoctorAttributes = [
projectVersion : project.projectVersion,
]
+repositories {
+ mavenCentral()
+ maven { url 'https://repo.grails.org/grails/core' }
+ ruby.gems()
+}
-import org.apache.tools.ant.taskdefs.condition.Os
-import org.asciidoctor.gradle.AsciidoctorTask
+dependencies {
+ asciidoctorGems 'rubygems:rouge:4.4.0'
+}
-tasks.withType(AsciidoctorTask) {
+asciidoctor {
+ sourceDir file('src/docs')
+ sources {
+ include 'index.adoc'
+ }
+ outputDir = new File(buildDir, 'docs')
attributes asciidoctorAttributes
- outputDir new File(buildDir, 'docs')
- separateOutputDirs = false
+}
+
+asciidoctorPdf {
+ dependsOn asciidoctorGemsPrepare
sourceDir = file('src/docs')
sources {
include 'index.adoc'
}
+ outputDir = new File(buildDir, 'docs')
+
+ asciidoctorj {
+ requires 'rouge'
+ attributes asciidoctorAttributes
+ }
}
+asciidoctorEpub {
+ dependsOn asciidoctorGemsPrepare
+ sourceDir = file('src/docs')
+ sources {
+ include 'index.adoc'
+ }
+ outputDir = new File(buildDir, 'docs')
-task asciidoc(type: AsciidoctorTask, description: 'Generates single-page HTML, PDF, and EPUB3') {
- group 'documentation'
- backends 'html5', 'pdf', 'epub3'
+ asciidoctorj {
+ requires 'rouge'
+ attributes asciidoctorAttributes
+ }
+
+ ebookFormats = ["EPUB3"]
+}
+
+tasks.named("asciidoctor").configure {
+ dependsOn = ['asciidoctorPdf', 'asciidoctorEpub']
}
-task docs(dependsOn: [asciidoc]) {
- group 'documentation'
+tasks.register("docs") {
+ group = "documentation"
+ dependsOn = ["asciidoctor"]
doLast {
File dir = new File(buildDir, 'docs')
['epub', 'pdf'].each { String ext ->
@@ -73,4 +110,4 @@ task docs(dependsOn: [asciidoc]) {
include '**/*.png'
}
}
-}
\ No newline at end of file
+}
diff --git a/docs/src/docs/index.adoc b/docs/src/docs/index.adoc
index fa5c95a..11e1d7b 100644
--- a/docs/src/docs/index.adoc
+++ b/docs/src/docs/index.adoc
@@ -1,3 +1,4 @@
+:includedir: src/docs/
= Spring Security ACL Plugin - Reference Documentation
Burt Beckwith
@@ -8,20 +9,20 @@ Burt Beckwith
:toclevels: 2
:numbered:
-include::introduction.adoc[]
+include::{includedir}introduction.adoc[]
-include::installing.adoc[]
+include::{includedir}installing.adoc[]
-include::usage.adoc[]
+include::{includedir}usage.adoc[]
-include::tutorial.adoc[]
+include::{includedir}tutorial.adoc[]
-include::sampleApp.adoc[]
+include::{includedir}sampleApp.adoc[]
-include::AclUtilService.adoc[]
+include::{includedir}AclUtilService.adoc[]
-include::Scripts.adoc[]
+include::{includedir}Scripts.adoc[]
-include::TagLibraries.adoc[]
+include::{includedir}TagLibraries.adoc[]
-include::history.adoc[]
\ No newline at end of file
+include::{includedir}history.adoc[]
\ No newline at end of file
diff --git a/functional-test-app/build.gradle b/functional-test-app/build.gradle
index 1fe4693..5cd8dca 100644
--- a/functional-test-app/build.gradle
+++ b/functional-test-app/build.gradle
@@ -7,7 +7,7 @@ buildscript {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:5.0.1"
classpath "org.grails.plugins:hibernate5:$gormVersion"
- classpath "gradle.plugin.com.github.erdi.webdriver-binaries:webdriver-binaries-gradle-plugin:2.7"
+ classpath "com.github.erdi:webdriver-binaries-gradle-plugin:3.2"
}
}
@@ -41,12 +41,11 @@ dependencies {
implementation "org.grails:grails-plugin-url-mappings"
implementation "org.grails:grails-plugin-interceptors"
implementation "org.grails:grails-web-boot"
- implementation "org.grails.plugins:cache"
implementation "org.grails.plugins:async"
implementation "org.grails.plugins:scaffolding"
implementation "org.grails.plugins:events"
implementation "org.grails.plugins:hibernate5"
- implementation "org.hibernate:hibernate-core:$hibernateCoreVersion"
+ implementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion"
implementation "org.grails.plugins:gsp"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
@@ -55,24 +54,27 @@ dependencies {
runtimeOnly "com.h2database:h2"
testImplementation "org.grails:grails-gorm-testing-support"
testImplementation "org.grails:grails-web-testing-support"
- testImplementation "io.micronaut:micronaut-http-client:$micronautVersion"
- testImplementation "org.grails.plugins:geb"
- testRuntimeOnly "org.seleniumhq.selenium:selenium-chrome-driver:4.19.1"
- testImplementation "org.seleniumhq.selenium:selenium-remote-driver:4.19.1"
- testImplementation "org.seleniumhq.selenium:selenium-api:4.19.1"
- implementation project(':spring-security-acl')
-}
+ integrationTestImplementation testFixtures('org.grails.plugins:geb')
-webdriverBinaries {
- chromedriver '2.46.0'
- geckodriver '0.29.1'
+ testRuntimeOnly "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
+ testRuntimeOnly "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
+ testRuntimeOnly "org.seleniumhq.selenium:selenium-safari-driver:$seleniumVersion"
+ testImplementation "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion"
+ testImplementation "org.seleniumhq.selenium:selenium-api:$seleniumVersion"
+ implementation project(':spring-security-acl')
}
tasks.withType(Test) {
useJUnitPlatform()
systemProperty "geb.env", System.getProperty('geb.env')
- systemProperty "webdriver.chrome.driver", System.getProperty('webdriver.chrome.driver')
- systemProperty "webdriver.gecko.driver", System.getProperty('webdriver.gecko.driver')
+ systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest")
+ if (System.getenv('CHROMEWEBDRIVER')) {
+ systemProperty 'webdriver.chrome.driver', "${System.getenv('CHROMEWEBDRIVER')}/chromedriver"
+ }
+ if (System.getenv('GECKOWEBDRIVER')) {
+ systemProperty 'webdriver.gecko.driver', "${System.getenv('GECKOWEBDRIVER')}/geckodriver"
+ }
+
beforeTest { descriptor -> logger.quiet " -- $descriptor" }
testLogging {
events "passed", "skipped", "failed"
diff --git a/functional-test-app/grails-app/conf/application.yml b/functional-test-app/grails-app/conf/application.yml
index 4d17859..551d12b 100644
--- a/functional-test-app/grails-app/conf/application.yml
+++ b/functional-test-app/grails-app/conf/application.yml
@@ -1,33 +1,65 @@
----
-grails:
- profile: web
- codegen:
- defaultPackage: misc.functional.test.app
- spring:
- transactionManagement:
- proxies: false
- gorm:
- reactor:
- # Whether to translate GORM events into Reactor events
- # Disabled by default for performance reasons
- events: false
info:
- app:
- name: '@info.app.name@'
- version: '@info.app.version@'
- grailsVersion: '@info.app.grailsVersion@'
-spring:
- main:
- banner-mode: "off"
- groovy:
- template:
- check-template-location: false
-
-# Spring Actuator Endpoints are Disabled by Default
-endpoints:
- enabled: false
- jmx:
- enabled: true
+ app:
+ name: '@info.app.name@'
+ version: '@info.app.version@'
+ grailsVersion: '@info.app.grailsVersion@'
+grails:
+ mime:
+ disable:
+ accept:
+ header:
+ userAgents:
+ - Gecko
+ - WebKit
+ - Presto
+ - Trident
+ types:
+ all: '*/*'
+ atom: application/atom+xml
+ css: text/css
+ csv: text/csv
+ form: application/x-www-form-urlencoded
+ html:
+ - text/html
+ - application/xhtml+xml
+ js: text/javascript
+ json:
+ - application/json
+ - text/json
+ multipartForm: multipart/form-data
+ pdf: application/pdf
+ rss: application/rss+xml
+ text: text/plain
+ hal:
+ - application/hal+json
+ - application/hal+xml
+ xml:
+ - text/xml
+ - application/xml
+ views:
+ gsp:
+ encoding: UTF-8
+ htmlcodec: xml
+ codecs:
+ expression: html
+ scriptlet: html
+ taglib: none
+ staticparts: none
+ default:
+ codec: html
+dataSource:
+ url: jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
+ driverClassName: org.h2.Driver
+ username: sa
+ password: ''
+ pooled: true
+ jmxExport: true
+ dbCreate: update
+hibernate:
+ cache:
+ queries: false
+ use_second_level_cache: false
+ use_query_cache: false
---
grails:
@@ -35,103 +67,3 @@ grails:
springsecurity:
userLookup:
user-domain-class-name: com.testacl.User
- mime:
- disable:
- accept:
- header:
- userAgents:
- - Gecko
- - WebKit
- - Presto
- - Trident
- types:
- all: '*/*'
- atom: application/atom+xml
- css: text/css
- csv: text/csv
- form: application/x-www-form-urlencoded
- html:
- - text/html
- - application/xhtml+xml
- js: text/javascript
- json:
- - application/json
- - text/json
- multipartForm: multipart/form-data
- pdf: application/pdf
- rss: application/rss+xml
- text: text/plain
- hal:
- - application/hal+json
- - application/hal+xml
- xml:
- - text/xml
- - application/xml
- urlmapping:
- cache:
- maxsize: 1000
- controllers:
- defaultScope: singleton
- converters:
- encoding: UTF-8
- views:
- default:
- codec: html
- gsp:
- encoding: UTF-8
- htmlcodec: xml
- codecs:
- expression: html
- scriptlets: html
- taglib: none
- staticparts: none
-endpoints:
- jmx:
- unique-names: true
-
----
-hibernate:
- cache:
- queries: false
- use_second_level_cache: false
- use_query_cache: false
-
-dataSource:
- pooled: true
- jmxExport: true
- driverClassName: org.h2.Driver
- username: sa
- password: ''
-
-environments:
- development:
- dataSource:
- dbCreate: create-drop
- url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
- test:
- dataSource:
- dbCreate: update
- url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
- production:
- dataSource:
- dbCreate: none
- url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
- properties:
- jmxEnabled: true
- initialSize: 5
- maxActive: 50
- minIdle: 5
- maxIdle: 25
- maxWait: 10000
- maxAge: 600000
- timeBetweenEvictionRunsMillis: 5000
- minEvictableIdleTimeMillis: 60000
- validationQuery: SELECT 1
- validationQueryTimeout: 3
- validationInterval: 15000
- testOnBorrow: true
- testWhileIdle: true
- testOnReturn: false
- jdbcInterceptors: ConnectionState
- defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
-
diff --git a/functional-test-app/grails-app/controllers/com/testacl/ErrorsController.groovy b/functional-test-app/grails-app/controllers/com/testacl/ErrorsController.groovy
index a71f6d2..4529276 100644
--- a/functional-test-app/grails-app/controllers/com/testacl/ErrorsController.groovy
+++ b/functional-test-app/grails-app/controllers/com/testacl/ErrorsController.groovy
@@ -7,11 +7,6 @@ import groovy.transform.CompileStatic
@Secured('permitAll')
class ErrorsController {
- def error403() {
- // Line necessary due to: https://github.com/grails/grails-core/issues/10582
- [view: 'error403']
- }
-
def error404() {
String uri = 'request.forwardURI'
if (!uri.contains('favicon.ico')) {
diff --git a/functional-test-app/grails-app/controllers/com/testacl/UrlMappings.groovy b/functional-test-app/grails-app/controllers/com/testacl/UrlMappings.groovy
index 2a720f4..4d622d3 100644
--- a/functional-test-app/grails-app/controllers/com/testacl/UrlMappings.groovy
+++ b/functional-test-app/grails-app/controllers/com/testacl/UrlMappings.groovy
@@ -13,7 +13,7 @@ class UrlMappings {
"403"(controller: 'errors', action: 'error403')
"404"(controller: 'errors', action: 'error404')
"500"(controller: 'errors', action: 'error500')
- "500"(controller: 'errors', action: 'error403', exception: AccessDeniedException)
- "500"(controller: 'errors', action: 'error403', exception: NotFoundException)
+ "500"(view: 'errors/error403', exception: AccessDeniedException)
+ "500"(controller: 'errors', action: 'error404', exception: NotFoundException)
}
}
diff --git a/functional-test-app/grails-app/domain/com/testacl/User.groovy b/functional-test-app/grails-app/domain/com/testacl/User.groovy
index 2dd9ab3..543a582 100644
--- a/functional-test-app/grails-app/domain/com/testacl/User.groovy
+++ b/functional-test-app/grails-app/domain/com/testacl/User.groovy
@@ -24,4 +24,8 @@ class User implements Serializable {
username blank: false, unique: true
password blank: false
}
+
+ static mapping = {
+ table name: '`user`'
+ }
}
diff --git a/functional-test-app/grails-app/domain/com/testacl/UserRole.groovy b/functional-test-app/grails-app/domain/com/testacl/UserRole.groovy
index 48b20f2..fdc68cb 100644
--- a/functional-test-app/grails-app/domain/com/testacl/UserRole.groovy
+++ b/functional-test-app/grails-app/domain/com/testacl/UserRole.groovy
@@ -2,7 +2,8 @@ package com.testacl
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
-import org.apache.commons.lang.builder.HashCodeBuilder
+import org.apache.commons.lang3.builder.HashCodeBuilder
+import org.hibernate.ObjectNotFoundException
@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {
@@ -86,7 +87,11 @@ class UserRole implements Serializable {
if (ur.user == null || ur.user.id == null) return
boolean existing = false
UserRole.withNewSession {
- existing = UserRole.exists(ur.user.id, r.id)
+ try {
+ existing = UserRole.exists(ur.user.id, r.id)
+ } catch (ObjectNotFoundException ignored) {
+ // no-op
+ }
}
if (existing) {
return 'userRole.exists'
diff --git a/functional-test-app/grails-app/init/com/testacl/BootStrap.groovy b/functional-test-app/grails-app/init/com/testacl/BootStrap.groovy
index 5c8799e..cff71db 100644
--- a/functional-test-app/grails-app/init/com/testacl/BootStrap.groovy
+++ b/functional-test-app/grails-app/init/com/testacl/BootStrap.groovy
@@ -2,9 +2,6 @@ package com.testacl
class BootStrap {
- TestDataService testDataService
-
def init = {
- testDataService.reset()
}
}
diff --git a/functional-test-app/grails-app/services/com/testacl/ReportService.groovy b/functional-test-app/grails-app/services/com/testacl/ReportService.groovy
index be1cbba..65a6d7b 100644
--- a/functional-test-app/grails-app/services/com/testacl/ReportService.groovy
+++ b/functional-test-app/grails-app/services/com/testacl/ReportService.groovy
@@ -8,6 +8,7 @@ import org.springframework.security.acls.domain.BasePermission
import org.springframework.security.acls.domain.PermissionFactory
import org.springframework.security.acls.model.Permission
import grails.gorm.transactions.Transactional
+import org.springframework.security.core.parameters.P
class ReportService {
@@ -17,13 +18,13 @@ class ReportService {
@PreAuthorize('hasPermission(#report, admin)')
@Transactional
- void addPermission(Report report, String username, int permission) {
+ void addPermission(@P("report") Report report, String username, int permission) {
addPermission report, username, aclPermissionFactory.buildFromMask(permission)
}
@PreAuthorize('hasPermission(#report, admin)')
@Transactional
- void addPermission(Report report, String username, Permission permission) {
+ void addPermission(@P("report") Report report, String username, Permission permission) {
aclUtilService.addPermission report, username, permission
}
@@ -40,7 +41,7 @@ class ReportService {
}
@PreAuthorize('hasPermission(#id, "com.testacl.Report", read) or hasPermission(#id, "com.testacl.Report", admin)')
- Report get(long id) {
+ Report get(@P("id") long id) {
Report.get id
}
@@ -56,13 +57,13 @@ class ReportService {
@Transactional
@PreAuthorize('hasPermission(#report, write) or hasPermission(#report, admin)')
- void update(Report report, String name) {
+ void update(@P("report") Report report, String name) {
report.name = name
}
@Transactional
@PreAuthorize('hasPermission(#report, delete) or hasPermission(#report, admin)')
- void delete(Report report) {
+ void delete(@P("report") Report report) {
report.delete()
// Delete the ACL information as well
diff --git a/functional-test-app/grails-app/services/com/testacl/TestDataService.groovy b/functional-test-app/grails-app/services/com/testacl/TestDataService.groovy
index fa414a7..da394e5 100644
--- a/functional-test-app/grails-app/services/com/testacl/TestDataService.groovy
+++ b/functional-test-app/grails-app/services/com/testacl/TestDataService.groovy
@@ -9,6 +9,7 @@ import grails.plugin.springsecurity.acl.AclSid
import grails.plugin.springsecurity.acl.AclUtilService
import grails.gorm.transactions.Transactional
import groovy.util.logging.Slf4j
+import jakarta.annotation.PostConstruct
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
@@ -26,6 +27,11 @@ class TestDataService {
AclUtilService aclUtilService
ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy
+ @PostConstruct
+ void init() {
+ reset()
+ }
+
void reset() {
deleteAll()
createData()
diff --git a/functional-test-app/src/integration-test/groovy/test/AbstractSecuritySpec.groovy b/functional-test-app/src/integration-test/groovy/test/AbstractSecuritySpec.groovy
index 41ac33b..69ef12b 100644
--- a/functional-test-app/src/integration-test/groovy/test/AbstractSecuritySpec.groovy
+++ b/functional-test-app/src/integration-test/groovy/test/AbstractSecuritySpec.groovy
@@ -1,12 +1,13 @@
package test
import geb.spock.GebReportingSpec
+import grails.gorm.transactions.Rollback
import grails.testing.mixin.integration.Integration
import pages.LoginPage
import spock.lang.Shared
@Integration
-@grails.gorm.transactions.Rollback
+@Rollback
abstract class AbstractSecuritySpec extends GebReportingSpec {
@Shared boolean reset = false
diff --git a/functional-test-app/src/integration-test/resources/GebConfig.groovy b/functional-test-app/src/integration-test/resources/GebConfig.groovy
index 17723e5..adb480e 100644
--- a/functional-test-app/src/integration-test/resources/GebConfig.groovy
+++ b/functional-test-app/src/integration-test/resources/GebConfig.groovy
@@ -1,21 +1,41 @@
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
-
-reportsDir = new File('build/geb-reports')
+import org.openqa.selenium.firefox.FirefoxDriver
+import org.openqa.selenium.firefox.FirefoxOptions
+import org.openqa.selenium.safari.SafariDriver
environments {
- // run via “./gradlew -Dgeb.env=chrome iT”
- chrome {
- driver = { new ChromeDriver() }
- }
+ // You need to configure in Safari -> Develop -> Allowed Remote Automation
+ safari {
+ driver = { new SafariDriver() }
+ }
+
+ // run via “./gradlew -Dgeb.env=chrome iT”
+ chrome {
+ driver = { new ChromeDriver() }
+ }
+
+ // run via “./gradlew -Dgeb.env=chromeHeadless iT”
+ chromeHeadless {
+ driver = {
+ ChromeOptions o = new ChromeOptions()
+ o.addArguments('headless')
+ new ChromeDriver(o)
+ }
+ }
+
+ // run via “./gradlew -Dgeb.env=firefoxHeadless iT”
+ firefoxHeadless {
+ driver = {
+ FirefoxOptions o = new FirefoxOptions()
+ o.addArguments('-headless')
+ new FirefoxDriver(o)
+ }
+ }
- // run via “./gradlew -Dgeb.env=chromeHeadless iT”
- chromeHeadless {
- driver = {
- ChromeOptions o = new ChromeOptions()
- o.addArguments('headless')
- new ChromeDriver(o)
- }
- }
-}
+ // run via “./gradlew -Dgeb.env=firefox iT”
+ firefox {
+ driver = { new FirefoxDriver() }
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 5652d90..a1cdf3a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,5 +7,5 @@ springSecurityCoreVersion=7.0.0-SNAPSHOT
jakartaServletApiVersion=6.0.0
micronautVersion=4.5.3
hibernateCoreVersion=5.6.15.Final
-groovyVersion=4.0.23
ehcacheVersion=3.10.8
+seleniumVersion=4.26.0
diff --git a/integration-test-app/build.gradle b/integration-test-app/build.gradle
index d5f2e4b..701bc6b 100644
--- a/integration-test-app/build.gradle
+++ b/integration-test-app/build.gradle
@@ -37,12 +37,11 @@ dependencies {
implementation "org.grails:grails-plugin-services"
implementation "org.grails:grails-plugin-url-mappings"
implementation "org.grails:grails-plugin-interceptors"
- implementation "org.grails.plugins:cache"
implementation "org.grails.plugins:async"
implementation "org.grails.plugins:scaffolding"
implementation "org.grails.plugins:events"
implementation "org.grails.plugins:hibernate5"
- implementation "org.hibernate:hibernate-core:$hibernateCoreVersion"
+ implementation "org.hibernate:hibernate-core-jakarta:$hibernateCoreVersion"
implementation "org.grails.plugins:gsp"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
diff --git a/integration-test-app/grails-app/conf/application.yml b/integration-test-app/grails-app/conf/application.yml
index 570acf8..d87bb9a 100644
--- a/integration-test-app/grails-app/conf/application.yml
+++ b/integration-test-app/grails-app/conf/application.yml
@@ -1,114 +1,63 @@
----
-grails:
- profile: web
- codegen:
- defaultPackage: grails.plugin.springsecurity.acl
- spring:
- transactionManagement:
- proxies: false
- gorm:
- reactor:
- # Whether to translate GORM events into Reactor events
- # Disabled by default for performance reasons
- events: false
-info:
- app:
- name: '@info.app.name@'
- version: '@info.app.version@'
- grailsVersion: '@info.app.grailsVersion@'
-spring:
- main:
- banner-mode: "off"
- groovy:
- template:
- check-template-location: false
-
-# Spring Actuator Endpoints are Disabled by Default
-endpoints:
- enabled: false
- jmx:
- enabled: true
----
+info:
+ app:
+ name: '@info.app.name@'
+ version: '@info.app.version@'
+ grailsVersion: '@info.app.grailsVersion@'
grails:
- mime:
- disable:
- accept:
- header:
- userAgents:
- - Gecko
- - WebKit
- - Presto
- - Trident
- types:
- all: '*/*'
- atom: application/atom+xml
- css: text/css
- csv: text/csv
- form: application/x-www-form-urlencoded
- html:
- - text/html
- - application/xhtml+xml
- js: text/javascript
- json:
- - application/json
- - text/json
- multipartForm: multipart/form-data
- pdf: application/pdf
- rss: application/rss+xml
- text: text/plain
- hal:
- - application/hal+json
- - application/hal+xml
- xml:
- - text/xml
- - application/xml
- urlmapping:
- cache:
- maxsize: 1000
- controllers:
- defaultScope: singleton
- converters:
- encoding: UTF-8
- views:
- default:
- codec: html
- gsp:
- encoding: UTF-8
- htmlcodec: xml
- codecs:
- expression: html
- scriptlets: html
- taglib: none
- staticparts: none
-endpoints:
- jmx:
- unique-names: true
-
----
-hibernate:
- cache:
- queries: false
- use_query_cache: false
- use_second_level_cache: false
- format_sql: true
- use_sql_comments: true
-
-#dataSource:
-# dbCreate: update
-# driverClassName: com.mysql.jdbc.Driver
-# dialect: org.hibernate.dialect.MySQL5InnoDBDialect
-# jmxExport: false
-# password: root
-# pooled: true
-# url: jdbc:mysql://127.0.0.1:8889/acl
-# username: root
-
+ mime:
+ disable:
+ accept:
+ header:
+ userAgents:
+ - Gecko
+ - WebKit
+ - Presto
+ - Trident
+ types:
+ all: '*/*'
+ atom: application/atom+xml
+ css: text/css
+ csv: text/csv
+ form: application/x-www-form-urlencoded
+ html:
+ - text/html
+ - application/xhtml+xml
+ js: text/javascript
+ json:
+ - application/json
+ - text/json
+ multipartForm: multipart/form-data
+ pdf: application/pdf
+ rss: application/rss+xml
+ text: text/plain
+ hal:
+ - application/hal+json
+ - application/hal+xml
+ xml:
+ - text/xml
+ - application/xml
+ views:
+ gsp:
+ encoding: UTF-8
+ htmlcodec: xml
+ codecs:
+ expression: html
+ scriptlet: html
+ taglib: none
+ staticparts: none
+ default:
+ codec: html
dataSource:
- pooled: true
- jmxExport: true
- driverClassName: org.h2.Driver
- username: sa
- password: ''
- dbCreate: create-drop
- url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
+ url: jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
+ driverClassName: org.h2.Driver
+ username: sa
+ password: ''
+ pooled: true
+ jmxExport: true
+ dbCreate: update
+hibernate:
+ cache:
+ queries: false
+ use_second_level_cache: false
+ use_query_cache: false
diff --git a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclServiceSpec.groovy b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclServiceSpec.groovy
index b700937..98d89a5 100644
--- a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclServiceSpec.groovy
+++ b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclServiceSpec.groovy
@@ -15,7 +15,7 @@
package grails.plugin.springsecurity.acl
import grails.gorm.transactions.Rollback
-import net.sf.ehcache.Ehcache
+import org.springframework.cache.CacheManager
import org.springframework.security.acls.domain.BasePermission
import org.springframework.security.acls.domain.CumulativePermission
import org.springframework.security.acls.domain.GrantedAuthoritySid
@@ -55,14 +55,14 @@ class AclServiceSpec extends AbstractIntegrationSpec {
AclCache aclCache
AclService aclService
- Ehcache ehcacheAclCache
+ CacheManager aclCacheManager
void setup() {
principalSid = new PrincipalSid(authenticate('ben', 'ROLE_ADMIN'))
}
void cleanup() {
- ehcacheAclCache.removeAll()
+ aclCacheManager.getCache("aclCache").clear()
}
void 'test lifecycle'() {
diff --git a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/jdbc/GormAclLookupStrategySpec.groovy b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/jdbc/GormAclLookupStrategySpec.groovy
index 26cb770..e2a7c3b 100644
--- a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/jdbc/GormAclLookupStrategySpec.groovy
+++ b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/jdbc/GormAclLookupStrategySpec.groovy
@@ -20,7 +20,7 @@ import grails.plugin.springsecurity.acl.AclClass
import grails.plugin.springsecurity.acl.AclEntry
import grails.plugin.springsecurity.acl.AclObjectIdentity
import grails.plugin.springsecurity.acl.AclSid
-import net.sf.ehcache.Ehcache
+import org.springframework.cache.CacheManager
import org.springframework.security.acls.domain.BasePermission
import org.springframework.security.acls.domain.ObjectIdentityImpl
import org.springframework.security.acls.domain.PrincipalSid
@@ -50,7 +50,7 @@ class GormAclLookupStrategySpec extends AbstractIntegrationSpec {
private AclObjectIdentity aclObjectIdentity
GormAclLookupStrategy aclLookupStrategy
- Ehcache ehcacheAclCache
+ CacheManager aclCacheManager
void buildData() {
@@ -107,7 +107,7 @@ class GormAclLookupStrategySpec extends AbstractIntegrationSpec {
}
void cleanup() {
- ehcacheAclCache.removeAll()
+ aclCacheManager.getCache("aclCache").clear()
}
void 'acls retrieval with default batch size'() {
diff --git a/plugin/build.gradle b/plugin/build.gradle
index 0c8c4af..f9b21f8 100644
--- a/plugin/build.gradle
+++ b/plugin/build.gradle
@@ -44,7 +44,6 @@ dependencies {
implementation "org.grails:grails-plugin-services"
implementation "org.grails:grails-plugin-url-mappings"
implementation "org.grails:grails-plugin-interceptors"
- implementation "org.grails.plugins:cache"
implementation "org.grails.plugins:gsp"
console "org.grails:grails-console"
profile "org.grails.profiles:web-plugin"
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/ProxyAwareParameterNameDiscoverer.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/ProxyAwareParameterNameDiscoverer.groovy
deleted file mode 100644
index e89c65d..0000000
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/ProxyAwareParameterNameDiscoverer.groovy
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2009-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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package grails.plugin.springsecurity.acl
-
-import grails.plugin.springsecurity.acl.util.ProxyUtils
-import groovy.transform.CompileStatic
-import org.springframework.core.StandardReflectionParameterNameDiscoverer
-
-import java.lang.reflect.Constructor
-import java.lang.reflect.Method
-
-/**
- * CGLIB proxies confuse parameter name discovery since the classes aren't compiled with
- * debug, so find the corresponding method or constructor in the target and use that.
- *
- * @author Burt Beckwith
- */
-@CompileStatic
-class ProxyAwareParameterNameDiscoverer extends StandardReflectionParameterNameDiscoverer {
-
- @Override
- String[] getParameterNames(Method method) {
- super.getParameterNames ProxyUtils.unproxy(method)
- }
-
- @Override
- String[] getParameterNames(Constructor> constructor) {
- super.getParameterNames ProxyUtils.unproxy(constructor)
- }
-}
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.groovy
index 2c7673d..84e36d1 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/SpringSecurityAclGrailsPlugin.groovy
@@ -177,7 +177,7 @@ class SpringSecurityAclGrailsPlugin extends Plugin {
aclCache(SpringAclCacheFactoryBean) {
cacheManager = ref('aclCacheManager')
cacheName = 'aclCache'
- aclPermissionGrantingStrategy = ref('aclPermissionGrantingStrategy')
+ permissionGrantingStrategy = ref('aclPermissionGrantingStrategy')
aclAuthorizationStrategy = ref('aclAuthorizationStrategy')
}
@@ -211,8 +211,6 @@ class SpringSecurityAclGrailsPlugin extends Plugin {
private configureExpressionBeans = { conf ->
- parameterNameDiscoverer(ProxyAwareParameterNameDiscoverer)
-
permissionEvaluator(AclPermissionEvaluator, ref('aclService')) {
objectIdentityRetrievalStrategy = ref('objectIdentityRetrievalStrategy')
objectIdentityGenerator = ref('objectIdentityRetrievalStrategy')
@@ -228,7 +226,6 @@ class SpringSecurityAclGrailsPlugin extends Plugin {
}
expressionHandler(DefaultMethodSecurityExpressionHandler) {
- parameterNameDiscoverer = ref('parameterNameDiscoverer')
permissionCacheOptimizer = ref('aclPermissionCacheOptimizer')
expressionParser = ref('expressionParser')
roleHierarchy = ref('roleHierarchy')
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/cache/SpringAclCacheFactoryBean.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/cache/SpringAclCacheFactoryBean.groovy
index 14ca201..a36d682 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/cache/SpringAclCacheFactoryBean.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/cache/SpringAclCacheFactoryBean.groovy
@@ -55,8 +55,8 @@ class SpringAclCacheFactoryBean implements FactoryBean
Assert.notNull(permissionGrantingStrategy, "permissionGrantingStrategy is required")
Assert.notNull(aclAuthorizationStrategy, "aclAuthorizationStrategy is required")
if (!cacheConfig) {
- cacheConfig = new MutableConfiguration()
- .setTypes(String, MutableAcl)
+ cacheConfig = new MutableConfiguration